removed node map file and utilities, added formal class methods to session objects and added checks for specific classes where needed
This commit is contained in:
parent
8c348b5ab1
commit
b14012e5e9
24 changed files with 161 additions and 264 deletions
|
@ -7,7 +7,6 @@ import sys
|
|||
import core.services
|
||||
from core.emulator.emudata import IdGen
|
||||
from core.emulator.session import Session
|
||||
from core.nodes import nodemaps, nodeutils
|
||||
from core.services.coreservices import ServiceManager
|
||||
|
||||
|
||||
|
@ -53,10 +52,6 @@ class CoreEmu(object):
|
|||
self.session_id_gen = IdGen(_id=0)
|
||||
self.sessions = {}
|
||||
|
||||
# set default nodes
|
||||
node_map = nodemaps.NODES
|
||||
nodeutils.set_node_map(node_map)
|
||||
|
||||
# load services
|
||||
self.service_errors = []
|
||||
self.load_services()
|
||||
|
@ -77,15 +72,6 @@ class CoreEmu(object):
|
|||
custom_service_errors = ServiceManager.add_services(service_path)
|
||||
self.service_errors.extend(custom_service_errors)
|
||||
|
||||
def update_nodes(self, node_map):
|
||||
"""
|
||||
Updates node map used by core.
|
||||
|
||||
:param dict node_map: node map to update existing node map with
|
||||
:return: nothing
|
||||
"""
|
||||
nodeutils.update_node_map(node_map)
|
||||
|
||||
def shutdown(self):
|
||||
"""
|
||||
Shutdown all CORE session.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
from core.emulator.enumerations import LinkTypes, NodeTypes
|
||||
from core.nodes import nodeutils
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.emulator.enumerations import LinkTypes
|
||||
from core.nodes.base import CoreNetworkBase
|
||||
from core.nodes.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
|
||||
from core.nodes.physical import PhysicalNode
|
||||
|
||||
|
||||
class IdGen(object):
|
||||
|
@ -65,7 +66,7 @@ def link_config(network, interface, link_options, devname=None, interface_two=No
|
|||
}
|
||||
|
||||
# hacky check here, because physical and emane nodes do not conform to the same linkconfig interface
|
||||
if not nodeutils.is_node(network, [NodeTypes.EMANE, NodeTypes.PHYSICAL]):
|
||||
if not isinstance(network, (EmaneNode, PhysicalNode)):
|
||||
config["devname"] = devname
|
||||
|
||||
network.linkconfig(**config)
|
||||
|
|
|
@ -14,11 +14,11 @@ import threading
|
|||
import time
|
||||
from multiprocessing.pool import ThreadPool
|
||||
|
||||
import core.nodes.base
|
||||
from core import CoreError, constants, utils
|
||||
from core.api.tlv import coreapi
|
||||
from core.api.tlv.broker import CoreBroker
|
||||
from core.emane.emanemanager import EmaneManager
|
||||
from core.emane.nodes import EmaneNet, EmaneNode
|
||||
from core.emulator.data import EventData, ExceptionData, NodeData
|
||||
from core.emulator.emudata import (
|
||||
IdGen,
|
||||
|
@ -33,14 +33,46 @@ from core.emulator.sessionconfig import SessionConfig, SessionMetaData
|
|||
from core.location.corelocation import CoreLocation
|
||||
from core.location.event import EventLoop
|
||||
from core.location.mobility import MobilityManager
|
||||
from core.nodes import nodeutils
|
||||
from core.nodes.base import CoreNodeBase
|
||||
from core.nodes.base import CoreNode, CoreNodeBase
|
||||
from core.nodes.docker import DockerNode
|
||||
from core.nodes.ipaddress import MacAddress
|
||||
from core.nodes.lxd import LxcNode
|
||||
from core.nodes.network import (
|
||||
CtrlNet,
|
||||
GreTapBridge,
|
||||
HubNode,
|
||||
PtpNet,
|
||||
SwitchNode,
|
||||
TunnelNode,
|
||||
WlanNode,
|
||||
)
|
||||
from core.nodes.physical import PhysicalNode, Rj45Node
|
||||
from core.plugins.sdt import Sdt
|
||||
from core.services.coreservices import CoreServices
|
||||
from core.xml import corexml, corexmldeployment
|
||||
from core.xml.corexml import CoreXmlReader, CoreXmlWriter
|
||||
|
||||
# maps for converting from API call node type values to classes and vice versa
|
||||
NODES = {
|
||||
NodeTypes.DEFAULT: CoreNode,
|
||||
NodeTypes.PHYSICAL: PhysicalNode,
|
||||
NodeTypes.TBD: None,
|
||||
NodeTypes.SWITCH: SwitchNode,
|
||||
NodeTypes.HUB: HubNode,
|
||||
NodeTypes.WIRELESS_LAN: WlanNode,
|
||||
NodeTypes.RJ45: Rj45Node,
|
||||
NodeTypes.TUNNEL: TunnelNode,
|
||||
NodeTypes.KTUNNEL: None,
|
||||
NodeTypes.EMANE: EmaneNode,
|
||||
NodeTypes.EMANE_NET: EmaneNet,
|
||||
NodeTypes.TAP_BRIDGE: GreTapBridge,
|
||||
NodeTypes.PEER_TO_PEER: PtpNet,
|
||||
NodeTypes.CONTROL_NET: CtrlNet,
|
||||
NodeTypes.DOCKER: DockerNode,
|
||||
NodeTypes.LXC: LxcNode,
|
||||
}
|
||||
NODES_TYPE = {NODES[x]: x for x in NODES}
|
||||
|
||||
|
||||
class Session(object):
|
||||
"""
|
||||
|
@ -121,6 +153,33 @@ class Session(object):
|
|||
"host": ("DefaultRoute", "SSH"),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_node_class(cls, _type):
|
||||
"""
|
||||
Retrieve the class for a given node type.
|
||||
|
||||
:param core.emulator.enumerations.NodeTypes _type: node type to get class for
|
||||
:return: node class
|
||||
"""
|
||||
node_class = NODES.get(_type)
|
||||
if node_class is None:
|
||||
raise CoreError("invalid node type: %s" % _type)
|
||||
return node_class
|
||||
|
||||
@classmethod
|
||||
def get_node_type(cls, _class):
|
||||
"""
|
||||
Retrieve node type for a given node class.
|
||||
|
||||
:param _class: node class to get a node type for
|
||||
:return: node type
|
||||
:rtype: core.emulator.enumerations.NodeTypes
|
||||
"""
|
||||
node_type = NODES_TYPE.get(_class)
|
||||
if node_type is None:
|
||||
raise CoreError("invalid node class: %s" % _class)
|
||||
return node_type
|
||||
|
||||
def _link_nodes(self, node_one_id, node_two_id):
|
||||
"""
|
||||
Convenience method for retrieving nodes within link data.
|
||||
|
@ -145,7 +204,7 @@ class Session(object):
|
|||
# both node ids are provided
|
||||
tunnel = self.broker.gettunnel(node_one_id, node_two_id)
|
||||
logging.debug("tunnel between nodes: %s", tunnel)
|
||||
if nodeutils.is_node(tunnel, NodeTypes.TAP_BRIDGE):
|
||||
if isinstance(tunnel, GreTapBridge):
|
||||
net_one = tunnel
|
||||
if tunnel.remotenum == node_one_id:
|
||||
node_one = None
|
||||
|
@ -203,9 +262,7 @@ class Session(object):
|
|||
raise CoreError("no common network found for wireless link/unlink")
|
||||
|
||||
for common_network, interface_one, interface_two in common_networks:
|
||||
if not nodeutils.is_node(
|
||||
common_network, [NodeTypes.WIRELESS_LAN, NodeTypes.EMANE]
|
||||
):
|
||||
if not isinstance(common_network, (WlanNode, EmaneNode)):
|
||||
logging.info(
|
||||
"skipping common network that is not wireless/emane: %s",
|
||||
common_network,
|
||||
|
@ -268,9 +325,8 @@ class Session(object):
|
|||
node_one.name,
|
||||
node_two.name,
|
||||
)
|
||||
ptp_class = nodeutils.get_node_class(NodeTypes.PEER_TO_PEER)
|
||||
start = self.state > EventTypes.DEFINITION_STATE.value
|
||||
net_one = self.create_node(cls=ptp_class, start=start)
|
||||
net_one = self.create_node(cls=PtpNet, start=start)
|
||||
|
||||
# node to network
|
||||
if node_one and net_one:
|
||||
|
@ -300,7 +356,7 @@ class Session(object):
|
|||
net_one.name,
|
||||
net_two.name,
|
||||
)
|
||||
if nodeutils.is_node(net_two, NodeTypes.RJ45):
|
||||
if isinstance(net_two, Rj45Node):
|
||||
interface = net_two.linknet(net_one)
|
||||
else:
|
||||
interface = net_one.linknet(net_two)
|
||||
|
@ -324,12 +380,12 @@ class Session(object):
|
|||
|
||||
# tunnel node logic
|
||||
key = link_options.key
|
||||
if key and nodeutils.is_node(net_one, NodeTypes.TUNNEL):
|
||||
if key and isinstance(net_one, TunnelNode):
|
||||
logging.info("setting tunnel key for: %s", net_one.name)
|
||||
net_one.setkey(key)
|
||||
if addresses:
|
||||
net_one.addrconfig(addresses)
|
||||
if key and nodeutils.is_node(net_two, NodeTypes.TUNNEL):
|
||||
if key and isinstance(net_two, TunnelNode):
|
||||
logging.info("setting tunnel key for: %s", net_two.name)
|
||||
net_two.setkey(key)
|
||||
if addresses:
|
||||
|
@ -337,14 +393,14 @@ class Session(object):
|
|||
|
||||
# physical node connected with tunnel
|
||||
if not net_one and not net_two and (node_one or node_two):
|
||||
if node_one and nodeutils.is_node(node_one, NodeTypes.PHYSICAL):
|
||||
if node_one and isinstance(node_one, PhysicalNode):
|
||||
logging.info("adding link for physical node: %s", node_one.name)
|
||||
addresses = interface_one.get_addresses()
|
||||
node_one.adoptnetif(
|
||||
tunnel, interface_one.id, interface_one.mac, addresses
|
||||
)
|
||||
link_config(node_one, tunnel, link_options)
|
||||
elif node_two and nodeutils.is_node(node_two, NodeTypes.PHYSICAL):
|
||||
elif node_two and isinstance(node_two, PhysicalNode):
|
||||
logging.info("adding link for physical node: %s", node_two.name)
|
||||
addresses = interface_two.get_addresses()
|
||||
node_two.adoptnetif(
|
||||
|
@ -584,14 +640,11 @@ class Session(object):
|
|||
:param int _id: id for node, defaults to None for generated id
|
||||
:param core.emulator.emudata.NodeOptions node_options: data to create node with
|
||||
:return: created node
|
||||
:raises core.CoreError: when an invalid node type is given
|
||||
"""
|
||||
|
||||
# retrieve node class for given node type
|
||||
try:
|
||||
node_class = nodeutils.get_node_class(_type)
|
||||
except KeyError:
|
||||
logging.error("invalid node type to create: %s", _type)
|
||||
return None
|
||||
# validate node type, get class, or throw error
|
||||
node_class = self.get_node_class(_type)
|
||||
|
||||
# set node start based on current session state, override and check when rj45
|
||||
start = self.state > EventTypes.DEFINITION_STATE.value
|
||||
|
@ -651,10 +704,8 @@ class Session(object):
|
|||
logging.debug("set node type: %s", node.type)
|
||||
self.services.add_services(node, node.type, node_options.services)
|
||||
|
||||
# boot nodes if created after runtime, LcxNodes, Physical, and RJ45 are all PyCoreNodes
|
||||
is_boot_node = isinstance(node, CoreNodeBase) and not nodeutils.is_node(
|
||||
node, NodeTypes.RJ45
|
||||
)
|
||||
# boot nodes if created after runtime, CoreNodes, Physical, and RJ45 are all nodes
|
||||
is_boot_node = isinstance(node, CoreNodeBase) and not isinstance(node, Rj45Node)
|
||||
if self.state == EventTypes.RUNTIME_STATE.value and is_boot_node:
|
||||
self.write_nodes()
|
||||
self.add_remove_control_interface(node=node, remove=False)
|
||||
|
@ -1441,12 +1492,10 @@ class Session(object):
|
|||
count = 0
|
||||
for node_id in self.nodes:
|
||||
node = self.nodes[node_id]
|
||||
is_p2p_ctrlnet = nodeutils.is_node(
|
||||
node, (NodeTypes.PEER_TO_PEER, NodeTypes.CONTROL_NET)
|
||||
is_p2p_ctrlnet = isinstance(node, (PtpNet, CtrlNet))
|
||||
is_tap = isinstance(node, GreTapBridge) and not isinstance(
|
||||
node, TunnelNode
|
||||
)
|
||||
is_tap = nodeutils.is_node(
|
||||
node, NodeTypes.TAP_BRIDGE
|
||||
) and not nodeutils.is_node(node, NodeTypes.TUNNEL)
|
||||
if is_p2p_ctrlnet or is_tap:
|
||||
continue
|
||||
|
||||
|
@ -1493,7 +1542,7 @@ class Session(object):
|
|||
for node_id in self.nodes:
|
||||
node = self.nodes[node_id]
|
||||
# TODO: determine if checking for CoreNode alone is ok
|
||||
if isinstance(node, core.nodes.base.CoreNodeBase):
|
||||
if isinstance(node, CoreNodeBase):
|
||||
self.services.stop_services(node)
|
||||
|
||||
# shutdown emane
|
||||
|
@ -1546,10 +1595,7 @@ class Session(object):
|
|||
start = time.time()
|
||||
for _id in self.nodes:
|
||||
node = self.nodes[_id]
|
||||
# TODO: PyCoreNode is not the type to check
|
||||
if isinstance(node, CoreNodeBase) and not nodeutils.is_node(
|
||||
node, NodeTypes.RJ45
|
||||
):
|
||||
if isinstance(node, CoreNodeBase) and not isinstance(node, Rj45Node):
|
||||
# add a control interface if configured
|
||||
logging.info(
|
||||
"booting node(%s): %s",
|
||||
|
@ -1648,8 +1694,7 @@ class Session(object):
|
|||
# no controlnet needed
|
||||
return None
|
||||
else:
|
||||
control_net_class = nodeutils.get_node_class(NodeTypes.CONTROL_NET)
|
||||
prefix_spec = control_net_class.DEFAULT_PREFIX_LIST[net_index]
|
||||
prefix_spec = CtrlNet.DEFAULT_PREFIX_LIST[net_index]
|
||||
logging.debug("prefix spec: %s", prefix_spec)
|
||||
|
||||
server_interface = self.get_control_net_server_interfaces()[net_index]
|
||||
|
@ -1725,9 +1770,8 @@ class Session(object):
|
|||
prefix = prefixes[0]
|
||||
|
||||
logging.info("controlnet prefix: %s - %s", type(prefix), prefix)
|
||||
control_net_class = nodeutils.get_node_class(NodeTypes.CONTROL_NET)
|
||||
control_net = self.create_node(
|
||||
cls=control_net_class,
|
||||
cls=CtrlNet,
|
||||
_id=_id,
|
||||
prefix=prefix,
|
||||
assign_address=assign_address,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue