refactored some future naming to be more consistent, added new data objects to pass into coreemu api to help make scripting easier, set sessions to master by default now
This commit is contained in:
parent
1404ca19c5
commit
3ea885e2eb
9 changed files with 550 additions and 449 deletions
|
@ -9,8 +9,8 @@ from core.coreobj import PyCoreNode, PyCoreNet
|
|||
from core.data import NodeData
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.enumerations import NodeTypes, EventTypes, LinkTypes
|
||||
from core.future.futuredata import InterfaceData, LinkOptions
|
||||
from core.misc import nodeutils
|
||||
from core.misc.ipaddress import Ipv4Prefix
|
||||
from core.netns.nodes import CoreNode
|
||||
from core.session import Session
|
||||
from core.xml.xmlparser import core_document_parser
|
||||
|
@ -36,62 +36,13 @@ signal.signal(signal.SIGUSR1, signal_handler)
|
|||
signal.signal(signal.SIGUSR2, signal_handler)
|
||||
|
||||
|
||||
class InterfaceData(object):
|
||||
"""
|
||||
Convenience class for storing interface data.
|
||||
"""
|
||||
|
||||
def __init__(self, _id, name, mac, ip4, ip4_mask, ip6, ip6_mask):
|
||||
"""
|
||||
Creates an InterfaceData object.
|
||||
|
||||
:param int _id:
|
||||
:param str name:
|
||||
:param str mac:
|
||||
:param str ip4:
|
||||
:param int ip4_mask:
|
||||
:param str ip6:
|
||||
:param int ip6_mask:
|
||||
"""
|
||||
self.id = _id
|
||||
self.name = name
|
||||
self.mac = mac
|
||||
self.ip4 = ip4
|
||||
self.ip4_mask = ip4_mask
|
||||
self.ip6 = ip6
|
||||
self.ip6_mask = ip6_mask
|
||||
|
||||
def has_ip4(self):
|
||||
return all([self.ip4, self.ip4_mask])
|
||||
|
||||
def has_ip6(self):
|
||||
return all([self.ip6, self.ip6_mask])
|
||||
|
||||
def ip4_address(self):
|
||||
if self.has_ip4():
|
||||
return "%s/%s" % (self.ip4, self.ip4_mask)
|
||||
else:
|
||||
return None
|
||||
|
||||
def ip6_address(self):
|
||||
if self.has_ip6():
|
||||
return "%s/%s" % (self.ip6, self.ip6_mask)
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_addresses(self):
|
||||
ip4 = self.ip4_address()
|
||||
ip6 = self.ip6_address()
|
||||
return [i for i in [ip4, ip6] if i]
|
||||
|
||||
|
||||
def get_interfaces(link_data):
|
||||
"""
|
||||
Creates interface data objects for the interfaces defined within link data.
|
||||
|
||||
:param core.data.LinkData link_data: data to create interface data from
|
||||
:return: interface one and two data
|
||||
:rtype: tuple[InterfaceData]
|
||||
:rtype: tuple[core.future.futuredata.InterfaceData]
|
||||
"""
|
||||
interface_one = InterfaceData(
|
||||
_id=link_data.interface1_id,
|
||||
|
@ -120,7 +71,7 @@ def create_interface(node, network, interface_data):
|
|||
|
||||
:param node: node to create interface for
|
||||
:param network: network to associate interface with
|
||||
:param InterfaceData interface_data: interface data
|
||||
:param core.future.futuredata.InterfaceData interface_data: interface data
|
||||
:return: created interface
|
||||
"""
|
||||
node.newnetif(
|
||||
|
@ -133,24 +84,24 @@ def create_interface(node, network, interface_data):
|
|||
return node.netif(interface_data.id, network)
|
||||
|
||||
|
||||
def link_config(network, interface, link_data, devname=None, interface_two=None):
|
||||
def link_config(network, interface, link_options, devname=None, interface_two=None):
|
||||
"""
|
||||
Convenience method for configuring a link,
|
||||
|
||||
:param network: network to configure link for
|
||||
:param interface: interface to configure
|
||||
:param core.data.LinkData link_data: data to configure link with
|
||||
:param core.future.futuredata.LinkOptions link_options: data to configure link with
|
||||
:param str devname: device name, default is None
|
||||
:param interface_two: other interface associated, default is None
|
||||
:return: nothing
|
||||
"""
|
||||
config = {
|
||||
"netif": interface,
|
||||
"bw": link_data.bandwidth,
|
||||
"delay": link_data.delay,
|
||||
"loss": link_data.per,
|
||||
"duplicate": link_data.dup,
|
||||
"jitter": link_data.jitter,
|
||||
"bw": link_options.bandwidth,
|
||||
"delay": link_options.delay,
|
||||
"loss": link_options.per,
|
||||
"duplicate": link_options.dup,
|
||||
"jitter": link_options.jitter,
|
||||
"netif2": interface_two
|
||||
}
|
||||
|
||||
|
@ -192,12 +143,6 @@ class IdGen(object):
|
|||
return self.id
|
||||
|
||||
|
||||
class FutureIpv4Prefix(Ipv4Prefix):
|
||||
def get_address(self, node_id):
|
||||
address = self.addr(node_id)
|
||||
return "%s/%s" % (address, self.prefixlen)
|
||||
|
||||
|
||||
class FutureSession(Session):
|
||||
def __init__(self, session_id, config=None, persistent=True, mkdir=True):
|
||||
super(FutureSession, self).__init__(session_id, config, persistent, mkdir)
|
||||
|
@ -214,39 +159,37 @@ class FutureSession(Session):
|
|||
"host": ("DefaultRoute", "SSH"),
|
||||
}
|
||||
|
||||
def link_nodes(self, link_data):
|
||||
def _link_nodes(self, node_one_id, node_two_id):
|
||||
"""
|
||||
Convenience method for retrieving nodes within link data.
|
||||
|
||||
:param core.data.LinkData link_data: data to retrieve nodes from
|
||||
:return: nodes, network nodes if presetn, and tunnel
|
||||
:param int node_one_id: node one id
|
||||
:param int node_two_id: node two id
|
||||
:return: nodes, network nodes if present, and tunnel if present
|
||||
:rtype: tuple
|
||||
"""
|
||||
logger.info("link message between node1(%s:%s) and node2(%s:%s)",
|
||||
link_data.node1_id, link_data.interface1_id, link_data.node2_id, link_data.interface2_id)
|
||||
logger.info("link message between node1(%s) and node2(%s)", node_one_id, node_two_id)
|
||||
|
||||
# values to fill
|
||||
net_one = None
|
||||
net_two = None
|
||||
|
||||
# retrieve node one
|
||||
n1_id = link_data.node1_id
|
||||
n2_id = link_data.node2_id
|
||||
node_one = self.get_object(n1_id)
|
||||
node_two = self.get_object(n2_id)
|
||||
node_one = self.get_object(node_one_id)
|
||||
node_two = self.get_object(node_two_id)
|
||||
|
||||
# both node ids are provided
|
||||
tunnel = self.broker.gettunnel(n1_id, n2_id)
|
||||
tunnel = self.broker.gettunnel(node_one_id, node_two_id)
|
||||
logger.info("tunnel between nodes: %s", tunnel)
|
||||
if nodeutils.is_node(tunnel, NodeTypes.TAP_BRIDGE):
|
||||
net_one = tunnel
|
||||
if tunnel.remotenum == n1_id:
|
||||
if tunnel.remotenum == node_one_id:
|
||||
node_one = None
|
||||
else:
|
||||
node_two = None
|
||||
# physical node connected via gre tap tunnel
|
||||
elif tunnel:
|
||||
if tunnel.remotenum == n1_id:
|
||||
if tunnel.remotenum == node_one_id:
|
||||
node_one = None
|
||||
else:
|
||||
node_two = None
|
||||
|
@ -296,18 +239,19 @@ class FutureSession(Session):
|
|||
else:
|
||||
raise ValueError("no common network found for wireless link/unlink")
|
||||
|
||||
def link_add(self, link_data):
|
||||
def add_link(self, node_one_id, node_two_id, interface_one=None, interface_two=None, link_options=LinkOptions()):
|
||||
"""
|
||||
Add a link between nodes.
|
||||
|
||||
:param core.data.LinkData link_data: data to create a link with
|
||||
:return: nothing
|
||||
:param int node_one_id: node one id
|
||||
:param int node_two_id: node two id
|
||||
:param core.future.futuredata.InterfaceData interface_one: node one interface data, defaults to none
|
||||
:param core.future.futuredata.InterfaceData interface_two: node two interface data, defaults to none
|
||||
:param core.future.futuredata.LinkOptions link_options: data for creating link, defaults to no options
|
||||
:return:
|
||||
"""
|
||||
# interface data
|
||||
interface_one_data, interface_two_data = get_interfaces(link_data)
|
||||
|
||||
# get node objects identified by link data
|
||||
node_one, node_two, net_one, net_two, tunnel = self.link_nodes(link_data)
|
||||
node_one, node_two, net_one, net_two, tunnel = self._link_nodes(node_one_id, node_two_id)
|
||||
|
||||
if node_one:
|
||||
node_one.lock.acquire()
|
||||
|
@ -316,7 +260,7 @@ class FutureSession(Session):
|
|||
|
||||
try:
|
||||
# wireless link
|
||||
if link_data.link_type == LinkTypes.WIRELESS.value:
|
||||
if link_options.type == LinkTypes.WIRELESS:
|
||||
objects = [node_one, node_two, net_one, net_two]
|
||||
self._link_wireless(objects, connect=True)
|
||||
# wired link
|
||||
|
@ -329,14 +273,14 @@ class FutureSession(Session):
|
|||
|
||||
# node to network
|
||||
if node_one and net_one:
|
||||
interface = create_interface(node_one, net_one, interface_one_data)
|
||||
link_config(net_one, interface, link_data)
|
||||
interface = create_interface(node_one, net_one, interface_one)
|
||||
link_config(net_one, interface, link_options)
|
||||
|
||||
# network to node
|
||||
if node_two and net_one:
|
||||
interface = create_interface(node_two, net_one, interface_two_data)
|
||||
if not link_data.unidirectional:
|
||||
link_config(net_one, interface, link_data)
|
||||
interface = create_interface(node_two, net_one, interface_two)
|
||||
if not link_options.unidirectional:
|
||||
link_config(net_one, interface, link_options)
|
||||
|
||||
# network to network
|
||||
if net_one and net_two:
|
||||
|
@ -345,23 +289,23 @@ class FutureSession(Session):
|
|||
else:
|
||||
interface = net_one.linknet(net_two)
|
||||
|
||||
link_config(net_one, interface, link_data)
|
||||
link_config(net_one, interface, link_options)
|
||||
|
||||
if not link_data.unidirectional:
|
||||
if not link_options.unidirectional:
|
||||
interface.swapparams("_params_up")
|
||||
link_config(net_two, interface, link_data, devname=interface.name)
|
||||
link_config(net_two, interface, link_options, devname=interface.name)
|
||||
interface.swapparams("_params_up")
|
||||
|
||||
# a tunnel node was found for the nodes
|
||||
addresses = []
|
||||
if not node_one and net_one:
|
||||
addresses.extend(interface_one_data.get_addresses())
|
||||
if not node_one and all([net_one, interface_one]):
|
||||
addresses.extend(interface_one.get_addresses())
|
||||
|
||||
if not node_two and net_two:
|
||||
addresses.extend(interface_two_data.get_addresses())
|
||||
if not node_two and all([net_two, interface_two]):
|
||||
addresses.extend(interface_two.get_addresses())
|
||||
|
||||
# tunnel node logic
|
||||
key = link_data.key
|
||||
key = link_options.key
|
||||
if key and nodeutils.is_node(net_one, NodeTypes.TUNNEL):
|
||||
net_one.setkey(key)
|
||||
if addresses:
|
||||
|
@ -374,31 +318,35 @@ class FutureSession(Session):
|
|||
# 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):
|
||||
addresses = interface_one_data.get_addresses()
|
||||
node_one.adoptnetif(tunnel, link_data.interface1_id, link_data.interface1_mac, addresses)
|
||||
link_config(node_one, tunnel, link_data)
|
||||
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):
|
||||
addresses = interface_two_data.get_addresses()
|
||||
node_two.adoptnetif(tunnel, link_data.interface2_id, link_data.interface2_mac, addresses)
|
||||
link_config(node_two, tunnel, link_data)
|
||||
addresses = interface_two.get_addresses()
|
||||
node_two.adoptnetif(tunnel, interface_two.id, interface_two.mac, addresses)
|
||||
link_config(node_two, tunnel, link_options)
|
||||
finally:
|
||||
if node_one:
|
||||
node_one.lock.release()
|
||||
if node_two:
|
||||
node_two.lock.release()
|
||||
|
||||
def link_delete(self, link_data):
|
||||
def delete_link(self, node_one_id, node_two_id, interface_one_id, interface_two_id, link_type=LinkTypes.WIRED):
|
||||
"""
|
||||
Delete a link between nodes.
|
||||
|
||||
:param core.data.LinkData link_data: data to delete link with
|
||||
:param int node_one_id: node one id
|
||||
:param int node_two_id: node two id
|
||||
:param int interface_one_id: interface id for node one
|
||||
:param int interface_two_id: interface id for node two
|
||||
:param core.enumerations.LinkTypes link_type: link type to delete
|
||||
:return: nothing
|
||||
"""
|
||||
# interface data
|
||||
interface_one_data, interface_two_data = get_interfaces(link_data)
|
||||
# interface_one_data, interface_two_data = get_interfaces(link_data)
|
||||
|
||||
# get node objects identified by link data
|
||||
node_one, node_two, net_one, net_two, tunnel = self.link_nodes(link_data)
|
||||
node_one, node_two, net_one, net_two, tunnel = self._link_nodes(node_one_id, node_two_id)
|
||||
|
||||
if node_one:
|
||||
node_one.lock.acquire()
|
||||
|
@ -407,7 +355,7 @@ class FutureSession(Session):
|
|||
|
||||
try:
|
||||
# wireless link
|
||||
if link_data.link_type == LinkTypes.WIRELESS.value:
|
||||
if link_type == LinkTypes.WIRELESS:
|
||||
objects = [node_one, node_two, net_one, net_two]
|
||||
self._link_wireless(objects, connect=False)
|
||||
# wired link
|
||||
|
@ -415,8 +363,8 @@ class FutureSession(Session):
|
|||
if all([node_one, node_two]):
|
||||
# TODO: fix this for the case where ifindex[1,2] are not specified
|
||||
# a wired unlink event, delete the connecting bridge
|
||||
interface_one = node_one.netif(interface_one_data.id)
|
||||
interface_two = node_two.netif(interface_two_data.id)
|
||||
interface_one = node_one.netif(interface_one_id)
|
||||
interface_two = node_two.netif(interface_two_id)
|
||||
|
||||
# get interfaces from common network, if no network node
|
||||
# otherwise get interfaces between a node and network
|
||||
|
@ -446,18 +394,22 @@ class FutureSession(Session):
|
|||
if node_two:
|
||||
node_two.lock.release()
|
||||
|
||||
def link_update(self, link_data):
|
||||
def update_link(self, node_one_id, node_two_id, link_options, interface_one_id=None, interface_two_id=None):
|
||||
"""
|
||||
Update link information between nodes.
|
||||
|
||||
:param core.data.LinkData link_data: data to update link with
|
||||
:param int node_one_id: node one id
|
||||
:param int node_two_id: node two id
|
||||
:param int interface_one_id: interface id for node one
|
||||
:param int interface_two_id: interface id for node two
|
||||
:param core.future.futuredata.LinkOptions link_options: data to update link with
|
||||
:return: nothing
|
||||
"""
|
||||
# interface data
|
||||
interface_one_data, interface_two_data = get_interfaces(link_data)
|
||||
# interface_one_data, interface_two_data = get_interfaces(link_data)
|
||||
|
||||
# get node objects identified by link data
|
||||
node_one, node_two, net_one, net_two, tunnel = self.link_nodes(link_data)
|
||||
node_one, node_two, net_one, net_two, tunnel = self._link_nodes(node_one_id, node_two_id)
|
||||
|
||||
if node_one:
|
||||
node_one.lock.acquire()
|
||||
|
@ -466,7 +418,7 @@ class FutureSession(Session):
|
|||
|
||||
try:
|
||||
# wireless link
|
||||
if link_data.link_type == LinkTypes.WIRELESS.value:
|
||||
if link_options.type == LinkTypes.WIRELESS.value:
|
||||
raise ValueError("cannot update wireless link")
|
||||
else:
|
||||
if not node_one and not node_two:
|
||||
|
@ -484,37 +436,37 @@ class FutureSession(Session):
|
|||
|
||||
if upstream:
|
||||
interface.swapparams("_params_up")
|
||||
link_config(net_one, interface, link_data, devname=interface.name)
|
||||
link_config(net_one, interface, link_options, devname=interface.name)
|
||||
interface.swapparams("_params_up")
|
||||
else:
|
||||
link_config(net_one, interface, link_data)
|
||||
link_config(net_one, interface, link_options)
|
||||
|
||||
if not link_data.unidirectional:
|
||||
if not link_options.unidirectional:
|
||||
if upstream:
|
||||
link_config(net_two, interface, link_data)
|
||||
link_config(net_two, interface, link_options)
|
||||
else:
|
||||
interface.swapparams("_params_up")
|
||||
link_config(net_two, interface, link_data, devname=interface.name)
|
||||
link_config(net_two, interface, link_options, devname=interface.name)
|
||||
interface.swapparams("_params_up")
|
||||
else:
|
||||
raise ValueError("modify link for unknown nodes")
|
||||
elif not node_one:
|
||||
# node1 = layer 2node, node2 = layer3 node
|
||||
interface = node_two.netif(interface_two_data.id, net_one)
|
||||
link_config(net_one, interface, link_data)
|
||||
interface = node_two.netif(interface_two_id, net_one)
|
||||
link_config(net_one, interface, link_options)
|
||||
elif not node_two:
|
||||
# node2 = layer 2node, node1 = layer3 node
|
||||
interface = node_one.netif(interface_one_data.id, net_one)
|
||||
link_config(net_one, interface, link_data)
|
||||
interface = node_one.netif(interface_one_id, net_one)
|
||||
link_config(net_one, interface, link_options)
|
||||
else:
|
||||
common_networks = node_one.commonnets(node_two)
|
||||
for net_one, interface_one, interface_two in common_networks:
|
||||
if interface_one_data.id and interface_one_data.id != node_one.getifindex(interface_one):
|
||||
if interface_one_id and interface_one_id != node_one.getifindex(interface_one):
|
||||
continue
|
||||
|
||||
link_config(net_one, interface_one, link_data, interface_two=interface_two)
|
||||
if not link_data.unidirectional:
|
||||
link_config(net_one, interface_two, link_data, interface_two=interface_one)
|
||||
link_config(net_one, interface_one, link_options, interface_two=interface_two)
|
||||
if not link_options.unidirectional:
|
||||
link_config(net_one, interface_two, link_options, interface_two=interface_one)
|
||||
else:
|
||||
raise ValueError("no common network found")
|
||||
finally:
|
||||
|
@ -523,30 +475,29 @@ class FutureSession(Session):
|
|||
if node_two:
|
||||
node_two.lock.release()
|
||||
|
||||
def node_add(self, node_data):
|
||||
def add_node(self, node_options):
|
||||
"""
|
||||
Add a node to the session, based on the provided node data.
|
||||
|
||||
:param core.data.NodeData node_data: data to create node with
|
||||
:return: nothing
|
||||
:param core.future.futuredata.NodeOptions node_options: data to create node with
|
||||
:return: created node
|
||||
"""
|
||||
|
||||
# retrieve node class for given node type
|
||||
try:
|
||||
node_type = NodeTypes(node_data.node_type)
|
||||
node_class = nodeutils.get_node_class(node_type)
|
||||
node_class = nodeutils.get_node_class(node_options.type)
|
||||
except KeyError:
|
||||
logger.error("invalid node type to create: %s", node_data.node_type)
|
||||
logger.error("invalid node type to create: %s", node_options.type)
|
||||
return None
|
||||
|
||||
# set node start based on current session state, override and check when rj45
|
||||
start = self.state > EventTypes.DEFINITION_STATE.value
|
||||
enable_rj45 = getattr(self.options, "enablerj45", "0") == "1"
|
||||
if node_type == NodeTypes.RJ45 and not enable_rj45:
|
||||
if node_options.type == NodeTypes.RJ45 and not enable_rj45:
|
||||
start = False
|
||||
|
||||
# determine node id
|
||||
node_id = node_data.id
|
||||
node_id = node_options.id
|
||||
if not node_id:
|
||||
while True:
|
||||
node_id = self.node_id_gen.next()
|
||||
|
@ -554,7 +505,7 @@ class FutureSession(Session):
|
|||
break
|
||||
|
||||
# generate name if not provided
|
||||
name = node_data.name
|
||||
name = node_options.name
|
||||
if not name:
|
||||
name = "%s%s" % (node_class.__name__, node_id)
|
||||
|
||||
|
@ -563,18 +514,18 @@ class FutureSession(Session):
|
|||
node = self.add_object(cls=node_class, objid=node_id, name=name, start=start)
|
||||
|
||||
# set node attributes
|
||||
node.type = node_data.model or "router"
|
||||
node.icon = node_data.icon
|
||||
node.canvas = node_data.canvas
|
||||
node.opaque = node_data.opaque
|
||||
node.type = node_options.model or "router"
|
||||
node.icon = node_options.icon
|
||||
node.canvas = node_options.canvas
|
||||
node.opaque = node_options.opaque
|
||||
|
||||
# set node position and broadcast it
|
||||
self.node_set_position(node, node_data)
|
||||
self.set_node_position(node, node_options)
|
||||
|
||||
# add services to default and physical nodes only
|
||||
services = node_data.services
|
||||
if node_type in [NodeTypes.DEFAULT, NodeTypes.PHYSICAL]:
|
||||
logger.info("setting model (%s) with services (%s)", node.type, services)
|
||||
if node_options.type in [NodeTypes.DEFAULT, NodeTypes.PHYSICAL]:
|
||||
logger.info("setting model (%s) with services (%s)", node.type, node_options.services)
|
||||
services = "|".join(node_options.services) or None
|
||||
self.services.addservicestonode(node, node.type, services)
|
||||
|
||||
# boot nodes if created after runtime, LcxNodes, Physical, and RJ45 are all PyCoreNodes
|
||||
|
@ -586,35 +537,35 @@ class FutureSession(Session):
|
|||
# TODO: common method to both Physical and LxcNodes, but not the common PyCoreNode
|
||||
node.boot()
|
||||
|
||||
# return node id, in case it was generated
|
||||
return node_id
|
||||
return node
|
||||
|
||||
def node_update(self, node_data):
|
||||
def update_node(self, node_options):
|
||||
"""
|
||||
Update node information.
|
||||
|
||||
:param core.data.NodeData node_data: data to update node with
|
||||
:param core.future.futuredata.NodeOptions node_options: data to update node with
|
||||
:return: nothing
|
||||
"""
|
||||
try:
|
||||
# get node to update
|
||||
node = self.get_object(node_data.id)
|
||||
node = self.get_object(node_options.id)
|
||||
|
||||
# set node position and broadcast it
|
||||
self.node_set_position(node, node_data)
|
||||
self.set_node_position(node, node_options)
|
||||
|
||||
# update attributes
|
||||
node.canvas = node_data.canvas
|
||||
node.icon = node_data.icon
|
||||
node.canvas = node_options.canvas
|
||||
node.icon = node_options.icon
|
||||
except KeyError:
|
||||
logger.error("failure to update node that does not exist: %s", node_data.id)
|
||||
logger.error("failure to update node that does not exist: %s", node_options.id)
|
||||
|
||||
def node_delete(self, node_id):
|
||||
def delete_node(self, node_id):
|
||||
"""
|
||||
Delete a node from the session and check if session should shutdown, if no nodes are left.
|
||||
|
||||
:param int node_id:
|
||||
:return: True if node deleted, False otherwise
|
||||
:rtype: bool
|
||||
"""
|
||||
# delete node and check for session shutdown if a node was removed
|
||||
result = self.custom_delete_object(node_id)
|
||||
|
@ -622,20 +573,20 @@ class FutureSession(Session):
|
|||
self.check_shutdown()
|
||||
return result
|
||||
|
||||
def node_set_position(self, node, node_data):
|
||||
def set_node_position(self, node, node_options):
|
||||
"""
|
||||
Set position for a node, use lat/lon/alt if needed.
|
||||
|
||||
:param node: node to set position for
|
||||
:param NodeData node_data: data for node
|
||||
:param core.future.futuredata.NodeOptions node_options: data for node
|
||||
:return: nothing
|
||||
"""
|
||||
# extract location values
|
||||
x = node_data.x_position
|
||||
y = node_data.y_position
|
||||
lat = node_data.latitude
|
||||
lon = node_data.longitude
|
||||
alt = node_data.altitude
|
||||
x = node_options.x
|
||||
y = node_options.y
|
||||
lat = node_options.lat
|
||||
lon = node_options.lon
|
||||
alt = node_options.alt
|
||||
|
||||
# check if we need to generate position from lat/lon/alt
|
||||
has_empty_position = all(i is None for i in [x, y])
|
||||
|
@ -741,7 +692,7 @@ class FutureSession(Session):
|
|||
doc = core_document_writer(self, version)
|
||||
doc.writexml(file_name)
|
||||
|
||||
def hook_add(self, state, file_name, source_name, data):
|
||||
def add_hook(self, state, file_name, source_name, data):
|
||||
"""
|
||||
Store a hook from a received file message.
|
||||
|
||||
|
@ -755,7 +706,7 @@ class FutureSession(Session):
|
|||
state = ":%s" % state
|
||||
self.set_hook(state, file_name, source_name, data)
|
||||
|
||||
def node_service_file(self, node_id, service_name, file_name, source_name, data):
|
||||
def add_node_service_file(self, node_id, service_name, file_name, source_name, data):
|
||||
"""
|
||||
Add a service file for a node.
|
||||
|
||||
|
@ -770,7 +721,7 @@ class FutureSession(Session):
|
|||
service_name = ":%s" % service_name
|
||||
self.services.setservicefile(node_id, service_name, file_name, source_name, data)
|
||||
|
||||
def node_file(self, node_id, source_name, file_name, data):
|
||||
def add_node_file(self, node_id, source_name, file_name, data):
|
||||
"""
|
||||
Add a file to a node.
|
||||
|
||||
|
@ -874,16 +825,16 @@ class FutureSession(Session):
|
|||
self.set_emane_model(emane_network, model)
|
||||
return emane_network
|
||||
|
||||
def set_emane_model(self, emane_node, model):
|
||||
def set_emane_model(self, emane_node, emane_model):
|
||||
"""
|
||||
Set emane model for a given emane node.
|
||||
|
||||
:param emane_node: emane node to set model for
|
||||
:param model: emane model to set
|
||||
:param emane_model: emane model to set
|
||||
:return: nothing
|
||||
"""
|
||||
values = list(model.getdefaultvalues())
|
||||
self.emane.setconfig(emane_node.objid, model.name, values)
|
||||
values = list(emane_model.getdefaultvalues())
|
||||
self.emane.setconfig(emane_node.objid, emane_model.name, values)
|
||||
|
||||
|
||||
class CoreEmu(object):
|
||||
|
@ -921,7 +872,7 @@ class CoreEmu(object):
|
|||
session.shutdown()
|
||||
self.sessions.clear()
|
||||
|
||||
def create_session(self, _id=None, master=False):
|
||||
def create_session(self, _id=None, master=True):
|
||||
"""
|
||||
Create a new CORE session, set to master if running standalone.
|
||||
|
||||
|
@ -981,15 +932,16 @@ class CoreEmu(object):
|
|||
for common_network, interface_one, interface_two in node.commonnets(network):
|
||||
common_network.link(interface_one, interface_two)
|
||||
|
||||
def add_interface(self, network, node, prefix):
|
||||
def add_interface(self, network, node, prefixes):
|
||||
"""
|
||||
Convenience method for adding an interface with a prefix based on node id.
|
||||
|
||||
:param network: network to add interface with
|
||||
:param node: node to add interface to
|
||||
:param prefix: prefix to get address from for interface
|
||||
:param core.future.futuredata.IpPrefixes prefixes: to get address from for interface
|
||||
:return: created interface
|
||||
"""
|
||||
address = prefix.get_address(node.objid)
|
||||
interface_index = node.newnetif(network, [address])
|
||||
interface_data = prefixes.create_interface(node)
|
||||
logger.info("adding interface: %s", interface_data.get_addresses())
|
||||
interface_index = node.newnetif(network, interface_data.get_addresses(), ifindex=interface_data.id)
|
||||
return node.netif(interface_index)
|
||||
|
|
225
daemon/core/future/futuredata.py
Normal file
225
daemon/core/future/futuredata.py
Normal file
|
@ -0,0 +1,225 @@
|
|||
from core.enumerations import LinkTypes
|
||||
from core.misc.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
|
||||
|
||||
|
||||
class NodeOptions(object):
|
||||
"""
|
||||
Options for creating and updating nodes within core.
|
||||
"""
|
||||
|
||||
def __init__(self, _type=None, _id=None, name=None, model=None):
|
||||
"""
|
||||
Create a NodeOptions object.
|
||||
|
||||
:param core.enumerations.NodeType _type: type of node to create
|
||||
:param int _id: id for node being created, defaults to generated id
|
||||
:param str name: name of node, defaults to node class name postfix with its id
|
||||
:param str model: model to use for this node, defines services
|
||||
"""
|
||||
self.id = _id
|
||||
self.name = name
|
||||
self.type = _type
|
||||
self.model = model
|
||||
self.canvas = None
|
||||
self.icon = None
|
||||
self.opaque = None
|
||||
self.services = []
|
||||
self.x = None
|
||||
self.y = None
|
||||
self.lat = None
|
||||
self.lon = None
|
||||
self.alt = None
|
||||
self.emulation_id = None
|
||||
self.emulation_server = None
|
||||
|
||||
def set_position(self, x, y):
|
||||
"""
|
||||
Convenience method for setting position.
|
||||
|
||||
:param int x: x position
|
||||
:param int y: y position
|
||||
:return: nothing
|
||||
"""
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def set_location(self, lat, lon, alt):
|
||||
"""
|
||||
Convenience method for setting location.
|
||||
|
||||
:param float lat: latitude
|
||||
:param float lon: longitude
|
||||
:param float alt: altitude
|
||||
:return: nothing
|
||||
"""
|
||||
self.lat = lat
|
||||
self.lon = lon
|
||||
self.alt = alt
|
||||
|
||||
|
||||
class LinkOptions(object):
|
||||
"""
|
||||
Options for creating and updating links within core.
|
||||
"""
|
||||
|
||||
def __init__(self, _type=LinkTypes.WIRED):
|
||||
"""
|
||||
Create a LinkOptions object.
|
||||
|
||||
:param core.enumerations.LinkTypes _type: type of link, defaults to wired
|
||||
"""
|
||||
self.type = _type
|
||||
self.session = None
|
||||
self.delay = None
|
||||
self.bandwidth = None
|
||||
self.per = None
|
||||
self.dup = None
|
||||
self.jitter = None
|
||||
self.mer = None
|
||||
self.burst = None
|
||||
self.mburst = None
|
||||
self.gui_attributes = None
|
||||
self.unidirectional = None
|
||||
self.emulation_id = None
|
||||
self.network_id = None
|
||||
self.key = None
|
||||
self.opaque = None
|
||||
|
||||
|
||||
class IpPrefixes(object):
|
||||
"""
|
||||
Convenience class to help generate IP4 and IP6 addresses for nodes within CORE.
|
||||
"""
|
||||
|
||||
def __init__(self, ip4_prefix=None, ip6_prefix=None):
|
||||
"""
|
||||
Creates an IpPrefixes object.
|
||||
|
||||
:param str ip4_prefix: ip4 prefix to use for generation
|
||||
:param str ip6_prefix: ip6 prefix to use for generation
|
||||
:raises ValueError: when both ip4 and ip6 prefixes have not been provided
|
||||
"""
|
||||
if not ip4_prefix and not ip6_prefix:
|
||||
raise ValueError("ip4 or ip6 must be provided")
|
||||
|
||||
self.ip4 = None
|
||||
if ip4_prefix:
|
||||
self.ip4 = Ipv4Prefix(ip4_prefix)
|
||||
self.ip6 = None
|
||||
if ip6_prefix:
|
||||
self.ip6 = Ipv6Prefix(ip6_prefix)
|
||||
|
||||
def ip4_address(self, node):
|
||||
"""
|
||||
Convenience method to return the IP4 address for a node.
|
||||
|
||||
:param node: node to get IP4 address for
|
||||
:return: IP4 address or None
|
||||
:rtype: str
|
||||
"""
|
||||
if not self.ip4:
|
||||
raise ValueError("ip4 prefixes have not been set")
|
||||
return str(self.ip4.addr(node.objid))
|
||||
|
||||
def ip6_address(self, node):
|
||||
"""
|
||||
Convenience method to return the IP6 address for a node.
|
||||
|
||||
:param node: node to get IP6 address for
|
||||
:return: IP4 address or None
|
||||
:rtype: str
|
||||
"""
|
||||
if not self.ip6:
|
||||
raise ValueError("ip6 prefixes have not been set")
|
||||
return str(self.ip6.addr(node.objid))
|
||||
|
||||
def create_interface(self, node, name=None, mac=None):
|
||||
"""
|
||||
Creates interface data for linking nodes, using the nodes unique id for generation, along with a random
|
||||
mac address, unless provided.
|
||||
|
||||
:param core.coreobj.PyCoreNode node: node to create interface for
|
||||
:param str name: name to set for interface, default is eth{id}
|
||||
:param str mac: mac address to use for this interface, default is random generation
|
||||
:return: new interface data for the provided node
|
||||
:rtype: InterfaceData
|
||||
"""
|
||||
# interface id
|
||||
inteface_id = node.newifindex()
|
||||
|
||||
# generate ip4 data
|
||||
ip4 = None
|
||||
ip4_mask = None
|
||||
if self.ip4:
|
||||
ip4 = str(self.ip4.addr(node.objid))
|
||||
ip4_mask = self.ip4.prefixlen
|
||||
|
||||
# generate ip6 data
|
||||
ip6 = None
|
||||
ip6_mask = None
|
||||
if self.ip6:
|
||||
ip6 = str(self.ip6.addr(node.objid))
|
||||
ip6_mask = self.ip6.prefixlen
|
||||
|
||||
# random mac
|
||||
if not mac:
|
||||
mac = str(MacAddress.random())
|
||||
|
||||
return InterfaceData(
|
||||
_id=inteface_id,
|
||||
name=name,
|
||||
ip4=ip4,
|
||||
ip4_mask=ip4_mask,
|
||||
ip6=ip6,
|
||||
ip6_mask=ip6_mask,
|
||||
mac=mac
|
||||
)
|
||||
|
||||
|
||||
class InterfaceData(object):
|
||||
"""
|
||||
Convenience class for storing interface data.
|
||||
"""
|
||||
|
||||
def __init__(self, _id, name, mac, ip4, ip4_mask, ip6, ip6_mask):
|
||||
"""
|
||||
Creates an InterfaceData object.
|
||||
|
||||
:param int _id:
|
||||
:param str name:
|
||||
:param str mac:
|
||||
:param str ip4:
|
||||
:param int ip4_mask:
|
||||
:param str ip6:
|
||||
:param int ip6_mask:
|
||||
"""
|
||||
self.id = _id
|
||||
self.name = name
|
||||
self.mac = mac
|
||||
self.ip4 = ip4
|
||||
self.ip4_mask = ip4_mask
|
||||
self.ip6 = ip6
|
||||
self.ip6_mask = ip6_mask
|
||||
|
||||
def has_ip4(self):
|
||||
return all([self.ip4, self.ip4_mask])
|
||||
|
||||
def has_ip6(self):
|
||||
return all([self.ip6, self.ip6_mask])
|
||||
|
||||
def ip4_address(self):
|
||||
if self.has_ip4():
|
||||
return "%s/%s" % (self.ip4, self.ip4_mask)
|
||||
else:
|
||||
return None
|
||||
|
||||
def ip6_address(self):
|
||||
if self.has_ip6():
|
||||
return "%s/%s" % (self.ip6, self.ip6_mask)
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_addresses(self):
|
||||
ip4 = self.ip4_address()
|
||||
ip6 = self.ip6_address()
|
||||
return [i for i in [ip4, ip6] if i]
|
|
@ -14,10 +14,9 @@ import time
|
|||
from core import logger
|
||||
from core.api import coreapi
|
||||
from core.coreserver import CoreServer
|
||||
from core.data import ConfigData, LinkData
|
||||
from core.data import ConfigData
|
||||
from core.data import EventData
|
||||
from core.data import NodeData
|
||||
from core.enumerations import ConfigTlvs
|
||||
from core.enumerations import ConfigTlvs, LinkTypes
|
||||
from core.enumerations import EventTlvs
|
||||
from core.enumerations import EventTypes
|
||||
from core.enumerations import ExceptionTlvs
|
||||
|
@ -30,6 +29,7 @@ from core.enumerations import NodeTlvs
|
|||
from core.enumerations import NodeTypes
|
||||
from core.enumerations import RegisterTlvs
|
||||
from core.enumerations import SessionTlvs
|
||||
from core.future.futuredata import NodeOptions, LinkOptions, InterfaceData
|
||||
from core.misc import nodeutils
|
||||
from core.misc import structutils
|
||||
from core.misc import utils
|
||||
|
@ -566,7 +566,7 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
|||
port = self.request.getpeername()[1]
|
||||
|
||||
# TODO: add shutdown handler for session
|
||||
self.session = self.coreemu.create_session(port)
|
||||
self.session = self.coreemu.create_session(port, master=False)
|
||||
# self.session.shutdown_handlers.append(self.session_shutdown)
|
||||
logger.info("created new session for client: %s", self.session.session_id)
|
||||
|
||||
|
@ -642,44 +642,58 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
|||
logger.warn("ignoring invalid message: add and delete flag both set")
|
||||
return ()
|
||||
|
||||
# create node data from message data
|
||||
node_data = NodeData(
|
||||
id=message.get_tlv(NodeTlvs.NUMBER.value),
|
||||
x_position=message.get_tlv(NodeTlvs.X_POSITION.value),
|
||||
y_position=message.get_tlv(NodeTlvs.Y_POSITION.value),
|
||||
canvas=message.get_tlv(NodeTlvs.CANVAS.value),
|
||||
icon=message.get_tlv(NodeTlvs.ICON.value),
|
||||
latitude=message.get_tlv(NodeTlvs.LATITUDE.value),
|
||||
longitude=message.get_tlv(NodeTlvs.LONGITUDE.value),
|
||||
altitude=message.get_tlv(NodeTlvs.ALTITUDE.value),
|
||||
node_type=message.get_tlv(NodeTlvs.TYPE.value),
|
||||
node_type = None
|
||||
node_type_value = message.get_tlv(NodeTlvs.TYPE.value)
|
||||
if node_type_value is not None:
|
||||
node_type = NodeTypes(node_type_value)
|
||||
|
||||
node_options = NodeOptions(
|
||||
_type=node_type,
|
||||
_id=message.get_tlv(NodeTlvs.NUMBER.value),
|
||||
name=message.get_tlv(NodeTlvs.NAME.value),
|
||||
model=message.get_tlv(NodeTlvs.MODEL.value),
|
||||
opaque=message.get_tlv(NodeTlvs.OPAQUE.value),
|
||||
services=message.get_tlv(NodeTlvs.SERVICES.value),
|
||||
model=message.get_tlv(NodeTlvs.MODEL.value)
|
||||
)
|
||||
|
||||
node_options.set_position(
|
||||
x=message.get_tlv(NodeTlvs.X_POSITION.value),
|
||||
y=message.get_tlv(NodeTlvs.Y_POSITION.value)
|
||||
)
|
||||
|
||||
node_options.set_location(
|
||||
lat=message.get_tlv(NodeTlvs.LATITUDE.value),
|
||||
lon=message.get_tlv(NodeTlvs.LONGITUDE.value),
|
||||
alt=message.get_tlv(NodeTlvs.ALTITUDE.value)
|
||||
)
|
||||
|
||||
node_options.icon = message.get_tlv(NodeTlvs.ICON.value)
|
||||
node_options.canvas = message.get_tlv(NodeTlvs.CANVAS.value)
|
||||
node_options.opaque = message.get_tlv(NodeTlvs.OPAQUE.value)
|
||||
|
||||
services = message.get_tlv(NodeTlvs.SERVICES.value)
|
||||
if services:
|
||||
node_options.services = services.split("|")
|
||||
|
||||
if message.flags & MessageFlags.ADD.value:
|
||||
node_id = self.session.node_add(node_data)
|
||||
if node_id:
|
||||
node = self.session.add_node(node_options)
|
||||
if node:
|
||||
if message.flags & MessageFlags.STRING.value:
|
||||
self.node_status_request[node_id] = True
|
||||
self.node_status_request[node.objid] = True
|
||||
|
||||
if self.session.state == EventTypes.RUNTIME_STATE.value:
|
||||
self.send_node_emulation_id(node_id)
|
||||
self.send_node_emulation_id(node.objid)
|
||||
elif message.flags & MessageFlags.DELETE.value:
|
||||
with self._shutdown_lock:
|
||||
result = self.session.node_delete(node_data.id)
|
||||
result = self.session.delete_node(node_options.id)
|
||||
|
||||
# if we deleted a node broadcast out its removal
|
||||
if result and message.flags & MessageFlags.STRING.value:
|
||||
tlvdata = ""
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(NodeTlvs.NUMBER.value, node_data.id)
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(NodeTlvs.NUMBER.value, node_options.id)
|
||||
flags = MessageFlags.DELETE.value | MessageFlags.LOCAL.value
|
||||
replies.append(coreapi.CoreNodeMessage.pack(flags, tlvdata))
|
||||
# node update
|
||||
else:
|
||||
self.session.node_update(node_data)
|
||||
self.session.update_node(node_options)
|
||||
|
||||
return replies
|
||||
|
||||
|
@ -690,47 +704,56 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
|||
:param coreapi.CoreLinkMessage message: link message to handle
|
||||
:return: link message replies
|
||||
"""
|
||||
link_data = LinkData(
|
||||
session=message.get_tlv(LinkTlvs.SESSION.value),
|
||||
link_type=message.get_tlv(LinkTlvs.TYPE.value),
|
||||
node1_id=message.get_tlv(LinkTlvs.N1_NUMBER.value),
|
||||
node2_id=message.get_tlv(LinkTlvs.N2_NUMBER.value),
|
||||
delay=message.get_tlv(LinkTlvs.DELAY.value),
|
||||
bandwidth=message.get_tlv(LinkTlvs.BANDWIDTH.value),
|
||||
per=message.get_tlv(LinkTlvs.PER.value),
|
||||
dup=message.get_tlv(LinkTlvs.DUP.value),
|
||||
jitter=message.get_tlv(LinkTlvs.JITTER.value),
|
||||
mer=message.get_tlv(LinkTlvs.MER.value),
|
||||
burst=message.get_tlv(LinkTlvs.BURST.value),
|
||||
mburst=message.get_tlv(LinkTlvs.MBURST.value),
|
||||
gui_attributes=message.get_tlv(LinkTlvs.GUI_ATTRIBUTES.value),
|
||||
unidirectional=message.get_tlv(LinkTlvs.UNIDIRECTIONAL.value),
|
||||
emulation_id=message.get_tlv(LinkTlvs.EMULATION_ID.value),
|
||||
network_id=message.get_tlv(LinkTlvs.NETWORK_ID.value),
|
||||
key=message.get_tlv(LinkTlvs.KEY.value),
|
||||
opaque=message.get_tlv(LinkTlvs.OPAQUE.value),
|
||||
interface1_id=message.get_tlv(LinkTlvs.INTERFACE1_NUMBER.value),
|
||||
interface1_name=message.get_tlv(LinkTlvs.INTERFACE1_NAME.value),
|
||||
interface1_ip4=message.get_tlv(LinkTlvs.INTERFACE1_IP4.value),
|
||||
interface1_ip4_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP4_MASK.value),
|
||||
interface1_mac=message.get_tlv(LinkTlvs.INTERFACE1_MAC.value),
|
||||
interface1_ip6=message.get_tlv(LinkTlvs.INTERFACE1_IP6.value),
|
||||
interface1_ip6_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP6_MASK.value),
|
||||
interface2_id=message.get_tlv(LinkTlvs.INTERFACE2_NUMBER.value),
|
||||
interface2_name=message.get_tlv(LinkTlvs.INTERFACE2_NAME.value),
|
||||
interface2_ip4=message.get_tlv(LinkTlvs.INTERFACE2_IP4.value),
|
||||
interface2_ip4_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP4_MASK.value),
|
||||
interface2_mac=message.get_tlv(LinkTlvs.INTERFACE2_MAC.value),
|
||||
interface2_ip6=message.get_tlv(LinkTlvs.INTERFACE2_IP6.value),
|
||||
interface2_ip6_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP6_MASK.value),
|
||||
node_one_id = message.get_tlv(LinkTlvs.N1_NUMBER.value)
|
||||
node_two_id = message.get_tlv(LinkTlvs.N2_NUMBER.value)
|
||||
|
||||
interface_one = InterfaceData(
|
||||
_id=message.get_tlv(LinkTlvs.INTERFACE1_NUMBER.value),
|
||||
name=message.get_tlv(LinkTlvs.INTERFACE1_NAME.value),
|
||||
mac=message.get_tlv(LinkTlvs.INTERFACE1_MAC.value),
|
||||
ip4=message.get_tlv(LinkTlvs.INTERFACE1_IP4.value),
|
||||
ip4_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP4_MASK.value),
|
||||
ip6=message.get_tlv(LinkTlvs.INTERFACE1_IP6.value),
|
||||
ip6_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP6_MASK.value),
|
||||
)
|
||||
interface_two = InterfaceData(
|
||||
_id=message.get_tlv(LinkTlvs.INTERFACE2_NUMBER.value),
|
||||
name=message.get_tlv(LinkTlvs.INTERFACE2_NAME.value),
|
||||
mac=message.get_tlv(LinkTlvs.INTERFACE2_MAC.value),
|
||||
ip4=message.get_tlv(LinkTlvs.INTERFACE2_IP4.value),
|
||||
ip4_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP4_MASK.value),
|
||||
ip6=message.get_tlv(LinkTlvs.INTERFACE2_IP6.value),
|
||||
ip6_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP6_MASK.value),
|
||||
)
|
||||
|
||||
link_type = None
|
||||
link_type_value = message.get_tlv(LinkTlvs.TYPE.value)
|
||||
if link_type_value is not None:
|
||||
link_type = LinkTypes(link_type_value)
|
||||
|
||||
link_options = LinkOptions(_type=link_type)
|
||||
link_options.delay = message.get_tlv(LinkTlvs.DELAY.value)
|
||||
link_options.bandwidth = message.get_tlv(LinkTlvs.BANDWIDTH.value)
|
||||
link_options.session = message.get_tlv(LinkTlvs.SESSION.value)
|
||||
link_options.per = message.get_tlv(LinkTlvs.PER.value)
|
||||
link_options.dup = message.get_tlv(LinkTlvs.DUP.value)
|
||||
link_options.jitter = message.get_tlv(LinkTlvs.JITTER.value)
|
||||
link_options.mer = message.get_tlv(LinkTlvs.MER.value)
|
||||
link_options.burst = message.get_tlv(LinkTlvs.BURST.value)
|
||||
link_options.mburst = message.get_tlv(LinkTlvs.MBURST.value)
|
||||
link_options.gui_attributes = message.get_tlv(LinkTlvs.GUI_ATTRIBUTES.value)
|
||||
link_options.unidirectional = message.get_tlv(LinkTlvs.UNIDIRECTIONAL.value)
|
||||
link_options.emulation_id = message.get_tlv(LinkTlvs.EMULATION_ID.value)
|
||||
link_options.network_id = message.get_tlv(LinkTlvs.NETWORK_ID.value)
|
||||
link_options.key = message.get_tlv(LinkTlvs.KEY.value)
|
||||
link_options.opaque = message.get_tlv(LinkTlvs.OPAQUE.value)
|
||||
|
||||
if message.flags & MessageFlags.ADD.value:
|
||||
self.session.link_add(link_data)
|
||||
self.session.add_link(node_one_id, node_two_id, interface_one, interface_two, link_options)
|
||||
elif message.flags & MessageFlags.DELETE.value:
|
||||
self.session.link_delete(link_data)
|
||||
self.session.delete_link(node_one_id, node_two_id, interface_one.id, interface_two.id)
|
||||
else:
|
||||
self.session.link_update(link_data)
|
||||
self.session.update_link(node_one_id, node_two_id, interface_one.id, interface_two.id, link_options)
|
||||
|
||||
return ()
|
||||
|
||||
|
@ -829,7 +852,7 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
|||
file_name = sys.argv[0]
|
||||
|
||||
if os.path.splitext(file_name)[1].lower() == ".xml":
|
||||
session = self.coreemu.create_session()
|
||||
session = self.coreemu.create_session(master=False)
|
||||
try:
|
||||
session.open_xml(file_name, start=True)
|
||||
except:
|
||||
|
@ -962,7 +985,7 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
|||
if file_type is not None:
|
||||
if file_type.startswith("service:"):
|
||||
_, service_name = file_type.split(':')[:2]
|
||||
self.session.node_service_file(node_num, service_name, file_name, source_name, data)
|
||||
self.session.add_node_service_file(node_num, service_name, file_name, source_name, data)
|
||||
return ()
|
||||
elif file_type.startswith("hook:"):
|
||||
_, state = file_type.split(':')[:2]
|
||||
|
@ -970,7 +993,7 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
|||
logger.error("error setting hook having state '%s'", state)
|
||||
return ()
|
||||
state = int(state)
|
||||
self.session.hook_add(state, file_name, source_name, data)
|
||||
self.session.add_hook(state, file_name, source_name, data)
|
||||
return ()
|
||||
|
||||
# writing a file to the host
|
||||
|
|
|
@ -6,12 +6,13 @@ import datetime
|
|||
|
||||
import parser
|
||||
from core.emane.ieee80211abg import EmaneIeee80211abgModel
|
||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
||||
from core.future.coreemu import CoreEmu
|
||||
from core.future.futuredata import IpPrefixes
|
||||
|
||||
|
||||
def example(options):
|
||||
# ip generator for example
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||
|
||||
# create emulator instance for creating sessions and utility methods
|
||||
coreemu = CoreEmu()
|
||||
|
@ -27,8 +28,8 @@ def example(options):
|
|||
# create nodes
|
||||
for i in xrange(options.nodes):
|
||||
node = session.create_emane_node()
|
||||
coreemu.add_interface(emane_network, node, prefix)
|
||||
node.setposition(x=150 * (i + 1), y=150)
|
||||
coreemu.add_interface(emane_network, node, prefixes)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -39,7 +40,7 @@ def example(options):
|
|||
|
||||
# shutdown session
|
||||
raw_input("press enter to exit...")
|
||||
session.shutdown()
|
||||
coreemu.shutdown()
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
import datetime
|
||||
|
||||
import parser
|
||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
||||
from core.future.coreemu import CoreEmu
|
||||
from core.future.futuredata import IpPrefixes
|
||||
from core.netns.nodes import CoreNode, SwitchNode
|
||||
|
||||
|
||||
def example(options):
|
||||
# ip generator for example
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
prefixes = IpPrefixes("10.83.0.0/16")
|
||||
|
||||
# create emulator instance for creating sessions and utility methods
|
||||
coreemu = CoreEmu()
|
||||
|
@ -26,7 +27,7 @@ def example(options):
|
|||
# create nodes
|
||||
for _ in xrange(options.nodes):
|
||||
node = session.create_node(cls=CoreNode)
|
||||
coreemu.add_interface(switch_network, node, prefix)
|
||||
coreemu.add_interface(switch_network, node, prefixes)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -37,13 +38,13 @@ def example(options):
|
|||
|
||||
print "starting iperf server on node: %s" % first_node.name
|
||||
first_node.cmd(["iperf", "-s", "-D"])
|
||||
address = str(prefix.addr(first_node.objid))
|
||||
address = prefixes.ip4_address(first_node)
|
||||
print "node %s connecting to %s" % (last_node.name, address)
|
||||
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address])
|
||||
first_node.cmd(["killall", "-9", "iperf"])
|
||||
|
||||
# shutdown session
|
||||
session.shutdown()
|
||||
coreemu.shutdown()
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -8,41 +8,32 @@
|
|||
import datetime
|
||||
|
||||
import parser
|
||||
from core.data import NodeData, LinkData
|
||||
from core.enumerations import NodeTypes, EventTypes
|
||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
||||
from core.future.coreemu import CoreEmu
|
||||
from core.future.futuredata import IpPrefixes, NodeOptions
|
||||
|
||||
|
||||
def example(options):
|
||||
# ip generator for example
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||
|
||||
# create emulator instance for creating sessions and utility methods
|
||||
coreemu = CoreEmu()
|
||||
session = coreemu.create_session(master=True)
|
||||
session = coreemu.create_session()
|
||||
|
||||
# must be in configuration state for nodes to start, when using "node_add" below
|
||||
session.set_state(EventTypes.CONFIGURATION_STATE.value)
|
||||
|
||||
# create switch network node
|
||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
||||
switch_id = session.node_add(node_data)
|
||||
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||
switch = session.add_node(node_options)
|
||||
|
||||
# create nodes
|
||||
for _ in xrange(options.nodes):
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
||||
node_id = session.node_add(node_data)
|
||||
node = session.get_object(node_id)
|
||||
inteface_index = node.newifindex()
|
||||
address = prefix.addr(node_id)
|
||||
link_data = LinkData(
|
||||
node1_id=node_id,
|
||||
node2_id=switch_id,
|
||||
interface1_id=inteface_index,
|
||||
interface1_ip4=str(address),
|
||||
interface1_ip4_mask=prefix.prefixlen,
|
||||
)
|
||||
session.link_add(link_data)
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||
node = session.add_node(node_options)
|
||||
interface = prefixes.create_interface(node)
|
||||
session.add_link(node.objid, switch.objid, interface_one=interface)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -53,9 +44,9 @@ def example(options):
|
|||
|
||||
print "starting iperf server on node: %s" % first_node.name
|
||||
first_node.cmd(["iperf", "-s", "-D"])
|
||||
address = str(prefix.addr(first_node.objid))
|
||||
print "node %s connecting to %s" % (last_node.name, address)
|
||||
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address])
|
||||
first_node_address = prefixes.ip4_address(first_node)
|
||||
print "node %s connecting to %s" % (last_node.name, first_node_address)
|
||||
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", first_node_address])
|
||||
first_node.cmd(["killall", "-9", "iperf"])
|
||||
|
||||
# shutdown session
|
||||
|
|
|
@ -5,17 +5,13 @@
|
|||
# and repeat for minnodes <= n <= maxnodes with a step size of
|
||||
# nodestep
|
||||
|
||||
import datetime
|
||||
|
||||
import parser
|
||||
from core.data import NodeData, LinkData
|
||||
from core.enumerations import NodeTypes, EventTypes
|
||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
||||
from core.future.futuredata import IpPrefixes, NodeOptions
|
||||
|
||||
|
||||
def example(nodes):
|
||||
# ip generator for example
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
prefixes = IpPrefixes("10.83.0.0/16")
|
||||
|
||||
# create emulator instance for creating sessions and utility methods
|
||||
coreemu = globals()["coreemu"]
|
||||
|
@ -25,24 +21,15 @@ def example(nodes):
|
|||
session.set_state(EventTypes.CONFIGURATION_STATE.value)
|
||||
|
||||
# create switch network node
|
||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
||||
switch_id = session.node_add(node_data)
|
||||
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||
switch = session.add_node(node_options)
|
||||
|
||||
# create nodes
|
||||
for _ in xrange(nodes):
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
||||
node_id = session.node_add(node_data)
|
||||
node = session.get_object(node_id)
|
||||
inteface_index = node.newifindex()
|
||||
address = prefix.addr(node_id)
|
||||
link_data = LinkData(
|
||||
node1_id=node_id,
|
||||
node2_id=switch_id,
|
||||
interface1_id=inteface_index,
|
||||
interface1_ip4=str(address),
|
||||
interface1_ip4_mask=prefix.prefixlen,
|
||||
)
|
||||
session.link_add(link_data)
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT.value)
|
||||
node = session.add_node(node_options)
|
||||
interface = prefixes.create_interface(node)
|
||||
session.add_link(node.objid, switch.objid, interface_one=interface)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
|
|
@ -8,14 +8,15 @@
|
|||
import datetime
|
||||
|
||||
import parser
|
||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
||||
from core.future.coreemu import CoreEmu
|
||||
from core.future.futuredata import IpPrefixes
|
||||
from core.mobility import BasicRangeModel
|
||||
from core.netns.nodes import WlanNode, CoreNode
|
||||
|
||||
|
||||
def example(options):
|
||||
# ip generator for example
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
prefixes = IpPrefixes("10.83.0.0/16")
|
||||
|
||||
# create emulator instance for creating sessions and utility methods
|
||||
coreemu = CoreEmu()
|
||||
|
@ -29,7 +30,7 @@ def example(options):
|
|||
wireless_nodes = []
|
||||
for _ in xrange(options.nodes):
|
||||
node = session.create_node(cls=CoreNode)
|
||||
coreemu.add_interface(wlan_network, node, prefix)
|
||||
coreemu.add_interface(wlan_network, node, prefixes)
|
||||
wireless_nodes.append(node)
|
||||
|
||||
# link all created nodes with the wireless network
|
||||
|
@ -44,13 +45,13 @@ def example(options):
|
|||
|
||||
print "starting iperf server on node: %s" % first_node.name
|
||||
first_node.cmd(["iperf", "-s", "-D"])
|
||||
address = str(prefix.addr(first_node.objid))
|
||||
address = prefixes.ip4_address(first_node)
|
||||
print "node %s connecting to %s" % (last_node.name, address)
|
||||
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address])
|
||||
first_node.cmd(["killall", "-9", "iperf"])
|
||||
|
||||
# shutdown session
|
||||
session.shutdown()
|
||||
coreemu.shutdown()
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -3,9 +3,9 @@ import time
|
|||
|
||||
import pytest
|
||||
|
||||
from core.data import NodeData, LinkData
|
||||
from core.enumerations import NodeTypes, EventTypes
|
||||
from core.future.coreemu import CoreEmu, FutureIpv4Prefix
|
||||
from core.future.coreemu import CoreEmu
|
||||
from core.future.futuredata import IpPrefixes, NodeOptions, LinkOptions
|
||||
from core.misc import utils
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ from core.misc import utils
|
|||
def future_session():
|
||||
# use coreemu and create a session
|
||||
coreemu = CoreEmu()
|
||||
session = coreemu.create_session(master=True)
|
||||
session = coreemu.create_session()
|
||||
session.set_state(EventTypes.CONFIGURATION_STATE.value)
|
||||
|
||||
# return created session
|
||||
|
@ -41,16 +41,15 @@ class TestFuture:
|
|||
@pytest.mark.parametrize("model", MODELS)
|
||||
def test_node_add(self, future_session, model):
|
||||
# given
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value, model=model)
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT, model=model)
|
||||
|
||||
# when
|
||||
node_id = future_session.node_add(node_data)
|
||||
node = future_session.add_node(node_options)
|
||||
|
||||
# give time for node services to boot
|
||||
time.sleep(1)
|
||||
|
||||
# then
|
||||
node = future_session.get_object(node_id)
|
||||
assert node
|
||||
assert os.path.exists(node.nodedir)
|
||||
assert node.alive()
|
||||
|
@ -60,187 +59,116 @@ class TestFuture:
|
|||
|
||||
def test_node_update(self, future_session):
|
||||
# given
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
||||
node_id = future_session.node_add(node_data)
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||
node = future_session.add_node(node_options)
|
||||
position_value = 100
|
||||
update_data = NodeData(
|
||||
id=node_id,
|
||||
x_position=position_value,
|
||||
y_position=position_value
|
||||
)
|
||||
update_options = NodeOptions(_id=node.objid)
|
||||
update_options.set_position(x=position_value, y=position_value)
|
||||
|
||||
# when
|
||||
future_session.node_update(update_data)
|
||||
future_session.update_node(update_options)
|
||||
|
||||
# then
|
||||
node = future_session.get_object(node_id)
|
||||
assert node.position.x == position_value
|
||||
assert node.position.y == position_value
|
||||
|
||||
def test_node_delete(self, future_session):
|
||||
# given
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
||||
node_id = future_session.node_add(node_data)
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||
node = future_session.add_node(node_options)
|
||||
|
||||
# when
|
||||
future_session.node_delete(node_id)
|
||||
future_session.delete_node(node.objid)
|
||||
|
||||
# then
|
||||
with pytest.raises(KeyError):
|
||||
future_session.get_object(node_id)
|
||||
future_session.get_object(node.objid)
|
||||
|
||||
@pytest.mark.parametrize("net_type", NET_TYPES)
|
||||
def test_net(self, future_session, net_type):
|
||||
# given
|
||||
node_data = NodeData(node_type=net_type.value)
|
||||
node_options = NodeOptions(_type=net_type)
|
||||
|
||||
# when
|
||||
node_id = future_session.node_add(node_data)
|
||||
node = future_session.add_node(node_options)
|
||||
|
||||
# then
|
||||
node = future_session.get_object(node_id)
|
||||
assert node
|
||||
assert node.up
|
||||
assert utils.check_cmd(["brctl", "show", node.brname])
|
||||
|
||||
def test_ptp(self, future_session):
|
||||
# given
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
||||
node_one_id = future_session.node_add(node_data)
|
||||
node_two_id = future_session.node_add(node_data)
|
||||
|
||||
node_one = future_session.get_object(node_one_id)
|
||||
inteface_one_index = node_one.newifindex()
|
||||
address_one = prefix.addr(node_one_id)
|
||||
|
||||
node_two = future_session.get_object(node_two_id)
|
||||
inteface_two_index = node_two.newifindex()
|
||||
address_two = prefix.addr(node_two_id)
|
||||
|
||||
link_data = LinkData(
|
||||
node1_id=node_one_id,
|
||||
node2_id=node_two_id,
|
||||
interface1_id=inteface_one_index,
|
||||
interface1_ip4=str(address_one),
|
||||
interface1_ip4_mask=prefix.prefixlen,
|
||||
interface2_id=inteface_two_index,
|
||||
interface2_ip4=str(address_two),
|
||||
interface2_ip4_mask=prefix.prefixlen,
|
||||
)
|
||||
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||
node_one = future_session.add_node(node_options)
|
||||
node_two = future_session.add_node(node_options)
|
||||
interface_one = prefixes.create_interface(node_one)
|
||||
inteface_two = prefixes.create_interface(node_two)
|
||||
|
||||
# when
|
||||
future_session.link_add(link_data)
|
||||
future_session.add_link(node_one.objid, node_two.objid, interface_one, inteface_two)
|
||||
|
||||
# then
|
||||
assert node_one.netif(inteface_one_index)
|
||||
assert node_two.netif(inteface_two_index)
|
||||
assert node_one.netif(interface_one.id)
|
||||
assert node_two.netif(inteface_two.id)
|
||||
|
||||
def test_node_to_net(self, future_session):
|
||||
# given
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
||||
node_one = future_session.node_add(node_data)
|
||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
||||
node_two = future_session.node_add(node_data)
|
||||
|
||||
node = future_session.get_object(node_one)
|
||||
inteface_index = node.newifindex()
|
||||
address = prefix.addr(node_one)
|
||||
|
||||
link_data = LinkData(
|
||||
node1_id=node_one,
|
||||
node2_id=node_two,
|
||||
interface1_id=inteface_index,
|
||||
interface1_ip4=str(address),
|
||||
interface1_ip4_mask=prefix.prefixlen,
|
||||
)
|
||||
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||
node_one = future_session.add_node(node_options)
|
||||
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||
node_two = future_session.add_node(node_options)
|
||||
interface_one = prefixes.create_interface(node_one)
|
||||
|
||||
# when
|
||||
future_session.link_add(link_data)
|
||||
future_session.add_link(node_one.objid, node_two.objid, interface_one)
|
||||
|
||||
# then
|
||||
node_two = future_session.get_object(node_two)
|
||||
assert node_two.all_link_data(0)
|
||||
assert node.netif(inteface_index)
|
||||
assert node_one.netif(interface_one.id)
|
||||
|
||||
def test_net_to_node(self, future_session):
|
||||
# given
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||
|
||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
||||
node_one = future_session.node_add(node_data)
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
||||
node_two = future_session.node_add(node_data)
|
||||
|
||||
node = future_session.get_object(node_two)
|
||||
inteface_index = node.newifindex()
|
||||
address = prefix.addr(node_two)
|
||||
|
||||
link_data = LinkData(
|
||||
node1_id=node_one,
|
||||
node2_id=node_two,
|
||||
interface2_id=inteface_index,
|
||||
interface2_ip4=str(address),
|
||||
interface2_ip4_mask=prefix.prefixlen,
|
||||
)
|
||||
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||
node_one = future_session.add_node(node_options)
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||
node_two = future_session.add_node(node_options)
|
||||
interface_two = prefixes.create_interface(node_two)
|
||||
|
||||
# when
|
||||
future_session.link_add(link_data)
|
||||
future_session.add_link(node_one.objid, node_two.objid, interface_two=interface_two)
|
||||
|
||||
# then
|
||||
node_one = future_session.get_object(node_one)
|
||||
assert node_one.all_link_data(0)
|
||||
assert node.netif(inteface_index)
|
||||
assert node_two.netif(interface_two.id)
|
||||
|
||||
def test_net_to_net(self, future_session):
|
||||
# given
|
||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
||||
node_one = future_session.node_add(node_data)
|
||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
||||
node_two = future_session.node_add(node_data)
|
||||
|
||||
link_data = LinkData(
|
||||
node1_id=node_one,
|
||||
node2_id=node_two,
|
||||
)
|
||||
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||
node_one = future_session.add_node(node_options)
|
||||
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||
node_two = future_session.add_node(node_options)
|
||||
|
||||
# when
|
||||
future_session.link_add(link_data)
|
||||
future_session.add_link(node_one.objid, node_two.objid)
|
||||
|
||||
# then
|
||||
node_one = future_session.get_object(node_one)
|
||||
assert node_one.all_link_data(0)
|
||||
|
||||
def test_link_update(self, future_session):
|
||||
# given
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
||||
node_one = future_session.node_add(node_data)
|
||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
||||
node_two = future_session.node_add(node_data)
|
||||
node = future_session.get_object(node_one)
|
||||
inteface_index = node.newifindex()
|
||||
address = prefix.addr(node_one)
|
||||
link_data = LinkData(
|
||||
node1_id=node_one,
|
||||
node2_id=node_two,
|
||||
interface1_id=inteface_index,
|
||||
interface1_ip4=str(address),
|
||||
interface1_ip4_mask=prefix.prefixlen,
|
||||
)
|
||||
future_session.link_add(link_data)
|
||||
update_data = LinkData(
|
||||
node1_id=node_one,
|
||||
node2_id=node_two,
|
||||
interface1_id=inteface_index,
|
||||
delay=50,
|
||||
bandwidth=5000000,
|
||||
per=25,
|
||||
dup=25
|
||||
)
|
||||
interface = node.netif(inteface_index)
|
||||
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||
node_one = future_session.add_node(node_options)
|
||||
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||
node_two = future_session.add_node(node_options)
|
||||
interface_one = prefixes.create_interface(node_one)
|
||||
future_session.add_link(node_one.objid, node_two.objid, interface_one)
|
||||
interface = node_one.netif(interface_one.id)
|
||||
output = utils.check_cmd(["tc", "qdisc", "show", "dev", interface.localname])
|
||||
assert "delay" not in output
|
||||
assert "rate" not in output
|
||||
|
@ -248,7 +176,13 @@ class TestFuture:
|
|||
assert "duplicate" not in output
|
||||
|
||||
# when
|
||||
future_session.link_update(update_data)
|
||||
link_options = LinkOptions()
|
||||
link_options.delay = 50
|
||||
link_options.bandwidth = 5000000
|
||||
link_options.per = 25
|
||||
link_options.dup = 25
|
||||
future_session.update_link(node_one.objid, node_two.objid,
|
||||
interface_one_id=interface_one.id, link_options=link_options)
|
||||
|
||||
# then
|
||||
output = utils.check_cmd(["tc", "qdisc", "show", "dev", interface.localname])
|
||||
|
@ -259,35 +193,21 @@ class TestFuture:
|
|||
|
||||
def test_link_delete(self, future_session):
|
||||
# given
|
||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
||||
node_one_id = future_session.node_add(node_data)
|
||||
node_two_id = future_session.node_add(node_data)
|
||||
node_one = future_session.get_object(node_one_id)
|
||||
inteface_one_index = node_one.newifindex()
|
||||
address_one = prefix.addr(node_one_id)
|
||||
node_two = future_session.get_object(node_two_id)
|
||||
inteface_two_index = node_two.newifindex()
|
||||
address_two = prefix.addr(node_two_id)
|
||||
link_data = LinkData(
|
||||
node1_id=node_one_id,
|
||||
node2_id=node_two_id,
|
||||
interface1_id=inteface_one_index,
|
||||
interface1_ip4=str(address_one),
|
||||
interface1_ip4_mask=prefix.prefixlen,
|
||||
interface2_id=inteface_two_index,
|
||||
interface2_ip4=str(address_two),
|
||||
interface2_ip4_mask=prefix.prefixlen,
|
||||
)
|
||||
future_session.link_add(link_data)
|
||||
assert node_one.netif(inteface_one_index)
|
||||
assert node_two.netif(inteface_two_index)
|
||||
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||
node_one = future_session.add_node(node_options)
|
||||
node_two = future_session.add_node(node_options)
|
||||
interface_one = prefixes.create_interface(node_one)
|
||||
interface_two = prefixes.create_interface(node_two)
|
||||
future_session.add_link(node_one.objid, node_two.objid, interface_one, interface_two)
|
||||
assert node_one.netif(interface_one.id)
|
||||
assert node_two.netif(interface_two.id)
|
||||
assert future_session.get_node_count() == 3
|
||||
|
||||
# when
|
||||
future_session.link_delete(link_data)
|
||||
future_session.delete_link(node_one.objid, node_two.objid, interface_one.id, interface_two.id)
|
||||
|
||||
# then
|
||||
assert not node_one.netif(inteface_one_index)
|
||||
assert not node_two.netif(inteface_two_index)
|
||||
assert not node_one.netif(interface_one.id)
|
||||
assert not node_two.netif(interface_two.id)
|
||||
assert future_session.get_node_count() == 2
|
||||
|
|
Loading…
Reference in a new issue