Merge branch 'develop' into pydocupdates

This commit is contained in:
Huy Pham 2019-09-12 10:24:23 -07:00
commit 2bfcc9ef24
100 changed files with 5340 additions and 3488 deletions

View file

@ -10,8 +10,7 @@ from contextlib import contextmanager
import grpc
from core.api.grpc import core_pb2
from core.api.grpc import core_pb2_grpc
from core.api.grpc import core_pb2, core_pb2_grpc
from core.nodes.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
@ -99,7 +98,7 @@ class InterfaceHelper(object):
ip4mask=ip4_mask,
ip6=ip6,
ip6mask=ip6_mask,
mac=str(mac)
mac=str(mac),
)
@ -215,7 +214,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.SetSessionOptionsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetSessionOptionsRequest(session_id=session_id, config=config)
request = core_pb2.SetSessionOptionsRequest(
session_id=session_id, config=config
)
return self.stub.SetSessionOptions(request)
def get_session_location(self, session_id):
@ -230,7 +231,17 @@ class CoreGrpcClient(object):
request = core_pb2.GetSessionLocationRequest(session_id=session_id)
return self.stub.GetSessionLocation(request)
def set_session_location(self, session_id, x=None, y=None, z=None, lat=None, lon=None, alt=None, scale=None):
def set_session_location(
self,
session_id,
x=None,
y=None,
z=None,
lat=None,
lon=None,
alt=None,
scale=None,
):
"""
Set session location.
@ -247,7 +258,9 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session doesn't exist
"""
position = core_pb2.SessionPosition(x=x, y=y, z=z, lat=lat, lon=lon, alt=alt)
request = core_pb2.SetSessionLocationRequest(session_id=session_id, position=position, scale=scale)
request = core_pb2.SetSessionLocationRequest(
session_id=session_id, position=position, scale=scale
)
return self.stub.SetSessionLocation(request)
def set_session_state(self, session_id, state):
@ -324,7 +337,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.EditNodeResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.EditNodeRequest(session_id=session_id, node_id=node_id, position=position)
request = core_pb2.EditNodeRequest(
session_id=session_id, node_id=node_id, position=position
)
return self.stub.EditNode(request)
def delete_node(self, session_id, node_id):
@ -350,7 +365,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.NodeCommandResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.NodeCommandRequest(session_id=session_id, node_id=node_id, command=command)
request = core_pb2.NodeCommandRequest(
session_id=session_id, node_id=node_id, command=command
)
return self.stub.NodeCommand(request)
def get_node_terminal(self, session_id, node_id):
@ -363,7 +380,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.GetNodeTerminalResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeTerminalRequest(session_id=session_id, node_id=node_id)
request = core_pb2.GetNodeTerminalRequest(
session_id=session_id, node_id=node_id
)
return self.stub.GetNodeTerminal(request)
def get_node_links(self, session_id, node_id):
@ -379,7 +398,15 @@ class CoreGrpcClient(object):
request = core_pb2.GetNodeLinksRequest(session_id=session_id, node_id=node_id)
return self.stub.GetNodeLinks(request)
def add_link(self, session_id, node_one_id, node_two_id, interface_one=None, interface_two=None, options=None):
def add_link(
self,
session_id,
node_one_id,
node_two_id,
interface_one=None,
interface_two=None,
options=None,
):
"""
Add a link between nodes.
@ -394,12 +421,25 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session or one of the nodes don't exist
"""
link = core_pb2.Link(
node_one_id=node_one_id, node_two_id=node_two_id, type=core_pb2.LinkType.WIRED,
interface_one=interface_one, interface_two=interface_two, options=options)
node_one_id=node_one_id,
node_two_id=node_two_id,
type=core_pb2.LinkType.WIRED,
interface_one=interface_one,
interface_two=interface_two,
options=options,
)
request = core_pb2.AddLinkRequest(session_id=session_id, link=link)
return self.stub.AddLink(request)
def edit_link(self, session_id, node_one_id, node_two_id, options, interface_one_id=None, interface_two_id=None):
def edit_link(
self,
session_id,
node_one_id,
node_two_id,
options,
interface_one_id=None,
interface_two_id=None,
):
"""
Edit a link between nodes.
@ -414,11 +454,23 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session or one of the nodes don't exist
"""
request = core_pb2.EditLinkRequest(
session_id=session_id, node_one_id=node_one_id, node_two_id=node_two_id, options=options,
interface_one_id=interface_one_id, interface_two_id=interface_two_id)
session_id=session_id,
node_one_id=node_one_id,
node_two_id=node_two_id,
options=options,
interface_one_id=interface_one_id,
interface_two_id=interface_two_id,
)
return self.stub.EditLink(request)
def delete_link(self, session_id, node_one_id, node_two_id, interface_one_id=None, interface_two_id=None):
def delete_link(
self,
session_id,
node_one_id,
node_two_id,
interface_one_id=None,
interface_two_id=None,
):
"""
Delete a link between nodes.
@ -432,8 +484,12 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.DeleteLinkRequest(
session_id=session_id, node_one_id=node_one_id, node_two_id=node_two_id,
interface_one_id=interface_one_id, interface_two_id=interface_two_id)
session_id=session_id,
node_one_id=node_one_id,
node_two_id=node_two_id,
interface_one_id=interface_one_id,
interface_two_id=interface_two_id,
)
return self.stub.DeleteLink(request)
def get_hooks(self, session_id):
@ -486,7 +542,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.GetMobilityConfigResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetMobilityConfigRequest(session_id=session_id, node_id=node_id)
request = core_pb2.GetMobilityConfigRequest(
session_id=session_id, node_id=node_id
)
return self.stub.GetMobilityConfig(request)
def set_mobility_config(self, session_id, node_id, config):
@ -500,7 +558,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.SetMobilityConfigResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.SetMobilityConfigRequest(session_id=session_id, node_id=node_id, config=config)
request = core_pb2.SetMobilityConfigRequest(
session_id=session_id, node_id=node_id, config=config
)
return self.stub.SetMobilityConfig(request)
def mobility_action(self, session_id, node_id, action):
@ -514,7 +574,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.MobilityActionResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.MobilityActionRequest(session_id=session_id, node_id=node_id, action=action)
request = core_pb2.MobilityActionRequest(
session_id=session_id, node_id=node_id, action=action
)
return self.stub.MobilityAction(request)
def get_services(self):
@ -554,7 +616,9 @@ class CoreGrpcClient(object):
services = service_defaults[node_type]
default = core_pb2.ServiceDefaults(node_type=node_type, services=services)
defaults.append(default)
request = core_pb2.SetServiceDefaultsRequest(session_id=session_id, defaults=defaults)
request = core_pb2.SetServiceDefaultsRequest(
session_id=session_id, defaults=defaults
)
return self.stub.SetServiceDefaults(request)
def get_node_service(self, session_id, node_id, service):
@ -568,7 +632,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.GetNodeServiceResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeServiceRequest(session_id=session_id, node_id=node_id, service=service)
request = core_pb2.GetNodeServiceRequest(
session_id=session_id, node_id=node_id, service=service
)
return self.stub.GetNodeService(request)
def get_node_service_file(self, session_id, node_id, service, file_name):
@ -584,10 +650,13 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeServiceFileRequest(
session_id=session_id, node_id=node_id, service=service, file=file_name)
session_id=session_id, node_id=node_id, service=service, file=file_name
)
return self.stub.GetNodeServiceFile(request)
def set_node_service(self, session_id, node_id, service, startup, validate, shutdown):
def set_node_service(
self, session_id, node_id, service, startup, validate, shutdown
):
"""
Set service data for a node.
@ -602,8 +671,13 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.SetNodeServiceRequest(
session_id=session_id, node_id=node_id, service=service, startup=startup, validate=validate,
shutdown=shutdown)
session_id=session_id,
node_id=node_id,
service=service,
startup=startup,
validate=validate,
shutdown=shutdown,
)
return self.stub.SetNodeService(request)
def set_node_service_file(self, session_id, node_id, service, file_name, data):
@ -620,7 +694,12 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.SetNodeServiceFileRequest(
session_id=session_id, node_id=node_id, service=service, file=file_name, data=data)
session_id=session_id,
node_id=node_id,
service=service,
file=file_name,
data=data,
)
return self.stub.SetNodeServiceFile(request)
def service_action(self, session_id, node_id, service, action):
@ -635,7 +714,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.ServiceActionResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.ServiceActionRequest(session_id=session_id, node_id=node_id, service=service, action=action)
request = core_pb2.ServiceActionRequest(
session_id=session_id, node_id=node_id, service=service, action=action
)
return self.stub.ServiceAction(request)
def get_wlan_config(self, session_id, node_id):
@ -662,7 +743,9 @@ class CoreGrpcClient(object):
:rtype: core_pb2.SetWlanConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetWlanConfigRequest(session_id=session_id, node_id=node_id, config=config)
request = core_pb2.SetWlanConfigRequest(
session_id=session_id, node_id=node_id, config=config
)
return self.stub.SetWlanConfig(request)
def get_emane_config(self, session_id):
@ -715,10 +798,13 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetEmaneModelConfigRequest(
session_id=session_id, node_id=node_id, model=model, interface=interface_id)
session_id=session_id, node_id=node_id, model=model, interface=interface_id
)
return self.stub.GetEmaneModelConfig(request)
def set_emane_model_config(self, session_id, node_id, model, config, interface_id=-1):
def set_emane_model_config(
self, session_id, node_id, model, config, interface_id=-1
):
"""
Set emane model configuration for a node or a node's interface.
@ -732,7 +818,12 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetEmaneModelConfigRequest(
session_id=session_id, node_id=node_id, model=model, config=config, interface_id=interface_id)
session_id=session_id,
node_id=node_id,
model=model,
config=config,
interface_id=interface_id,
)
return self.stub.SetEmaneModelConfig(request)
def get_emane_model_configs(self, session_id):

View file

@ -4,17 +4,24 @@ import os
import re
import tempfile
import time
import grpc
from builtins import int
from concurrent import futures
from queue import Queue, Empty
from queue import Empty, Queue
from core.api.grpc import core_pb2
from core.api.grpc import core_pb2_grpc
from core.emulator.data import NodeData, LinkData, EventData, ConfigData, ExceptionData, FileData
from core.emulator.emudata import NodeOptions, InterfaceData, LinkOptions
from core.emulator.enumerations import NodeTypes, EventTypes, LinkTypes
import grpc
from core import CoreError
from core.api.grpc import core_pb2, core_pb2_grpc
from core.emulator.data import (
ConfigData,
EventData,
ExceptionData,
FileData,
LinkData,
NodeData,
)
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
from core.emulator.enumerations import EventTypes, LinkTypes, NodeTypes
from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility
from core.nodes import nodeutils
from core.nodes.base import CoreNetworkBase
@ -50,8 +57,10 @@ def get_config_groups(config, configurable_options):
for config_group in configurable_options.config_groups():
start = config_group.start - 1
stop = config_group.stop
options = config_options[start: stop]
config_group_proto = core_pb2.ConfigGroup(name=config_group.name, options=options)
options = config_options[start:stop]
config_group_proto = core_pb2.ConfigGroup(
name=config_group.name, options=options
)
groups.append(config_group_proto)
return groups
@ -87,9 +96,14 @@ def convert_link(session, link_data):
interface = node.netif(link_data.interface1_id)
interface_name = interface.name
interface_one = core_pb2.Interface(
id=link_data.interface1_id, name=interface_name, mac=convert_value(link_data.interface1_mac),
ip4=convert_value(link_data.interface1_ip4), ip4mask=link_data.interface1_ip4_mask,
ip6=convert_value(link_data.interface1_ip6), ip6mask=link_data.interface1_ip6_mask)
id=link_data.interface1_id,
name=interface_name,
mac=convert_value(link_data.interface1_mac),
ip4=convert_value(link_data.interface1_ip4),
ip4mask=link_data.interface1_ip4_mask,
ip6=convert_value(link_data.interface1_ip6),
ip6mask=link_data.interface1_ip6_mask,
)
interface_two = None
if link_data.interface2_id is not None:
@ -99,9 +113,14 @@ def convert_link(session, link_data):
interface = node.netif(link_data.interface2_id)
interface_name = interface.name
interface_two = core_pb2.Interface(
id=link_data.interface2_id, name=interface_name, mac=convert_value(link_data.interface2_mac),
ip4=convert_value(link_data.interface2_ip4), ip4mask=link_data.interface2_ip4_mask,
ip6=convert_value(link_data.interface2_ip6), ip6mask=link_data.interface2_ip6_mask)
id=link_data.interface2_id,
name=interface_name,
mac=convert_value(link_data.interface2_mac),
ip4=convert_value(link_data.interface2_ip4),
ip4mask=link_data.interface2_ip4_mask,
ip6=convert_value(link_data.interface2_ip6),
ip6mask=link_data.interface2_ip6_mask,
)
options = core_pb2.LinkOptions(
opaque=link_data.opaque,
@ -114,12 +133,16 @@ def convert_link(session, link_data):
burst=link_data.burst,
delay=link_data.delay,
dup=link_data.dup,
unidirectional=link_data.unidirectional
unidirectional=link_data.unidirectional,
)
return core_pb2.Link(
type=link_data.link_type, node_one_id=link_data.node1_id, node_two_id=link_data.node2_id,
interface_one=interface_one, interface_two=interface_two, options=options
type=link_data.link_type,
node_one_id=link_data.node1_id,
node_two_id=link_data.node2_id,
interface_one=interface_one,
interface_two=interface_two,
options=options,
)
@ -158,7 +181,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
context.abort(grpc.StatusCode.CANCELLED, "server stopping")
def listen(self, address):
logging.info("starting grpc api: %s", address)
logging.info("CORE gRPC API listening on: %s", address)
self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
core_pb2_grpc.add_CoreApiServicer_to_server(self, self.server)
self.server.add_insecure_port(address)
@ -173,14 +196,18 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def get_session(self, session_id, context):
session = self.coreemu.sessions.get(session_id)
if not session:
context.abort(grpc.StatusCode.NOT_FOUND, "session {} not found".format(session_id))
context.abort(
grpc.StatusCode.NOT_FOUND, "session {} not found".format(session_id)
)
return session
def get_node(self, session, node_id, context):
try:
return session.get_node(node_id)
except KeyError:
context.abort(grpc.StatusCode.NOT_FOUND, "node {} not found".format(node_id))
context.abort(
grpc.StatusCode.NOT_FOUND, "node {} not found".format(node_id)
)
def CreateSession(self, request, context):
logging.debug("create session: %s", request)
@ -188,7 +215,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
session.set_state(EventTypes.DEFINITION_STATE)
session.location.setrefgeo(47.57917, -122.13232, 2.0)
session.location.refscale = 150000.0
return core_pb2.CreateSessionResponse(session_id=session.id, state=session.state)
return core_pb2.CreateSessionResponse(
session_id=session.id, state=session.state
)
def DeleteSession(self, request, context):
logging.debug("delete session: %s", request)
@ -201,7 +230,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
for session_id in self.coreemu.sessions:
session = self.coreemu.sessions[session_id]
session_summary = core_pb2.SessionSummary(
id=session_id, state=session.state, nodes=session.get_node_count())
id=session_id, state=session.state, nodes=session.get_node_count()
)
sessions.append(session_summary)
return core_pb2.GetSessionsResponse(sessions=sessions)
@ -211,13 +241,21 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
x, y, z = session.location.refxyz
lat, lon, alt = session.location.refgeo
position = core_pb2.SessionPosition(x=x, y=y, z=z, lat=lat, lon=lon, alt=alt)
return core_pb2.GetSessionLocationResponse(position=position, scale=session.location.refscale)
return core_pb2.GetSessionLocationResponse(
position=position, scale=session.location.refscale
)
def SetSessionLocation(self, request, context):
logging.debug("set session location: %s", request)
session = self.get_session(request.session_id, context)
session.location.refxyz = (request.position.x, request.position.y, request.position.z)
session.location.setrefgeo(request.position.lat, request.position.lon, request.position.alt)
session.location.refxyz = (
request.position.x,
request.position.y,
request.position.z,
)
session.location.setrefgeo(
request.position.lat, request.position.lon, request.position.alt
)
session.location.refscale = request.scale
return core_pb2.SetSessionLocationResponse(result=True)
@ -275,7 +313,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
node_type = nodeutils.get_node_type(node.__class__).value
model = getattr(node, "type", None)
position = core_pb2.Position(x=node.position.x, y=node.position.y, z=node.position.z)
position = core_pb2.Position(
x=node.position.x, y=node.position.y, z=node.position.z
)
services = getattr(node, "services", [])
if services is None:
@ -287,8 +327,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
emane_model = node.model.name
node_proto = core_pb2.Node(
id=node.id, name=node.name, emane=emane_model, model=model,
type=node_type, position=position, services=services)
id=node.id,
name=node.name,
emane=emane_model,
model=model,
type=node_type,
position=position,
services=services,
)
if isinstance(node, (DockerNode, LxcNode)):
node_proto.image = node.image
nodes.append(node_proto)
@ -348,23 +394,38 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
services = event.services or ""
services = services.split("|")
node_proto = core_pb2.Node(
id=event.id, name=event.name, model=event.model, position=position, services=services)
id=event.id,
name=event.name,
model=event.model,
position=position,
services=services,
)
return core_pb2.NodeEvent(node=node_proto)
def _handle_link_event(self, event):
interface_one = None
if event.interface1_id is not None:
interface_one = core_pb2.Interface(
id=event.interface1_id, name=event.interface1_name, mac=convert_value(event.interface1_mac),
ip4=convert_value(event.interface1_ip4), ip4mask=event.interface1_ip4_mask,
ip6=convert_value(event.interface1_ip6), ip6mask=event.interface1_ip6_mask)
id=event.interface1_id,
name=event.interface1_name,
mac=convert_value(event.interface1_mac),
ip4=convert_value(event.interface1_ip4),
ip4mask=event.interface1_ip4_mask,
ip6=convert_value(event.interface1_ip6),
ip6mask=event.interface1_ip6_mask,
)
interface_two = None
if event.interface2_id is not None:
interface_two = core_pb2.Interface(
id=event.interface2_id, name=event.interface2_name, mac=convert_value(event.interface2_mac),
ip4=convert_value(event.interface2_ip4), ip4mask=event.interface2_ip4_mask,
ip6=convert_value(event.interface2_ip6), ip6mask=event.interface2_ip6_mask)
id=event.interface2_id,
name=event.interface2_name,
mac=convert_value(event.interface2_mac),
ip4=convert_value(event.interface2_ip4),
ip4mask=event.interface2_ip4_mask,
ip6=convert_value(event.interface2_ip6),
ip6mask=event.interface2_ip6_mask,
)
options = core_pb2.LinkOptions(
opaque=event.opaque,
@ -377,11 +438,16 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
burst=event.burst,
delay=event.delay,
dup=event.dup,
unidirectional=event.unidirectional
unidirectional=event.unidirectional,
)
link = core_pb2.Link(
type=event.link_type, node_one_id=event.node1_id, node_two_id=event.node2_id,
interface_one=interface_one, interface_two=interface_two, options=options)
type=event.link_type,
node_one_id=event.node1_id,
node_two_id=event.node2_id,
interface_one=interface_one,
interface_two=interface_two,
options=options,
)
return core_pb2.LinkEvent(message_type=event.message_type, link=link)
def _handle_session_event(self, event):
@ -394,7 +460,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
name=event.name,
data=event.data,
time=event_time,
session_id=event.session
session_id=event.session,
)
def _handle_config_event(self, event):
@ -415,7 +481,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
interface=event.interface_number,
network_id=event.network_id,
opaque=event.opaque,
data_types=event.data_types
data_types=event.data_types,
)
def _handle_exception_event(self, event):
@ -426,7 +492,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
source=event.source,
date=event.date,
text=event.text,
opaque=event.opaque
opaque=event.opaque,
)
def _handle_file_event(self, event):
@ -440,7 +506,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
source=event.source,
session_id=event.session,
data=event.data,
compressed_data=event.compressed_data
compressed_data=event.compressed_data,
)
def Throughputs(self, request, context):
@ -460,21 +526,29 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
previous_rxtx = last_stats.get(key)
if not previous_rxtx:
continue
rx_kbps = (current_rxtx["rx"] - previous_rxtx["rx"]) * 8.0 / interval
tx_kbps = (current_rxtx["tx"] - previous_rxtx["tx"]) * 8.0 / interval
rx_kbps = (
(current_rxtx["rx"] - previous_rxtx["rx"]) * 8.0 / interval
)
tx_kbps = (
(current_rxtx["tx"] - previous_rxtx["tx"]) * 8.0 / interval
)
throughput = rx_kbps + tx_kbps
if key.startswith("veth"):
key = key.split(".")
node_id = int(_INTERFACE_REGEX.search(key[0]).group())
interface_id = int(key[1])
interface_throughput = throughputs_event.interface_throughputs.add()
interface_throughput = (
throughputs_event.interface_throughputs.add()
)
interface_throughput.node_id = node_id
interface_throughput.interface_id = interface_id
interface_throughput.throughput = throughput
elif key.startswith("b."):
try:
node_id = int(key.split(".")[1])
bridge_throughput = throughputs_event.bridge_throughputs.add()
bridge_throughput = (
throughputs_event.bridge_throughputs.add()
)
bridge_throughput.node_id = node_id
bridge_throughput.throughput = throughput
except ValueError:
@ -527,8 +601,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
if interface.net:
net_id = interface.net.id
interface_proto = core_pb2.Interface(
id=interface_id, netid=net_id, name=interface.name, mac=str(interface.hwaddr),
mtu=interface.mtu, flowid=interface.flow_id)
id=interface_id,
netid=net_id,
name=interface.name,
mac=str(interface.hwaddr),
mtu=interface.mtu,
flowid=interface.flow_id,
)
interfaces.append(interface_proto)
emane_model = None
@ -536,11 +615,19 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
emane_model = node.model.name
services = [x.name for x in getattr(node, "services", [])]
position = core_pb2.Position(x=node.position.x, y=node.position.y, z=node.position.z)
position = core_pb2.Position(
x=node.position.x, y=node.position.y, z=node.position.z
)
node_type = nodeutils.get_node_type(node.__class__).value
node_proto = core_pb2.Node(
id=node.id, name=node.name, type=node_type, emane=emane_model, model=node.type, position=position,
services=services)
id=node.id,
name=node.name,
type=node_type,
emane=emane_model,
model=node.type,
position=position,
services=services,
)
if isinstance(node, (DockerNode, LxcNode)):
node_proto.image = node.image
@ -558,7 +645,11 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
lon = request.position.lon
alt = request.position.alt
node_options.set_location(lat, lon, alt)
result = session.update_node(node_id, node_options)
result = True
try:
session.update_node(node_id, node_options)
except CoreError:
result = False
return core_pb2.EditNodeResponse(result=result)
def DeleteNode(self, request, context):
@ -660,7 +751,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
link_options.key = options_data.key
link_options.opaque = options_data.opaque
session.add_link(node_one_id, node_two_id, interface_one, interface_two, link_options=link_options)
session.add_link(
node_one_id,
node_two_id,
interface_one,
interface_two,
link_options=link_options,
)
return core_pb2.AddLinkResponse(result=True)
def EditLink(self, request, context):
@ -683,7 +780,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
link_options.unidirectional = options_data.unidirectional
link_options.key = options_data.key
link_options.opaque = options_data.opaque
session.update_link(node_one_id, node_two_id, interface_one_id, interface_two_id, link_options)
session.update_link(
node_one_id, node_two_id, interface_one_id, interface_two_id, link_options
)
return core_pb2.EditLinkResponse(result=True)
def DeleteLink(self, request, context):
@ -693,7 +792,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
node_two_id = request.node_two_id
interface_one_id = request.interface_one_id
interface_two_id = request.interface_two_id
session.delete_link(node_one_id, node_two_id, interface_one_id, interface_two_id)
session.delete_link(
node_one_id, node_two_id, interface_one_id, interface_two_id
)
return core_pb2.DeleteLinkResponse(result=True)
def GetHooks(self, request, context):
@ -733,14 +834,18 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetMobilityConfig(self, request, context):
logging.debug("get mobility config: %s", request)
session = self.get_session(request.session_id, context)
config = session.mobility.get_model_config(request.node_id, Ns2ScriptedMobility.name)
config = session.mobility.get_model_config(
request.node_id, Ns2ScriptedMobility.name
)
groups = get_config_groups(config, Ns2ScriptedMobility)
return core_pb2.GetMobilityConfigResponse(groups=groups)
def SetMobilityConfig(self, request, context):
logging.debug("set mobility config: %s", request)
session = self.get_session(request.session_id, context)
session.mobility.set_model_config(request.node_id, Ns2ScriptedMobility.name, request.config)
session.mobility.set_model_config(
request.node_id, Ns2ScriptedMobility.name, request.config
)
return core_pb2.SetMobilityConfigResponse(result=True)
def MobilityAction(self, request, context):
@ -773,7 +878,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
all_service_defaults = []
for node_type in session.services.default_services:
services = session.services.default_services[node_type]
service_defaults = core_pb2.ServiceDefaults(node_type=node_type, services=services)
service_defaults = core_pb2.ServiceDefaults(
node_type=node_type, services=services
)
all_service_defaults.append(service_defaults)
return core_pb2.GetServiceDefaultsResponse(defaults=all_service_defaults)
@ -782,13 +889,17 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
session = self.get_session(request.session_id, context)
session.services.default_services.clear()
for service_defaults in request.defaults:
session.services.default_services[service_defaults.node_type] = service_defaults.services
session.services.default_services[
service_defaults.node_type
] = service_defaults.services
return core_pb2.SetServiceDefaultsResponse(result=True)
def GetNodeService(self, request, context):
logging.debug("get node service: %s", request)
session = self.get_session(request.session_id, context)
service = session.services.get_service(request.node_id, request.service, default_service=True)
service = session.services.get_service(
request.node_id, request.service, default_service=True
)
service_proto = core_pb2.NodeServiceData(
executables=service.executables,
dependencies=service.dependencies,
@ -799,7 +910,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
validation_mode=service.validation_mode.value,
validation_timer=service.validation_timer,
shutdown=service.shutdown,
meta=service.meta
meta=service.meta,
)
return core_pb2.GetNodeServiceResponse(service=service_proto)
@ -814,7 +925,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
break
if not service:
context.abort(grpc.StatusCode.NOT_FOUND, "service not found")
file_data = session.services.get_service_file(node, request.service, request.file)
file_data = session.services.get_service_file(
node, request.service, request.file
)
return core_pb2.GetNodeServiceFileResponse(data=file_data.data)
def SetNodeService(self, request, context):
@ -830,7 +943,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def SetNodeServiceFile(self, request, context):
logging.debug("set node service file: %s", request)
session = self.get_session(request.session_id, context)
session.services.set_service_file(request.node_id, request.service, request.file, request.data)
session.services.set_service_file(
request.node_id, request.service, request.file, request.data
)
return core_pb2.SetNodeServiceFileResponse(result=True)
def ServiceAction(self, request, context):
@ -867,14 +982,18 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetWlanConfig(self, request, context):
logging.debug("get wlan config: %s", request)
session = self.get_session(request.session_id, context)
config = session.mobility.get_model_config(request.node_id, BasicRangeModel.name)
config = session.mobility.get_model_config(
request.node_id, BasicRangeModel.name
)
groups = get_config_groups(config, BasicRangeModel)
return core_pb2.GetWlanConfigResponse(groups=groups)
def SetWlanConfig(self, request, context):
logging.debug("set wlan config: %s", request)
session = self.get_session(request.session_id, context)
session.mobility.set_model_config(request.node_id, BasicRangeModel.name, request.config)
session.mobility.set_model_config(
request.node_id, BasicRangeModel.name, request.config
)
if session.state == EventTypes.RUNTIME_STATE.value:
node = self.get_node(session, request.node_id, context)
node.updatemodel(request.config)
@ -970,7 +1089,11 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetInterfaces(self, request, context):
interfaces = []
for interface in os.listdir("/sys/class/net"):
if interface.startswith("b.") or interface.startswith("veth") or interface == "lo":
if (
interface.startswith("b.")
or interface.startswith("veth")
or interface == "lo"
):
continue
interfaces.append(interface)
return core_pb2.GetInterfacesResponse(interfaces=interfaces)

View file

@ -12,23 +12,25 @@ import threading
from core import utils
from core.api.tlv import coreapi
from core.nodes.base import CoreNodeBase, CoreNetworkBase
from core.emulator.enumerations import ConfigDataTypes
from core.emulator.enumerations import ConfigFlags
from core.emulator.enumerations import ConfigTlvs
from core.emulator.enumerations import EventTlvs
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import FileTlvs
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import NodeTlvs
from core.emulator.enumerations import NodeTypes
from core.emulator.enumerations import RegisterTlvs
from core.emulator.enumerations import (
ConfigDataTypes,
ConfigFlags,
ConfigTlvs,
EventTlvs,
EventTypes,
ExecuteTlvs,
FileTlvs,
LinkTlvs,
MessageFlags,
MessageTypes,
NodeTlvs,
NodeTypes,
RegisterTlvs,
)
from core.nodes import nodeutils
from core.nodes.ipaddress import IpAddress
from core.nodes.base import CoreNetworkBase, CoreNodeBase
from core.nodes.interface import GreTap
from core.nodes.ipaddress import IpAddress
from core.nodes.network import GreTapBridge
from core.nodes.physical import PhysicalNode
@ -147,7 +149,12 @@ class CoreBroker(object):
while len(self.servers) > 0:
name, server = self.servers.popitem()
if server.sock is not None:
logging.info("closing connection with %s: %s:%s", name, server.host, server.port)
logging.info(
"closing connection with %s: %s:%s",
name,
server.host,
server.port,
)
server.close()
self.dorecvloop = False
if self.recvthread is not None:
@ -157,7 +164,7 @@ class CoreBroker(object):
"""
Reset to initial state.
"""
logging.info("clearing state")
logging.debug("broker reset")
self.nodemap_lock.acquire()
self.nodemap.clear()
for server in self.nodecounts:
@ -208,14 +215,22 @@ class CoreBroker(object):
r, _w, _x = select.select(rlist, [], [], 1.0)
for sock in r:
server = self.getserverbysock(sock)
logging.info("attempting to receive from server: peer:%s remote:%s",
server.sock.getpeername(), server.sock.getsockname())
logging.info(
"attempting to receive from server: peer:%s remote:%s",
server.sock.getpeername(),
server.sock.getsockname(),
)
if server is None:
# servers may have changed; loop again
continue
rcvlen = self.recv(server)
if rcvlen == 0:
logging.info("connection with server(%s) closed: %s:%s", server.name, server.host, server.port)
logging.info(
"connection with server(%s) closed: %s:%s",
server.name,
server.host,
server.port,
)
def recv(self, server):
"""
@ -236,7 +251,9 @@ class CoreBroker(object):
return 0
if len(msghdr) != coreapi.CoreMessage.header_len:
logging.warning("warning: broker received not enough data len=%s", len(msghdr))
logging.warning(
"warning: broker received not enough data len=%s", len(msghdr)
)
return len(msghdr)
msgtype, msgflags, msglen = coreapi.CoreMessage.unpack_header(msghdr)
@ -293,11 +310,17 @@ class CoreBroker(object):
with self.servers_lock:
server = self.servers.get(name)
if server is not None:
if host == server.host and port == server.port and server.sock is not None:
if (
host == server.host
and port == server.port
and server.sock is not None
):
# leave this socket connected
return
logging.info("closing connection with %s @ %s:%s", name, server.host, server.port)
logging.info(
"closing connection with %s @ %s:%s", name, server.host, server.port
)
server.close()
del self.servers[name]
@ -307,7 +330,9 @@ class CoreBroker(object):
try:
server.connect()
except IOError:
logging.exception("error connecting to server(%s): %s:%s", name, host, port)
logging.exception(
"error connecting to server(%s): %s:%s", name, host, port
)
if server.sock is not None:
self.startrecvloop()
self.servers[name] = server
@ -328,7 +353,12 @@ class CoreBroker(object):
logging.exception("error deleting server")
if server.sock is not None:
logging.info("closing connection with %s @ %s:%s", server.name, server.host, server.port)
logging.info(
"closing connection with %s @ %s:%s",
server.name,
server.host,
server.port,
)
server.close()
def getserverbyname(self, name):
@ -414,16 +444,31 @@ class CoreBroker(object):
remotenum = n2num
if key in self.tunnels.keys():
logging.warning("tunnel with key %s (%s-%s) already exists!", key, n1num, n2num)
logging.warning(
"tunnel with key %s (%s-%s) already exists!", key, n1num, n2num
)
else:
_id = key & ((1 << 16) - 1)
logging.info("adding tunnel for %s-%s to %s with key %s", n1num, n2num, remoteip, key)
logging.info(
"adding tunnel for %s-%s to %s with key %s", n1num, n2num, remoteip, key
)
if localnum in self.physical_nodes:
# no bridge is needed on physical nodes; use the GreTap directly
gt = GreTap(node=None, name=None, session=self.session,
remoteip=remoteip, key=key)
gt = GreTap(
node=None,
name=None,
session=self.session,
remoteip=remoteip,
key=key,
)
else:
gt = self.session.create_node(cls=GreTapBridge, _id=_id, policy="ACCEPT", remoteip=remoteip, key=key)
gt = self.session.create_node(
cls=GreTapBridge,
_id=_id,
policy="ACCEPT",
remoteip=remoteip,
key=key,
)
gt.localnum = localnum
gt.remotenum = remotenum
self.tunnels[key] = gt
@ -457,8 +502,13 @@ class CoreBroker(object):
return None
server_interface = getattr(net, "serverintf", None)
if nodeutils.is_node(net, NodeTypes.CONTROL_NET) and server_interface is not None:
logging.warning("control networks with server interfaces do not need a tunnel")
if (
nodeutils.is_node(net, NodeTypes.CONTROL_NET)
and server_interface is not None
):
logging.warning(
"control networks with server interfaces do not need a tunnel"
)
return None
servers = self.getserversbynode(node_id)
@ -491,12 +541,18 @@ class CoreBroker(object):
myip = host
key = self.tunnelkey(node_id, IpAddress.to_int(myip))
if key in self.tunnels.keys():
logging.info("tunnel already exists, returning existing tunnel: %s", key)
logging.info(
"tunnel already exists, returning existing tunnel: %s", key
)
gt = self.tunnels[key]
r.append(gt)
continue
logging.info("adding tunnel for net %s to %s with key %s", node_id, host, key)
gt = GreTap(node=None, name=None, session=self.session, remoteip=host, key=key)
logging.info(
"adding tunnel for net %s to %s with key %s", node_id, host, key
)
gt = GreTap(
node=None, name=None, session=self.session, remoteip=host, key=key
)
self.tunnels[key] = gt
r.append(gt)
# attaching to net will later allow gt to be destroyed
@ -515,7 +571,9 @@ class CoreBroker(object):
"""
key = self.tunnelkey(n1num, n2num)
try:
logging.info("deleting tunnel between %s - %s with key: %s", n1num, n2num, key)
logging.info(
"deleting tunnel between %s - %s with key: %s", n1num, n2num, key
)
gt = self.tunnels.pop(key)
except KeyError:
gt = None
@ -643,12 +701,19 @@ class CoreBroker(object):
elif message.message_type == MessageTypes.CONFIG.value:
# broadcast location and services configuration everywhere
confobj = message.get_tlv(ConfigTlvs.OBJECT.value)
if confobj == "location" or confobj == "services" or confobj == "session" or confobj == "all":
if (
confobj == "location"
or confobj == "services"
or confobj == "session"
or confobj == "all"
):
servers = self.getservers()
elif message.message_type == MessageTypes.FILE.value:
# broadcast hook scripts and custom service files everywhere
filetype = message.get_tlv(FileTlvs.TYPE.value)
if filetype is not None and (filetype[:5] == "hook:" or filetype[:8] == "service:"):
if filetype is not None and (
filetype[:5] == "hook:" or filetype[:8] == "service:"
):
servers = self.getservers()
if message.message_type == MessageTypes.LINK.value:
# prepare a server list from two node numbers in link message
@ -695,11 +760,19 @@ class CoreBroker(object):
# server of its local name
tlvdata = b""
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.OBJECT.value, "broker")
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.TYPE.value, ConfigFlags.UPDATE.value)
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.DATA_TYPES.value, (ConfigDataTypes.STRING.value,))
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.VALUES.value,
"%s:%s:%s" % (server.name, server.host, server.port))
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.SESSION.value, "%s" % self.session.id)
tlvdata += coreapi.CoreConfigTlv.pack(
ConfigTlvs.TYPE.value, ConfigFlags.UPDATE.value
)
tlvdata += coreapi.CoreConfigTlv.pack(
ConfigTlvs.DATA_TYPES.value, (ConfigDataTypes.STRING.value,)
)
tlvdata += coreapi.CoreConfigTlv.pack(
ConfigTlvs.VALUES.value,
"%s:%s:%s" % (server.name, server.host, server.port),
)
tlvdata += coreapi.CoreConfigTlv.pack(
ConfigTlvs.SESSION.value, "%s" % self.session.id
)
msg = coreapi.CoreConfMessage.pack(0, tlvdata)
server.sock.send(msg)
@ -760,7 +833,10 @@ class CoreBroker(object):
if nodecls is None:
logging.warning("broker unimplemented node type %s", nodetype)
return handle_locally, servers
if issubclass(nodecls, CoreNetworkBase) and nodetype != NodeTypes.WIRELESS_LAN.value:
if (
issubclass(nodecls, CoreNetworkBase)
and nodetype != NodeTypes.WIRELESS_LAN.value
):
# network node replicated on all servers; could be optimized
# don"t replicate WLANs, because ebtables rules won"t work
servers = self.getservers()
@ -810,7 +886,9 @@ class CoreBroker(object):
# determine link message destination using non-network nodes
nn = message.node_numbers()
logging.debug("checking link nodes (%s) with network nodes (%s)", nn, self.network_nodes)
logging.debug(
"checking link nodes (%s) with network nodes (%s)", nn, self.network_nodes
)
if nn[0] in self.network_nodes:
if nn[1] in self.network_nodes:
# two network nodes linked together - prevent loops caused by
@ -854,7 +932,9 @@ class CoreBroker(object):
if host is None:
host = self.getlinkendpoint(message, localn == nn[0])
logging.debug("handle locally(%s) and local node(%s)", handle_locally, localn)
logging.debug(
"handle locally(%s) and local node(%s)", handle_locally, localn
)
if localn is None:
message = self.addlinkendpoints(message, servers1, servers2)
elif message.flags & MessageFlags.ADD.value:
@ -889,10 +969,10 @@ class CoreBroker(object):
if server.host is not None:
ip2 = server.host
break
tlvdata = message.raw_message[coreapi.CoreMessage.header_len:]
tlvdata = message.raw_message[coreapi.CoreMessage.header_len :]
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.OPAQUE.value, "%s:%s" % (ip1, ip2))
newraw = coreapi.CoreLinkMessage.pack(message.flags, tlvdata)
msghdr = newraw[:coreapi.CoreMessage.header_len]
msghdr = newraw[: coreapi.CoreMessage.header_len]
return coreapi.CoreLinkMessage(message.flags, msghdr, tlvdata)
def getlinkendpoint(self, msg, first_is_local):
@ -934,10 +1014,12 @@ class CoreBroker(object):
:return: should handle locally or not
:rtype: bool
"""
hdr = msg[:coreapi.CoreMessage.header_len]
hdr = msg[: coreapi.CoreMessage.header_len]
msgtype, flags, _msglen = coreapi.CoreMessage.unpack_header(hdr)
msgcls = coreapi.CLASS_MAP[msgtype]
return self.handle_message(msgcls(flags, hdr, msg[coreapi.CoreMessage.header_len:]))
return self.handle_message(
msgcls(flags, hdr, msg[coreapi.CoreMessage.header_len :])
)
def forwardmsg(self, message, servers):
"""
@ -957,9 +1039,19 @@ class CoreBroker(object):
# local emulation server, handle this locally
handle_locally = True
elif server.sock is None:
logging.info("server %s @ %s:%s is disconnected", server.name, server.host, server.port)
logging.info(
"server %s @ %s:%s is disconnected",
server.name,
server.host,
server.port,
)
else:
logging.info("forwarding message to server(%s): %s:%s", server.name, server.host, server.port)
logging.info(
"forwarding message to server(%s): %s:%s",
server.name,
server.host,
server.port,
)
logging.debug("message being forwarded:\n%s", message)
server.sock.send(message.raw_message)
return handle_locally
@ -986,7 +1078,10 @@ class CoreBroker(object):
lhost, lport = None, None
if server.sock:
lhost, lport = server.sock.getsockname()
f.write("%s %s %s %s %s\n" % (server.name, server.host, server.port, lhost, lport))
f.write(
"%s %s %s %s %s\n"
% (server.name, server.host, server.port, lhost, lport)
)
except IOError:
logging.exception("error writing server list to the file: %s", filename)
@ -1015,7 +1110,9 @@ class CoreBroker(object):
with open(filename, "w") as f:
f.write("%s\n%s\n" % (serverstr, nodestr))
except IOError:
logging.exception("error writing server file %s for node %s", filename, name)
logging.exception(
"error writing server file %s for node %s", filename, name
)
def local_instantiation_complete(self):
"""
@ -1031,7 +1128,9 @@ class CoreBroker(object):
# broadcast out instantiate complete
tlvdata = b""
tlvdata += coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.INSTANTIATION_COMPLETE.value)
tlvdata += coreapi.CoreEventTlv.pack(
EventTlvs.TYPE.value, EventTypes.INSTANTIATION_COMPLETE.value
)
message = coreapi.CoreEventMessage.pack(0, tlvdata)
for session_client in self.session_clients:
session_client.sendall(message)

View file

@ -7,26 +7,27 @@ CORE API messaging is leveraged for communication with the GUI.
import socket
import struct
from past.builtins import basestring
from enum import Enum
from past.builtins import basestring
from core.api.tlv import structutils
from core.emulator.enumerations import ConfigTlvs
from core.emulator.enumerations import EventTlvs
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExceptionTlvs
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import FileTlvs
from core.emulator.enumerations import InterfaceTlvs
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import NodeTlvs
from core.emulator.enumerations import RegisterTlvs
from core.emulator.enumerations import SessionTlvs
from core.nodes.ipaddress import IpAddress
from core.nodes.ipaddress import MacAddress
from core.emulator.enumerations import (
ConfigTlvs,
EventTlvs,
EventTypes,
ExceptionTlvs,
ExecuteTlvs,
FileTlvs,
InterfaceTlvs,
LinkTlvs,
MessageFlags,
MessageTypes,
NodeTlvs,
RegisterTlvs,
SessionTlvs,
)
from core.nodes.ipaddress import IpAddress, MacAddress
class CoreTlvData(object):
@ -139,6 +140,7 @@ class CoreTlvDataUint16(CoreTlvData):
"""
Helper class for packing uint16 data.
"""
data_format = "!H"
data_type = int
pad_len = 0
@ -148,6 +150,7 @@ class CoreTlvDataUint32(CoreTlvData):
"""
Helper class for packing uint32 data.
"""
data_format = "!2xI"
data_type = int
pad_len = 2
@ -157,6 +160,7 @@ class CoreTlvDataUint64(CoreTlvData):
"""
Helper class for packing uint64 data.
"""
data_format = "!2xQ"
data_type = int
pad_len = 2
@ -166,6 +170,7 @@ class CoreTlvDataString(CoreTlvData):
"""
Helper class for packing string data.
"""
data_type = str
@classmethod
@ -204,6 +209,7 @@ class CoreTlvDataUint16List(CoreTlvData):
"""
List of unsigned 16-bit values.
"""
data_type = tuple
data_format = "!H"
@ -253,6 +259,7 @@ class CoreTlvDataIpv4Addr(CoreTlvDataObj):
"""
Utility class for packing/unpacking Ipv4 addresses.
"""
data_type = IpAddress.from_string
data_format = "!2x4s"
pad_len = 2
@ -283,6 +290,7 @@ class CoreTlvDataIPv6Addr(CoreTlvDataObj):
"""
Utility class for packing/unpacking Ipv6 addresses.
"""
data_format = "!16s2x"
data_type = IpAddress.from_string
pad_len = 2
@ -313,6 +321,7 @@ class CoreTlvDataMacAddr(CoreTlvDataObj):
"""
Utility class for packing/unpacking mac addresses.
"""
data_format = "!2x8s"
data_type = MacAddress.from_string
pad_len = 2
@ -345,6 +354,7 @@ class CoreTlv(object):
"""
Base class for representing CORE TLVs.
"""
header_format = "!BB"
header_len = struct.calcsize(header_format)
@ -379,10 +389,12 @@ class CoreTlv(object):
:param data: data to unpack
:return: unpacked data class
"""
tlv_type, tlv_len = struct.unpack(cls.header_format, data[:cls.header_len])
tlv_type, tlv_len = struct.unpack(cls.header_format, data[: cls.header_len])
header_len = cls.header_len
if tlv_len == 0:
tlv_type, _zero, tlv_len = struct.unpack(cls.long_header_format, data[:cls.long_header_len])
tlv_type, _zero, tlv_len = struct.unpack(
cls.long_header_format, data[: cls.long_header_len]
)
header_len = cls.long_header_len
tlv_size = header_len + tlv_len
# for 32-bit alignment
@ -435,7 +447,11 @@ class CoreTlv(object):
:return: string representation
:rtype: str
"""
return "%s <tlvtype = %s, value = %s>" % (self.__class__.__name__, self.type_str(), self.value)
return "%s <tlvtype = %s, value = %s>" % (
self.__class__.__name__,
self.type_str(),
self.value,
)
class CoreNodeTlv(CoreTlv):
@ -686,14 +702,16 @@ class CoreMessage(object):
:return: unpacked tuple
:rtype: tuple
"""
message_type, message_flags, message_len = struct.unpack(cls.header_format, data[:cls.header_len])
message_type, message_flags, message_len = struct.unpack(
cls.header_format, data[: cls.header_len]
)
return message_type, message_flags, message_len
@classmethod
def create(cls, flags, values):
tlv_data = structutils.pack_values(cls.tlv_class, values)
packed = cls.pack(flags, tlv_data)
header_data = packed[:cls.header_len]
header_data = packed[: cls.header_len]
return cls(flags, header_data, tlv_data)
@classmethod
@ -705,7 +723,9 @@ class CoreMessage(object):
:param tlv_data: data to get length from for packing
:return: combined header and tlv data
"""
header = struct.pack(cls.header_format, cls.message_type, message_flags, len(tlv_data))
header = struct.pack(
cls.header_format, cls.message_type, message_flags, len(tlv_data)
)
return header + tlv_data
def add_tlv_data(self, key, value):
@ -807,7 +827,11 @@ class CoreMessage(object):
:return: string representation
:rtype: str
"""
result = "%s <msgtype = %s, flags = %s>" % (self.__class__.__name__, self.type_str(), self.flag_str())
result = "%s <msgtype = %s, flags = %s>" % (
self.__class__.__name__,
self.type_str(),
self.flag_str(),
)
for key in self.tlv_data:
value = self.tlv_data[key]
@ -879,6 +903,7 @@ class CoreNodeMessage(CoreMessage):
"""
CORE node message class.
"""
message_type = MessageTypes.NODE.value
tlv_class = CoreNodeTlv
@ -887,6 +912,7 @@ class CoreLinkMessage(CoreMessage):
"""
CORE link message class.
"""
message_type = MessageTypes.LINK.value
tlv_class = CoreLinkTlv
@ -895,6 +921,7 @@ class CoreExecMessage(CoreMessage):
"""
CORE execute message class.
"""
message_type = MessageTypes.EXECUTE.value
tlv_class = CoreExecuteTlv
@ -903,6 +930,7 @@ class CoreRegMessage(CoreMessage):
"""
CORE register message class.
"""
message_type = MessageTypes.REGISTER.value
tlv_class = CoreRegisterTlv
@ -911,6 +939,7 @@ class CoreConfMessage(CoreMessage):
"""
CORE configuration message class.
"""
message_type = MessageTypes.CONFIG.value
tlv_class = CoreConfigTlv
@ -919,6 +948,7 @@ class CoreFileMessage(CoreMessage):
"""
CORE file message class.
"""
message_type = MessageTypes.FILE.value
tlv_class = CoreFileTlv
@ -927,6 +957,7 @@ class CoreIfaceMessage(CoreMessage):
"""
CORE interface message class.
"""
message_type = MessageTypes.INTERFACE.value
tlv_class = CoreInterfaceTlv
@ -935,6 +966,7 @@ class CoreEventMessage(CoreMessage):
"""
CORE event message class.
"""
message_type = MessageTypes.EVENT.value
tlv_class = CoreEventTlv
@ -943,6 +975,7 @@ class CoreSessionMessage(CoreMessage):
"""
CORE session message class.
"""
message_type = MessageTypes.SESSION.value
tlv_class = CoreSessionTlv
@ -951,6 +984,7 @@ class CoreExceptionMessage(CoreMessage):
"""
CORE exception message class.
"""
message_type = MessageTypes.EXCEPTION.value
tlv_class = CoreExceptionTlv

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,7 @@ class CoreServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
TCP server class, manages sessions and spawns request handlers for
incoming connections.
"""
daemon_threads = True
allow_reuse_address = True
@ -34,6 +35,7 @@ class CoreUdpServer(socketserver.ThreadingMixIn, socketserver.UDPServer):
UDP server class, manages sessions and spawns request handlers for
incoming connections.
"""
daemon_threads = True
allow_reuse_address = True

View file

@ -3,8 +3,7 @@ Converts CORE data objects into legacy API messages.
"""
from core.api.tlv import coreapi, structutils
from core.emulator.enumerations import ConfigTlvs
from core.emulator.enumerations import NodeTlvs
from core.emulator.enumerations import ConfigTlvs, NodeTlvs
def convert_node(node_data):
@ -14,28 +13,31 @@ def convert_node(node_data):
:param core.emulator.data.NodeData node_data: node data to convert
:return: packed node message
"""
tlv_data = structutils.pack_values(coreapi.CoreNodeTlv, [
(NodeTlvs.NUMBER, node_data.id),
(NodeTlvs.TYPE, node_data.node_type),
(NodeTlvs.NAME, node_data.name),
(NodeTlvs.IP_ADDRESS, node_data.ip_address),
(NodeTlvs.MAC_ADDRESS, node_data.mac_address),
(NodeTlvs.IP6_ADDRESS, node_data.ip6_address),
(NodeTlvs.MODEL, node_data.model),
(NodeTlvs.EMULATION_ID, node_data.emulation_id),
(NodeTlvs.EMULATION_SERVER, node_data.emulation_server),
(NodeTlvs.SESSION, node_data.session),
(NodeTlvs.X_POSITION, node_data.x_position),
(NodeTlvs.Y_POSITION, node_data.y_position),
(NodeTlvs.CANVAS, node_data.canvas),
(NodeTlvs.NETWORK_ID, node_data.network_id),
(NodeTlvs.SERVICES, node_data.services),
(NodeTlvs.LATITUDE, node_data.latitude),
(NodeTlvs.LONGITUDE, node_data.longitude),
(NodeTlvs.ALTITUDE, node_data.altitude),
(NodeTlvs.ICON, node_data.icon),
(NodeTlvs.OPAQUE, node_data.opaque)
])
tlv_data = structutils.pack_values(
coreapi.CoreNodeTlv,
[
(NodeTlvs.NUMBER, node_data.id),
(NodeTlvs.TYPE, node_data.node_type),
(NodeTlvs.NAME, node_data.name),
(NodeTlvs.IP_ADDRESS, node_data.ip_address),
(NodeTlvs.MAC_ADDRESS, node_data.mac_address),
(NodeTlvs.IP6_ADDRESS, node_data.ip6_address),
(NodeTlvs.MODEL, node_data.model),
(NodeTlvs.EMULATION_ID, node_data.emulation_id),
(NodeTlvs.EMULATION_SERVER, node_data.emulation_server),
(NodeTlvs.SESSION, node_data.session),
(NodeTlvs.X_POSITION, node_data.x_position),
(NodeTlvs.Y_POSITION, node_data.y_position),
(NodeTlvs.CANVAS, node_data.canvas),
(NodeTlvs.NETWORK_ID, node_data.network_id),
(NodeTlvs.SERVICES, node_data.services),
(NodeTlvs.LATITUDE, node_data.latitude),
(NodeTlvs.LONGITUDE, node_data.longitude),
(NodeTlvs.ALTITUDE, node_data.altitude),
(NodeTlvs.ICON, node_data.icon),
(NodeTlvs.OPAQUE, node_data.opaque),
],
)
return coreapi.CoreNodeMessage.pack(node_data.message_type, tlv_data)
@ -46,19 +48,22 @@ def convert_config(config_data):
:param core.emulator.data.ConfigData config_data: config data to convert
:return: packed message
"""
tlv_data = structutils.pack_values(coreapi.CoreConfigTlv, [
(ConfigTlvs.NODE, config_data.node),
(ConfigTlvs.OBJECT, config_data.object),
(ConfigTlvs.TYPE, config_data.type),
(ConfigTlvs.DATA_TYPES, config_data.data_types),
(ConfigTlvs.VALUES, config_data.data_values),
(ConfigTlvs.CAPTIONS, config_data.captions),
(ConfigTlvs.BITMAP, config_data.bitmap),
(ConfigTlvs.POSSIBLE_VALUES, config_data.possible_values),
(ConfigTlvs.GROUPS, config_data.groups),
(ConfigTlvs.SESSION, config_data.session),
(ConfigTlvs.INTERFACE_NUMBER, config_data.interface_number),
(ConfigTlvs.NETWORK_ID, config_data.network_id),
(ConfigTlvs.OPAQUE, config_data.opaque),
])
tlv_data = structutils.pack_values(
coreapi.CoreConfigTlv,
[
(ConfigTlvs.NODE, config_data.node),
(ConfigTlvs.OBJECT, config_data.object),
(ConfigTlvs.TYPE, config_data.type),
(ConfigTlvs.DATA_TYPES, config_data.data_types),
(ConfigTlvs.VALUES, config_data.data_values),
(ConfigTlvs.CAPTIONS, config_data.captions),
(ConfigTlvs.BITMAP, config_data.bitmap),
(ConfigTlvs.POSSIBLE_VALUES, config_data.possible_values),
(ConfigTlvs.GROUPS, config_data.groups),
(ConfigTlvs.SESSION, config_data.session),
(ConfigTlvs.INTERFACE_NUMBER, config_data.interface_number),
(ConfigTlvs.NETWORK_ID, config_data.network_id),
(ConfigTlvs.OPAQUE, config_data.opaque),
],
)
return coreapi.CoreConfMessage.pack(config_data.message_type, tlv_data)

View file

@ -3,6 +3,7 @@ Utilities for working with python struct data.
"""
import logging
from past.builtins import basestring