merged latest from develop

This commit is contained in:
Blake Harnden 2019-06-03 13:06:11 -07:00
commit 7efec88e79
178 changed files with 11969 additions and 692 deletions

View file

@ -149,27 +149,27 @@ class CoreGrpcClient(object):
self.stub = None
self.channel = None
def create_session(self, _id=None):
def create_session(self, session_id=None):
"""
Create a session.
:param int _id: id for session, default is None and one will be created for you
:param int session_id: id for session, default is None and one will be created for you
:return: response with created session id
:rtype: core_pb2.CreateSessionResponse
"""
request = core_pb2.CreateSessionRequest(id=_id)
request = core_pb2.CreateSessionRequest(session_id=session_id)
return self.stub.CreateSession(request)
def delete_session(self, _id):
def delete_session(self, session_id):
"""
Delete a session.
:param int _id: id of session
:param int session_id: id of session
:return: response with result of deletion success or failure
:rtype: core_pb2.DeleteSessionResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.DeleteSessionRequest(id=_id)
request = core_pb2.DeleteSessionRequest(session_id=session_id)
return self.stub.DeleteSession(request)
def get_sessions(self):
@ -181,60 +181,60 @@ class CoreGrpcClient(object):
"""
return self.stub.GetSessions(core_pb2.GetSessionsRequest())
def get_session(self, _id):
def get_session(self, session_id):
"""
Retrieve a session.
:param int _id: id of session
:param int session_id: id of session
:return: response with sessions state, nodes, and links
:rtype: core_pb2.GetSessionResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetSessionRequest(id=_id)
request = core_pb2.GetSessionRequest(session_id=session_id)
return self.stub.GetSession(request)
def get_session_options(self, _id):
def get_session_options(self, session_id):
"""
Retrieve session options.
:param int _id: id of session
:param int session_id: id of session
:return: response with a list of configuration groups
:rtype: core_pb2.GetSessionOptionsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetSessionOptionsRequest(id=_id)
request = core_pb2.GetSessionOptionsRequest(session_id=session_id)
return self.stub.GetSessionOptions(request)
def set_session_options(self, _id, config):
def set_session_options(self, session_id, config):
"""
Set options for a session.
:param int _id: id of session
:param int session_id: id of session
:param dict[str, str] config: configuration values to set
:return: response with result of success or failure
:rtype: core_pb2.SetSessionOptionsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetSessionOptionsRequest(id=_id, config=config)
request = core_pb2.SetSessionOptionsRequest(session_id=session_id, config=config)
return self.stub.SetSessionOptions(request)
def get_session_location(self, _id):
def get_session_location(self, session_id):
"""
Get session location.
:param int _id: id of session
:param int session_id: id of session
:return: response with session position reference and scale
:rtype: core_pb2.GetSessionLocationResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetSessionLocationRequest(id=_id)
request = core_pb2.GetSessionLocationRequest(session_id=session_id)
return self.stub.GetSessionLocation(request)
def set_session_location(self, _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.
:param int _id: id of session
:param int session_id: id of session
:param float x: x position
:param float y: y position
:param float z: z position
@ -247,173 +247,145 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session doesn't exist
"""
position = core_pb2.Position(x=x, y=y, z=z, lat=lat, lon=lon, alt=alt)
request = core_pb2.SetSessionLocationRequest(id=_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, _id, state):
def set_session_state(self, session_id, state):
"""
Set session state.
:param int _id: id of session
:param int session_id: id of session
:param core_pb2.SessionState state: session state to transition to
:return: response with result of success or failure
:rtype: core_pb2.SetSessionStateResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetSessionStateRequest(id=_id, state=state)
request = core_pb2.SetSessionStateRequest(session_id=session_id, state=state)
return self.stub.SetSessionState(request)
def node_events(self, _id, handler):
"""
Listen for session node events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.NodeEventsRequest(id=_id)
stream = self.stub.NodeEvents(request)
start_streamer(stream, handler)
def link_events(self, _id, handler):
"""
Listen for session link events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.LinkEventsRequest(id=_id)
stream = self.stub.LinkEvents(request)
start_streamer(stream, handler)
def session_events(self, _id, handler):
def events(self, session_id, handler):
"""
Listen for session events.
:param int _id: id of session
:param int session_id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SessionEventsRequest(id=_id)
stream = self.stub.SessionEvents(request)
request = core_pb2.EventsRequest(session_id=session_id)
stream = self.stub.Events(request)
start_streamer(stream, handler)
def config_events(self, _id, handler):
def throughputs(self, handler):
"""
Listen for session config events.
Listen for throughput events with information for interfaces and bridges.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.ConfigEventsRequest(id=_id)
stream = self.stub.ConfigEvents(request)
request = core_pb2.ThroughputsRequest()
stream = self.stub.Throughputs(request)
start_streamer(stream, handler)
def exception_events(self, _id, handler):
"""
Listen for session exception events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.ExceptionEventsRequest(id=_id)
stream = self.stub.ExceptionEvents(request)
start_streamer(stream, handler)
def file_events(self, _id, handler):
"""
Listen for session file events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.FileEventsRequest(id=_id)
stream = self.stub.FileEvents(request)
start_streamer(stream, handler)
def add_node(self, session, node):
def add_node(self, session_id, node):
"""
Add node to session.
:param int session: session id
:param int session_id: session id
:param core_pb2.Node node: node to add
:return: response with node id
:rtype: core_pb2.AddNodeResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.AddNodeRequest(session=session, node=node)
request = core_pb2.AddNodeRequest(session_id=session_id, node=node)
return self.stub.AddNode(request)
def get_node(self, session, _id):
def get_node(self, session_id, node_id):
"""
Get node details.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:return: response with node details
:rtype: core_pb2.GetNodeResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeRequest(session=session, id=_id)
request = core_pb2.GetNodeRequest(session_id=session_id, node_id=node_id)
return self.stub.GetNode(request)
def edit_node(self, session, _id, position):
def edit_node(self, session_id, node_id, position):
"""
Edit a node, currently only changes position.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param core_pb2.Position position: position to set node to
:return: response with result of success or failure
:rtype: core_pb2.EditNodeResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.EditNodeRequest(session=session, id=_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):
def delete_node(self, session_id, node_id):
"""
Delete node from session.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:return: response with result of success or failure
:rtype: core_pb2.DeleteNodeResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.DeleteNodeRequest(session=session, id=_id)
request = core_pb2.DeleteNodeRequest(session_id=session_id, node_id=node_id)
return self.stub.DeleteNode(request)
def get_node_links(self, session, _id):
def node_command(self, session_id, node_id, command):
"""
Send command to a node and get the output.
:param int session_id: session id
:param int node_id: node id
:return: response with command combined stdout/stderr
: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)
return self.stub.NodeCommand(request)
def get_node_terminal(self, session_id, node_id):
"""
Retrieve terminal command string for launching a local terminal.
:param int session_id: session id
:param int node_id: node id
:return: response with a node terminal command
: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)
return self.stub.GetNodeTerminal(request)
def get_node_links(self, session_id, node_id):
"""
Get current links for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:return: response with a list of links
:rtype: core_pb2.GetNodeLinksResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeLinksRequest(session=session, id=_id)
request = core_pb2.GetNodeLinksRequest(session_id=session_id, node_id=node_id)
return self.stub.GetNodeLinks(request)
def add_link(self, session, node_one, node_two, 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.
:param int session: session id
:param int node_one: node one id
:param int node_two: node two id
:param int session_id: session id
:param int node_one_id: node one id
:param int node_two_id: node two id
:param core_pb2.Interface interface_one: node one interface data
:param core_pb2.Interface interface_two: node two interface data
:param core_pb2.LinkOptions options: options for link (jitter, bandwidth, etc)
@ -422,65 +394,65 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session or one of the nodes don't exist
"""
link = core_pb2.Link(
node_one=node_one, node_two=node_two, type=core_pb2.LINK_WIRED,
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=session, link=link)
request = core_pb2.AddLinkRequest(session_id=session_id, link=link)
return self.stub.AddLink(request)
def edit_link(self, session, node_one, node_two, options, interface_one=None, interface_two=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.
:param int session: session id
:param int node_one: node one id
:param int node_two: node two id
:param int session_id: session id
:param int node_one_id: node one id
:param int node_two_id: node two id
:param core_pb2.LinkOptions options: options for link (jitter, bandwidth, etc)
:param int interface_one: node one interface id
:param int interface_two: node two interface id
:param int interface_one_id: node one interface id
:param int interface_two_id: node two interface id
:return: response with result of success or failure
:rtype: core_pb2.EditLinkResponse
:raises grpc.RpcError: when session or one of the nodes don't exist
"""
request = core_pb2.EditLinkRequest(
session=session, node_one=node_one, node_two=node_two, options=options,
interface_one=interface_one, interface_two=interface_two)
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, node_one, node_two, interface_one=None, interface_two=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.
:param int session: session id
:param int node_one: node one id
:param int node_two: node two id
:param int interface_one: node one interface id
:param int interface_two: node two interface id
:param int session_id: session id
:param int node_one_id: node one id
:param int node_two_id: node two id
:param int interface_one_id: node one interface id
:param int interface_two_id: node two interface id
:return: response with result of success or failure
:rtype: core_pb2.DeleteLinkResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.DeleteLinkRequest(
session=session, node_one=node_one, node_two=node_two,
interface_one=interface_one, interface_two=interface_two)
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):
def get_hooks(self, session_id):
"""
Get all hook scripts.
:param int session: session id
:param int session_id: session id
:return: response with a list of hooks
:rtype: core_pb2.GetHooksResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetHooksRequest(session=session)
request = core_pb2.GetHooksRequest(session_id=session_id)
return self.stub.GetHooks(request)
def add_hook(self, session, state, file_name, file_data):
def add_hook(self, session_id, state, file_name, file_data):
"""
Add hook scripts.
:param int session: session id
:param int session_id: session id
:param core_pb2.SessionState state: state to trigger hook
:param str file_name: name of file for hook script
:param bytes file_data: hook script contents
@ -489,60 +461,60 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session doesn't exist
"""
hook = core_pb2.Hook(state=state, file=file_name, data=file_data)
request = core_pb2.AddHookRequest(session=session, hook=hook)
request = core_pb2.AddHookRequest(session_id=session_id, hook=hook)
return self.stub.AddHook(request)
def get_mobility_configs(self, session):
def get_mobility_configs(self, session_id):
"""
Get all mobility configurations.
:param int session: session id
:param int session_id: session id
:return: response with a dict of node ids to mobility configurations
:rtype: core_pb2.GetMobilityConfigsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetMobilityConfigsRequest(session=session)
request = core_pb2.GetMobilityConfigsRequest(session_id=session_id)
return self.stub.GetMobilityConfigs(request)
def get_mobility_config(self, session, _id):
def get_mobility_config(self, session_id, node_id):
"""
Get mobility configuration for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:return: response with a list of configuration groups
:rtype: core_pb2.GetMobilityConfigResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetMobilityConfigRequest(session=session, id=_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, config):
def set_mobility_config(self, session_id, node_id, config):
"""
Set mobility configuration for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param dict[str, str] config: mobility configuration
:return: response with result of success or failure
:rtype: core_pb2.SetMobilityConfigResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.SetMobilityConfigRequest(session=session, id=_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, action):
def mobility_action(self, session_id, node_id, action):
"""
Send a mobility action for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param core_pb2.ServiceAction action: action to take
:return: response with result of success or failure
:rtype: core_pb2.MobilityActionResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.MobilityActionRequest(session=session, id=_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):
@ -555,23 +527,23 @@ class CoreGrpcClient(object):
request = core_pb2.GetServicesRequest()
return self.stub.GetServices(request)
def get_service_defaults(self, session):
def get_service_defaults(self, session_id):
"""
Get default services for different default node models.
:param int session: session id
:param int session_id: session id
:return: response with a dict of node model to a list of services
:rtype: core_pb2.GetServiceDefaultsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetServiceDefaultsRequest(session=session)
request = core_pb2.GetServiceDefaultsRequest(session_id=session_id)
return self.stub.GetServiceDefaults(request)
def set_service_defaults(self, session, service_defaults):
def set_service_defaults(self, session_id, service_defaults):
"""
Set default services for node models.
:param int session: session id
:param int session_id: session id
:param dict service_defaults: node models to lists of services
:return: response with result of success or failure
:rtype: core_pb2.SetServiceDefaultsResponse
@ -582,44 +554,45 @@ 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=session, defaults=defaults)
request = core_pb2.SetServiceDefaultsRequest(session_id=session_id, defaults=defaults)
return self.stub.SetServiceDefaults(request)
def get_node_service(self, session, _id, service):
def get_node_service(self, session_id, node_id, service):
"""
Get service data for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param str service: service name
:return: response with node service data
:rtype: core_pb2.GetNodeServiceResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeServiceRequest(session=session, id=_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, service, file_name):
def get_node_service_file(self, session_id, node_id, service, file_name):
"""
Get a service file for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param str service: service name
:param str file_name: file name to get data for
:return: response with file data
:rtype: core_pb2.GetNodeServiceFileResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeServiceFileRequest(session=session, id=_id, service=service, file=file_name)
request = core_pb2.GetNodeServiceFileRequest(
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, service, startup, validate, shutdown):
def set_node_service(self, session_id, node_id, service, startup, validate, shutdown):
"""
Set service data for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param str service: service name
:param list startup: startup commands
:param list validate: validation commands
@ -629,15 +602,16 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.SetNodeServiceRequest(
session=session, id=_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, service, file_name, data):
def set_node_service_file(self, session_id, node_id, service, file_name, data):
"""
Set a service file for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param str service: service name
:param str file_name: file name to save
:param bytes data: data to save for file
@ -646,109 +620,110 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.SetNodeServiceFileRequest(
session=session, id=_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, service, action):
def service_action(self, session_id, node_id, service, action):
"""
Send an action to a service for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param str service: service name
:param core_pb2.ServiceAction action: action for service (start, stop, restart, validate)
:return: response with result of success or failure
:rtype: core_pb2.ServiceActionResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.ServiceActionRequest(session=session, id=_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):
def get_wlan_config(self, session_id, node_id):
"""
Get wlan configuration for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:return: response with a list of configuration groups
:rtype: core_pb2.GetWlanConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetWlanConfigRequest(session=session, id=_id)
request = core_pb2.GetWlanConfigRequest(session_id=session_id, node_id=node_id)
return self.stub.GetWlanConfig(request)
def set_wlan_config(self, session, _id, config):
def set_wlan_config(self, session_id, node_id, config):
"""
Set wlan configuration for a node.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param dict[str, str] config: wlan configuration
:return: response with result of success or failure
:rtype: core_pb2.SetWlanConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetWlanConfigRequest(session=session, id=_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):
def get_emane_config(self, session_id):
"""
Get session emane configuration.
:param int session: session id
:param int session_id: session id
:return: response with a list of configuration groups
:rtype: core_pb2.GetEmaneConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetEmaneConfigRequest(session=session)
request = core_pb2.GetEmaneConfigRequest(session_id=session_id)
return self.stub.GetEmaneConfig(request)
def set_emane_config(self, session, config):
def set_emane_config(self, session_id, config):
"""
Set session emane configuration.
:param int session: session id
:param int session_id: session id
:param dict[str, str] config: emane configuration
:return: response with result of success or failure
:rtype: core_pb2.SetEmaneConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetEmaneConfigRequest(session=session, config=config)
request = core_pb2.SetEmaneConfigRequest(session_id=session_id, config=config)
return self.stub.SetEmaneConfig(request)
def get_emane_models(self, session):
def get_emane_models(self, session_id):
"""
Get session emane models.
:param int session: session id
:param int session_id: session id
:return: response with a list of emane models
:rtype: core_pb2.GetEmaneModelsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetEmaneModelsRequest(session=session)
request = core_pb2.GetEmaneModelsRequest(session_id=session_id)
return self.stub.GetEmaneModels(request)
def get_emane_model_config(self, session, _id, model, interface_id=-1):
def get_emane_model_config(self, session_id, node_id, model, interface_id=-1):
"""
Get emane model configuration for a node or a node's interface.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param str model: emane model name
:param int interface_id: node interface id
:return: response with a list of configuration groups
:rtype: core_pb2.GetEmaneModelConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetEmaneModelConfigRequest(session=session, id=_id, model=model, interface=interface_id)
request = core_pb2.GetEmaneModelConfigRequest(
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, 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.
:param int session: session id
:param int _id: node id
:param int session_id: session id
:param int node_id: node id
:param str model: emane model name
:param dict[str, str] config: emane model configuration
:param int interface_id: node interface id
@ -757,30 +732,30 @@ class CoreGrpcClient(object):
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetEmaneModelConfigRequest(
session=session, id=_id, model=model, config=config, interface=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):
def get_emane_model_configs(self, session_id):
"""
Get all emane model configurations for a session.
:param int session: session id
:param int session_id: session id
:return: response with a dictionary of node/interface ids to configurations
:rtype: core_pb2.GetEmaneModelConfigsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetEmaneModelConfigsRequest(session=session)
request = core_pb2.GetEmaneModelConfigsRequest(session_id=session_id)
return self.stub.GetEmaneModelConfigs(request)
def save_xml(self, session, file_path):
def save_xml(self, session_id, file_path):
"""
Save the current scenario to an XML file.
:param int session: session id
:param int session_id: session id
:param str file_path: local path to save scenario XML file to
:return: nothing
"""
request = core_pb2.SaveXmlRequest(session=session)
request = core_pb2.SaveXmlRequest(session_id=session_id)
response = self.stub.SaveXml(request)
with open(file_path, "wb") as xml_file:
xml_file.write(response.data)

View file

@ -1,16 +1,18 @@
import atexit
import logging
import os
import re
import tempfile
import time
from builtins import int
from queue import Queue, Empty
import grpc
from builtins import int
from concurrent import futures
from queue import Queue, Empty
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
from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility
@ -19,6 +21,7 @@ from core.nodes.ipaddress import MacAddress
from core.services.coreservices import ServiceManager
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_INTERFACE_REGEX = re.compile(r"\d+")
def convert_value(value):
@ -59,11 +62,11 @@ def get_links(session, node):
return links
def get_emane_model_id(_id, interface):
if interface >= 0:
return _id * 1000 + interface
def get_emane_model_id(node_id, interface_id):
if interface_id >= 0:
return node_id * 1000 + interface_id
else:
return _id
return node_id
def convert_link(session, link_data):
@ -100,11 +103,27 @@ def convert_link(session, link_data):
)
return core_pb2.Link(
type=link_data.link_type, node_one=link_data.node1_id, node_two=link_data.node2_id,
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
)
def get_net_stats():
with open("/proc/net/dev", "r") as f:
data = f.readlines()[2:]
stats = {}
for line in data:
line = line.strip()
if not line:
continue
line = line.split()
line[0] = line[0].strip(":")
stats[line[0]] = {"rx": float(line[1]), "tx": float(line[9])}
return stats
class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def __init__(self, coreemu):
super(CoreGrpcServer, self).__init__()
@ -123,7 +142,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def _cancel_stream(self, context):
context.abort(grpc.StatusCode.CANCELLED, "server stopping")
def listen(self, address="[::]:50051"):
def listen(self, address):
logging.info("starting grpc api: %s", address)
self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
core_pb2_grpc.add_CoreApiServicer_to_server(self, self.server)
@ -136,29 +155,29 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
except KeyboardInterrupt:
self.server.stop(None)
def get_session(self, _id, context):
session = self.coreemu.sessions.get(_id)
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(_id))
context.abort(grpc.StatusCode.NOT_FOUND, "session {} not found".format(session_id))
return session
def get_node(self, session, _id, context):
def get_node(self, session, node_id, context):
try:
return session.get_node(_id)
return session.get_node(node_id)
except KeyError:
context.abort(grpc.StatusCode.NOT_FOUND, "node {} not found".format(_id))
context.abort(grpc.StatusCode.NOT_FOUND, "node {} not found".format(node_id))
def CreateSession(self, request, context):
logging.debug("create session: %s", request)
session = self.coreemu.create_session(request.id)
session = self.coreemu.create_session(request.session_id)
session.set_state(EventTypes.DEFINITION_STATE)
session.location.setrefgeo(47.57917, -122.13232, 2.0)
session.location.refscale = 150000.0
return core_pb2.CreateSessionResponse(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)
result = self.coreemu.delete_session(request.id)
result = self.coreemu.delete_session(request.session_id)
return core_pb2.DeleteSessionResponse(result=result)
def GetSessions(self, request, context):
@ -173,7 +192,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetSessionLocation(self, request, context):
logging.debug("get session location: %s", request)
session = self.get_session(request.id, context)
session = self.get_session(request.session_id, context)
x, y, z = session.location.refxyz
lat, lon, alt = session.location.refgeo
position = core_pb2.Position(x=x, y=y, z=z, lat=lat, lon=lon, alt=alt)
@ -181,7 +200,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def SetSessionLocation(self, request, context):
logging.debug("set session location: %s", request)
session = self.get_session(request.id, context)
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.refscale = request.scale
@ -189,7 +208,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def SetSessionState(self, request, context):
logging.debug("set session state: %s", request)
session = self.get_session(request.id, context)
session = self.get_session(request.session_id, context)
try:
state = EventTypes(request.state)
@ -214,7 +233,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetSessionOptions(self, request, context):
logging.debug("get session options: %s", request)
session = self.get_session(request.id, context)
session = self.get_session(request.session_id, context)
config = session.options.get_configs()
defaults = session.options.default_values()
defaults.update(config)
@ -223,14 +242,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def SetSessionOptions(self, request, context):
logging.debug("set session options: %s", request)
session = self.get_session(request.id, context)
session = self.get_session(request.session_id, context)
config = session.options.get_configs()
config.update(request.config)
return core_pb2.SetSessionOptionsResponse(result=True)
def GetSession(self, request, context):
logging.debug("get session: %s", request)
session = self.get_session(request.id, context)
session = self.get_session(request.session_id, context)
links = []
nodes = []
@ -263,178 +282,196 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
session_proto = core_pb2.Session(state=session.state, nodes=nodes, links=links)
return core_pb2.GetSessionResponse(session=session_proto)
def NodeEvents(self, request, context):
session = self.get_session(request.id, context)
def Events(self, request, context):
session = self.get_session(request.session_id, context)
queue = Queue()
session.node_handlers.append(queue.put)
while self._is_running(context):
try:
node = queue.get(timeout=1)
position = core_pb2.Position(x=node.x_position, y=node.y_position)
services = node.services or ""
services = services.split("|")
node_proto = core_pb2.Node(
id=node.id, name=node.name, model=node.model, position=position, services=services)
node_event = core_pb2.NodeEvent(node=node_proto)
yield node_event
except Empty:
continue
self._cancel_stream(context)
def LinkEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.link_handlers.append(queue.put)
while self._is_running(context):
try:
event = queue.get(timeout=1)
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)
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)
options = core_pb2.LinkOptions(
opaque=event.opaque,
jitter=event.jitter,
key=event.key,
mburst=event.mburst,
mer=event.mer,
per=event.per,
bandwidth=event.bandwidth,
burst=event.burst,
delay=event.delay,
dup=event.dup,
unidirectional=event.unidirectional
)
link = core_pb2.Link(
type=event.link_type, node_one=event.node1_id, node_two=event.node2_id,
interface_one=interface_one, interface_two=interface_two, options=options)
link_event = core_pb2.LinkEvent(message_type=event.message_type, link=link)
yield link_event
except Empty:
continue
self._cancel_stream(context)
def SessionEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.config_handlers.append(queue.put)
session.file_handlers.append(queue.put)
session.exception_handlers.append(queue.put)
session.event_handlers.append(queue.put)
while self._is_running(context):
event = core_pb2.Event()
try:
event = queue.get(timeout=1)
event_time = event.time
if event_time is not None:
event_time = float(event_time)
session_event = core_pb2.SessionEvent(
node=event.node,
event=event.event_type,
name=event.name,
data=event.data,
time=event_time,
session=session.id
)
yield session_event
data = queue.get(timeout=1)
if isinstance(data, NodeData):
event.node_event.CopyFrom(self._handle_node_event(data))
elif isinstance(data, LinkData):
event.link_event.CopyFrom(self._handle_link_event(data))
elif isinstance(data, EventData):
event.session_event.CopyFrom(self._handle_session_event(data))
elif isinstance(data, ConfigData):
event.config_event.CopyFrom(self._handle_config_event(data))
# TODO: remove when config events are fixed
event.config_event.session_id = session.id
elif isinstance(data, ExceptionData):
event.exception_event.CopyFrom(self._handle_exception_event(data))
elif isinstance(data, FileData):
event.file_event.CopyFrom(self._handle_file_event(data))
else:
logging.error("unknown event: %s", data)
continue
yield event
except Empty:
continue
session.node_handlers.remove(queue.put)
session.link_handlers.remove(queue.put)
session.config_handlers.remove(queue.put)
session.file_handlers.remove(queue.put)
session.exception_handlers.remove(queue.put)
session.event_handlers.remove(queue.put)
self._cancel_stream(context)
def ConfigEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.config_handlers.append(queue.put)
def _handle_node_event(self, event):
position = core_pb2.Position(x=event.x_position, y=event.y_position)
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)
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)
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)
options = core_pb2.LinkOptions(
opaque=event.opaque,
jitter=event.jitter,
key=event.key,
mburst=event.mburst,
mer=event.mer,
per=event.per,
bandwidth=event.bandwidth,
burst=event.burst,
delay=event.delay,
dup=event.dup,
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)
return core_pb2.LinkEvent(message_type=event.message_type, link=link)
def _handle_session_event(self, event):
event_time = event.time
if event_time is not None:
event_time = float(event_time)
return core_pb2.SessionEvent(
node_id=event.node,
event=event.event_type,
name=event.name,
data=event.data,
time=event_time,
session_id=event.session
)
def _handle_config_event(self, event):
session_id = None
if event.session is not None:
session_id = int(event.session)
return core_pb2.ConfigEvent(
message_type=event.message_type,
node_id=event.node,
object=event.object,
type=event.type,
captions=event.captions,
bitmap=event.bitmap,
data_values=event.data_values,
possible_values=event.possible_values,
groups=event.groups,
session_id=session_id,
interface=event.interface_number,
network_id=event.network_id,
opaque=event.opaque,
data_types=event.data_types
)
def _handle_exception_event(self, event):
return core_pb2.ExceptionEvent(
node_id=event.node,
session_id=int(event.session),
level=event.level.value,
source=event.source,
date=event.date,
text=event.text,
opaque=event.opaque
)
def _handle_file_event(self, event):
return core_pb2.FileEvent(
message_type=event.message_type,
node_id=event.node,
name=event.name,
mode=event.mode,
number=event.number,
type=event.type,
source=event.source,
session_id=event.session,
data=event.data,
compressed_data=event.compressed_data
)
def Throughputs(self, request, context):
delay = 3
last_check = None
last_stats = None
while self._is_running(context):
try:
event = queue.get(timeout=1)
config_event = core_pb2.ConfigEvent(
message_type=event.message_type,
node=event.node,
object=event.object,
type=event.type,
captions=event.captions,
bitmap=event.bitmap,
data_values=event.data_values,
possible_values=event.possible_values,
groups=event.groups,
session=event.session,
interface=event.interface_number,
network_id=event.network_id,
opaque=event.opaque,
data_types=event.data_types
)
yield config_event
except Empty:
continue
now = time.time()
stats = get_net_stats()
self._cancel_stream(context)
# calculate average
if last_check is not None:
interval = now - last_check
throughputs_event = core_pb2.ThroughputsEvent()
for key, current_rxtx in stats.iteritems():
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
throughput = rx_kbps + tx_kbps
print "%s - %s" % (key, throughput)
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.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.node_id = node_id
bridge_throughput.throughput = throughput
except ValueError:
pass
def ExceptionEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.exception_handlers.append(queue.put)
yield throughputs_event
while self._is_running(context):
try:
event = queue.get(timeout=1)
exception_event = core_pb2.ExceptionEvent(
node=event.node,
session=int(event.session),
level=event.level.value,
source=event.source,
date=event.date,
text=event.text,
opaque=event.opaque
)
yield exception_event
except Empty:
continue
self._cancel_stream(context)
def FileEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.file_handlers.append(queue.put)
while self._is_running(context):
try:
event = queue.get(timeout=1)
file_event = core_pb2.FileEvent(
message_type=event.message_type,
node=event.node,
name=event.name,
mode=event.mode,
number=event.number,
type=event.type,
source=event.source,
session=event.session,
data=event.data,
compressed_data=event.compressed_data
)
yield file_event
except Empty:
continue
self._cancel_stream(context)
last_check = now
last_stats = stats
time.sleep(delay)
def AddNode(self, request, context):
logging.debug("add node: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
node_proto = request.node
node_id = node_proto.id
@ -458,12 +495,12 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
if emane_model:
session.emane.set_model_config(node_id, emane_model)
return core_pb2.AddNodeResponse(id=node.id)
return core_pb2.AddNodeResponse(node_id=node.id)
def GetNode(self, request, context):
logging.debug("get node: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context)
interfaces = []
for interface_id in node._netif:
@ -491,8 +528,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def EditNode(self, request, context):
logging.debug("edit node: %s", request)
session = self.get_session(request.session, context)
node_id = request.id
session = self.get_session(request.session_id, context)
node_id = request.node_id
node_options = NodeOptions()
x = request.position.x
y = request.position.y
@ -506,26 +543,40 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def DeleteNode(self, request, context):
logging.debug("delete node: %s", request)
session = self.get_session(request.session, context)
result = session.delete_node(request.id)
session = self.get_session(request.session_id, context)
result = session.delete_node(request.node_id)
return core_pb2.DeleteNodeResponse(result=result)
def NodeCommand(self, request, context):
logging.debug("sending node command: %s", request)
session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context)
_, output = node.cmd_output(request.command)
return core_pb2.NodeCommandResponse(output=output)
def GetNodeTerminal(self, request, context):
logging.debug("getting node terminal: %s", request)
session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context)
terminal = node.termcmdstring("/bin/bash")
return core_pb2.GetNodeTerminalResponse(terminal=terminal)
def GetNodeLinks(self, request, context):
logging.debug("get node links: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context)
links = get_links(session, node)
return core_pb2.GetNodeLinksResponse(links=links)
def AddLink(self, request, context):
logging.debug("add link: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
# validate node exist
self.get_node(session, request.link.node_one, context)
self.get_node(session, request.link.node_two, context)
node_one = request.link.node_one
node_two = request.link.node_two
self.get_node(session, request.link.node_one_id, context)
self.get_node(session, request.link.node_two_id, context)
node_one_id = request.link.node_one_id
node_two_id = request.link.node_two_id
interface_one = None
interface_one_data = request.link.interface_one
@ -589,16 +640,16 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
link_options.key = options_data.key
link_options.opaque = options_data.opaque
session.add_link(node_one, node_two, 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):
logging.debug("edit link: %s", request)
session = self.get_session(request.session, context)
node_one = request.node_one
node_two = request.node_two
interface_one_id = request.interface_one
interface_two_id = request.interface_two
session = self.get_session(request.session_id, context)
node_one_id = request.node_one_id
node_two_id = request.node_two_id
interface_one_id = request.interface_one_id
interface_two_id = request.interface_two_id
options_data = request.options
link_options = LinkOptions()
link_options.delay = options_data.delay
@ -612,22 +663,22 @@ 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, node_two, 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):
logging.debug("delete link: %s", request)
session = self.get_session(request.session, context)
node_one = request.node_one
node_two = request.node_two
interface_one = request.interface_one
interface_two = request.interface_two
session.delete_link(node_one, node_two, interface_one, interface_two)
session = self.get_session(request.session_id, context)
node_one_id = request.node_one_id
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)
return core_pb2.DeleteLinkResponse(result=True)
def GetHooks(self, request, context):
logging.debug("get hooks: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
hooks = []
for state in session._hooks:
state_hooks = session._hooks[state]
@ -638,14 +689,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def AddHook(self, request, context):
logging.debug("add hook: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
hook = request.hook
session.add_hook(hook.state, hook.file, None, hook.data)
return core_pb2.AddHookResponse(result=True)
def GetMobilityConfigs(self, request, context):
logging.debug("get mobility configs: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
response = core_pb2.GetMobilityConfigsResponse()
for node_id in session.mobility.node_configurations:
model_config = session.mobility.node_configurations[node_id]
@ -661,27 +712,27 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetMobilityConfig(self, request, context):
logging.debug("get mobility config: %s", request)
session = self.get_session(request.session, context)
config = session.mobility.get_model_config(request.id, Ns2ScriptedMobility.name)
session = self.get_session(request.session_id, context)
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, context)
session.mobility.set_model_config(request.id, Ns2ScriptedMobility.name, request.config)
session = self.get_session(request.session_id, context)
session.mobility.set_model_config(request.node_id, Ns2ScriptedMobility.name, request.config)
return core_pb2.SetMobilityConfigResponse(result=True)
def MobilityAction(self, request, context):
logging.debug("mobility action: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context)
result = True
if request.action == core_pb2.MOBILITY_START:
if request.action == core_pb2.MobilityAction.START:
node.mobility.start()
elif request.action == core_pb2.MOBILITY_PAUSE:
elif request.action == core_pb2.MobilityAction.PAUSE:
node.mobility.pause()
elif request.action == core_pb2.MOBILITY_STOP:
elif request.action == core_pb2.MobilityAction.STOP:
node.mobility.stop(move_initial=True)
else:
result = False
@ -698,7 +749,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetServiceDefaults(self, request, context):
logging.debug("get service defaults: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
all_service_defaults = []
for node_type in session.services.default_services:
services = session.services.default_services[node_type]
@ -708,7 +759,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def SetServiceDefaults(self, request, context):
logging.debug("set service defaults: %s", request)
session = self.get_session(request.session, context)
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
@ -716,8 +767,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetNodeService(self, request, context):
logging.debug("get node service: %s", request)
session = self.get_session(request.session, context)
service = session.services.get_service(request.id, request.service, default_service=True)
session = self.get_session(request.session_id, context)
service = session.services.get_service(request.node_id, request.service, default_service=True)
service_proto = core_pb2.NodeServiceData(
executables=service.executables,
dependencies=service.dependencies,
@ -734,8 +785,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetNodeServiceFile(self, request, context):
logging.debug("get node service file: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context)
service = None
for current_service in node.services:
if current_service.name == request.service:
@ -748,9 +799,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def SetNodeService(self, request, context):
logging.debug("set node service: %s", request)
session = self.get_session(request.session, context)
session.services.set_service(request.id, request.service)
service = session.services.get_service(request.id, request.service)
session = self.get_session(request.session_id, context)
session.services.set_service(request.node_id, request.service)
service = session.services.get_service(request.node_id, request.service)
service.startup = tuple(request.startup)
service.validate = tuple(request.validate)
service.shutdown = tuple(request.shutdown)
@ -758,14 +809,14 @@ 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, context)
session.services.set_service_file(request.id, request.service, request.file, request.data)
session = self.get_session(request.session_id, context)
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):
logging.debug("service action: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context)
service = None
for current_service in node.services:
if current_service.name == request.service:
@ -776,15 +827,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
context.abort(grpc.StatusCode.NOT_FOUND, "service not found")
status = -1
if request.action == core_pb2.SERVICE_START:
if request.action == core_pb2.ServiceAction.START:
status = session.services.startup_service(node, service, wait=True)
elif request.action == core_pb2.SERVICE_STOP:
elif request.action == core_pb2.ServiceAction.STOP:
status = session.services.stop_service(node, service)
elif request.action == core_pb2.SERVICE_RESTART:
elif request.action == core_pb2.ServiceAction.RESTART:
status = session.services.stop_service(node, service)
if not status:
status = session.services.startup_service(node, service, wait=True)
elif request.action == core_pb2.SERVICE_VALIDATE:
elif request.action == core_pb2.ServiceAction.VALIDATE:
status = session.services.validate_service(node, service)
result = False
@ -795,34 +846,34 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetWlanConfig(self, request, context):
logging.debug("get wlan config: %s", request)
session = self.get_session(request.session, context)
config = session.mobility.get_model_config(request.id, BasicRangeModel.name)
session = self.get_session(request.session_id, context)
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, context)
session.mobility.set_model_config(request.id, BasicRangeModel.name, request.config)
session = self.get_session(request.session_id, context)
session.mobility.set_model_config(request.node_id, BasicRangeModel.name, request.config)
return core_pb2.SetWlanConfigResponse(result=True)
def GetEmaneConfig(self, request, context):
logging.debug("get emane config: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
config = session.emane.get_configs()
groups = get_config_groups(config, session.emane.emane_config)
return core_pb2.GetEmaneConfigResponse(groups=groups)
def SetEmaneConfig(self, request, context):
logging.debug("set emane config: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
config = session.emane.get_configs()
config.update(request.config)
return core_pb2.SetEmaneConfigResponse(result=True)
def GetEmaneModels(self, request, context):
logging.debug("get emane models: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
models = []
for model in session.emane.models.keys():
if len(model.split("_")) != 2:
@ -832,23 +883,23 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetEmaneModelConfig(self, request, context):
logging.debug("get emane model config: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
model = session.emane.models[request.model]
_id = get_emane_model_id(request.id, request.interface)
_id = get_emane_model_id(request.node_id, request.interface)
config = session.emane.get_model_config(_id, request.model)
groups = get_config_groups(config, model)
return core_pb2.GetEmaneModelConfigResponse(groups=groups)
def SetEmaneModelConfig(self, request, context):
logging.debug("set emane model config: %s", request)
session = self.get_session(request.session, context)
_id = get_emane_model_id(request.id, request.interface)
session = self.get_session(request.session_id, context)
_id = get_emane_model_id(request.node_id, request.interface_id)
session.emane.set_model_config(_id, request.model, request.config)
return core_pb2.SetEmaneModelConfigResponse(result=True)
def GetEmaneModelConfigs(self, request, context):
logging.debug("get emane model configs: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
response = core_pb2.GetEmaneModelConfigsResponse()
for node_id in session.emane.node_configurations:
model_config = session.emane.node_configurations[node_id]
@ -866,7 +917,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def SaveXml(self, request, context):
logging.debug("save xml: %s", request)
session = self.get_session(request.session, context)
session = self.get_session(request.session_id, context)
_, temp_path = tempfile.mkstemp()
session.save_xml(temp_path)
@ -887,7 +938,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
try:
session.open_xml(temp_path, start=True)
return core_pb2.OpenXmlResponse(session=session.id, result=True)
return core_pb2.OpenXmlResponse(session_id=session.id, result=True)
except IOError:
logging.exception("error opening session file")
self.coreemu.delete_session(session.id)

View file

@ -79,7 +79,7 @@ class NodeOptions(object):
Options for creating and updating nodes within core.
"""
def __init__(self, name=None, model="router"):
def __init__(self, name=None, model="PC"):
"""
Create a NodeOptions object.

View file

@ -13,26 +13,22 @@ def main():
with core.context_connect():
# create session
session = core.create_session()
logging.info("created session: %s", session)
response = core.create_session()
logging.info("created session: %s", response)
# handle events session may broadcast
core.exception_events(session.id, log_event)
core.node_events(session.id, log_event)
core.session_events(session.id, log_event)
core.link_events(session.id, log_event)
core.file_events(session.id, log_event)
core.config_events(session.id, log_event)
session_id = response.session_id
core.events(session_id, log_event)
# change session state
response = core.set_session_state(session.id, core_pb2.STATE_CONFIGURATION)
response = core.set_session_state(session_id, core_pb2.SessionState.CONFIGURATION)
logging.info("set session state: %s", response)
# create switch node
switch = core_pb2.Node(type=core_pb2.NODE_SWITCH)
response = core.add_node(session.id, switch)
switch = core_pb2.Node(type=core_pb2.NodeType.SWITCH)
response = core.add_node(session_id, switch)
logging.info("created switch: %s", response)
switch_id = response.id
switch_id = response.node_id
# helper to create interfaces
interface_helper = client.InterfaceHelper(ip4_prefix="10.83.0.0/16")
@ -41,17 +37,17 @@ def main():
# create node
position = core_pb2.Position(x=50 + 50 * i, y=50)
node = core_pb2.Node(position=position)
response = core.add_node(session.id, node)
response = core.add_node(session_id, node)
logging.info("created node: %s", response)
node_id = response.id
node_id = response.node_id
# create link
interface_one = interface_helper.create_interface(node_id, 0)
response = core.add_link(session.id, node_id, switch_id, interface_one)
response = core.add_link(session_id, node_id, switch_id, interface_one)
logging.info("created link: %s", response)
# change session state
response = core.set_session_state(session.id, core_pb2.STATE_INSTANTIATION)
response = core.set_session_state(session_id, core_pb2.SessionState.INSTANTIATION)
logging.info("set session state: %s", response)

View file

@ -2,6 +2,9 @@ syntax = "proto3";
package core;
option java_package = "com.core.client.grpc";
option java_outer_classname = "CoreProto";
service CoreApi {
// session rpc
rpc CreateSession (CreateSessionRequest) returns (CreateSessionResponse) {
@ -23,18 +26,10 @@ service CoreApi {
rpc SetSessionState (SetSessionStateRequest) returns (SetSessionStateResponse) {
}
// event streams
rpc NodeEvents (NodeEventsRequest) returns (stream NodeEvent) {
// streams
rpc Events (EventsRequest) returns (stream Event) {
}
rpc LinkEvents (LinkEventsRequest) returns (stream LinkEvent) {
}
rpc SessionEvents (SessionEventsRequest) returns (stream SessionEvent) {
}
rpc ConfigEvents (ConfigEventsRequest) returns (stream ConfigEvent) {
}
rpc ExceptionEvents (ExceptionEventsRequest) returns (stream ExceptionEvent) {
}
rpc FileEvents (FileEventsRequest) returns (stream FileEvent) {
rpc Throughputs (ThroughputsRequest) returns (stream ThroughputsEvent) {
}
// node rpc
@ -46,6 +41,10 @@ service CoreApi {
}
rpc DeleteNode (DeleteNodeRequest) returns (DeleteNodeResponse) {
}
rpc NodeCommand (NodeCommandRequest) returns (NodeCommandResponse) {
}
rpc GetNodeTerminal (GetNodeTerminalRequest) returns (GetNodeTerminalResponse) {
}
// link rpc
rpc GetNodeLinks (GetNodeLinksRequest) returns (GetNodeLinksResponse) {
@ -120,16 +119,16 @@ service CoreApi {
// rpc request/response messages
message CreateSessionRequest {
int32 id = 1;
int32 session_id = 1;
}
message CreateSessionResponse {
int32 id = 1;
SessionState state = 2;
int32 session_id = 1;
SessionState.Enum state = 2;
}
message DeleteSessionRequest {
int32 id = 1;
int32 session_id = 1;
}
message DeleteSessionResponse {
@ -144,7 +143,7 @@ message GetSessionsResponse {
}
message GetSessionRequest {
int32 id = 1;
int32 session_id = 1;
}
message GetSessionResponse {
@ -152,7 +151,7 @@ message GetSessionResponse {
}
message GetSessionOptionsRequest {
int32 id = 1;
int32 session_id = 1;
}
message GetSessionOptionsResponse {
@ -160,7 +159,7 @@ message GetSessionOptionsResponse {
}
message SetSessionOptionsRequest {
int32 id = 1;
int32 session_id = 1;
map<string, string> config = 2;
}
@ -169,7 +168,7 @@ message SetSessionOptionsResponse {
}
message GetSessionLocationRequest {
int32 id = 1;
int32 session_id = 1;
}
message GetSessionLocationResponse {
@ -178,7 +177,7 @@ message GetSessionLocationResponse {
}
message SetSessionLocationRequest {
int32 id = 1;
int32 session_id = 1;
Position position = 2;
float scale = 3;
}
@ -188,51 +187,69 @@ message SetSessionLocationResponse {
}
message SetSessionStateRequest {
int32 id = 1;
SessionState state = 2;
int32 session_id = 1;
SessionState.Enum state = 2;
}
message SetSessionStateResponse {
bool result = 1;
}
message NodeEventsRequest {
int32 id = 1;
message EventsRequest {
int32 session_id = 1;
}
message ThroughputsRequest {
}
message ThroughputsEvent {
repeated BridgeThroughput bridge_throughputs = 1;
repeated InterfaceThroughput interface_throughputs = 2;
}
message InterfaceThroughput {
int32 node_id = 1;
int32 interface_id = 2;
double throughput = 3;
}
message BridgeThroughput {
int32 node_id = 1;
double throughput = 2;
}
message Event {
oneof event_type {
SessionEvent session_event = 1;
NodeEvent node_event = 2;
LinkEvent link_event = 3;
ConfigEvent config_event = 4;
ExceptionEvent exception_event = 5;
FileEvent file_event = 6;
}
}
message NodeEvent {
Node node = 1;
}
message LinkEventsRequest {
int32 id = 1;
}
message LinkEvent {
MessageType message_type = 1;
MessageType.Enum message_type = 1;
Link link = 2;
}
message SessionEventsRequest {
int32 id = 1;
}
message SessionEvent {
int32 node = 1;
int32 node_id = 1;
int32 event = 2;
string name = 3;
bytes data = 4;
float time = 5;
int32 session = 6;
}
message ConfigEventsRequest {
int32 id = 1;
int32 session_id = 6;
}
message ConfigEvent {
MessageType message_type = 1;
int32 node = 2;
MessageType.Enum message_type = 1;
int32 node_id = 2;
string object = 3;
int32 type = 4;
repeated int32 data_types = 5;
@ -241,55 +258,47 @@ message ConfigEvent {
string bitmap = 8;
string possible_values = 9;
string groups = 10;
string session = 11;
int32 session_id = 11;
int32 interface = 12;
int32 network_id = 13;
string opaque = 14;
}
message ExceptionEventsRequest {
int32 id = 1;
}
message ExceptionEvent {
int32 node = 1;
int32 session = 2;
ExceptionLevel level = 3;
int32 node_id = 1;
int32 session_id = 2;
ExceptionLevel.Enum level = 3;
string source = 4;
string date = 5;
string text = 6;
string opaque = 7;
}
message FileEventsRequest {
int32 id = 1;
}
message FileEvent {
MessageType message_type = 1;
int32 node = 2;
MessageType.Enum message_type = 1;
int32 node_id = 2;
string name = 3;
string mode = 4;
int32 number = 5;
string type = 6;
string source = 7;
int32 session = 8;
int32 session_id = 8;
bytes data = 9;
bytes compressed_data = 10;
}
message AddNodeRequest {
int32 session = 1;
int32 session_id = 1;
Node node = 2;
}
message AddNodeResponse {
int32 id = 1;
int32 node_id = 1;
}
message GetNodeRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
}
message GetNodeResponse {
@ -298,8 +307,8 @@ message GetNodeResponse {
}
message EditNodeRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
Position position = 3;
}
@ -308,17 +317,36 @@ message EditNodeResponse {
}
message DeleteNodeRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
}
message DeleteNodeResponse {
bool result = 1;
}
message GetNodeTerminalRequest {
int32 session_id = 1;
int32 node_id = 2;
}
message GetNodeTerminalResponse {
string terminal = 1;
}
message NodeCommandRequest {
int32 session_id = 1;
int32 node_id = 2;
string command = 3;
}
message NodeCommandResponse {
string output = 1;
}
message GetNodeLinksRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
}
message GetNodeLinksResponse {
@ -326,7 +354,7 @@ message GetNodeLinksResponse {
}
message AddLinkRequest {
int32 session = 1;
int32 session_id = 1;
Link link = 2;
}
@ -335,11 +363,11 @@ message AddLinkResponse {
}
message EditLinkRequest {
int32 session = 1;
int32 node_one = 2;
int32 node_two = 3;
int32 interface_one = 4;
int32 interface_two = 5;
int32 session_id = 1;
int32 node_one_id = 2;
int32 node_two_id = 3;
int32 interface_one_id = 4;
int32 interface_two_id = 5;
LinkOptions options = 6;
}
@ -348,11 +376,11 @@ message EditLinkResponse {
}
message DeleteLinkRequest {
int32 session = 1;
int32 node_one = 2;
int32 node_two = 3;
int32 interface_one = 4;
int32 interface_two = 5;
int32 session_id = 1;
int32 node_one_id = 2;
int32 node_two_id = 3;
int32 interface_one_id = 4;
int32 interface_two_id = 5;
}
message DeleteLinkResponse {
@ -360,7 +388,7 @@ message DeleteLinkResponse {
}
message GetHooksRequest {
int32 session = 1;
int32 session_id = 1;
}
message GetHooksResponse {
@ -368,7 +396,7 @@ message GetHooksResponse {
}
message AddHookRequest {
int32 session = 1;
int32 session_id = 1;
Hook hook = 2;
}
@ -377,7 +405,7 @@ message AddHookResponse {
}
message GetMobilityConfigsRequest {
int32 session = 1;
int32 session_id = 1;
}
message GetMobilityConfigsResponse {
@ -388,8 +416,8 @@ message GetMobilityConfigsResponse {
}
message GetMobilityConfigRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
}
message GetMobilityConfigResponse {
@ -397,8 +425,8 @@ message GetMobilityConfigResponse {
}
message SetMobilityConfigRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
map<string, string> config = 3;
}
@ -407,9 +435,9 @@ message SetMobilityConfigResponse {
}
message MobilityActionRequest {
int32 session = 1;
int32 id = 2;
MobilityAction action = 3;
int32 session_id = 1;
int32 node_id = 2;
MobilityAction.Enum action = 3;
}
message MobilityActionResponse {
@ -425,7 +453,7 @@ message GetServicesResponse {
}
message GetServiceDefaultsRequest {
int32 session = 1;
int32 session_id = 1;
}
message GetServiceDefaultsResponse {
@ -433,7 +461,7 @@ message GetServiceDefaultsResponse {
}
message SetServiceDefaultsRequest {
int32 session = 1;
int32 session_id = 1;
repeated ServiceDefaults defaults = 2;
}
@ -442,8 +470,8 @@ message SetServiceDefaultsResponse {
}
message GetNodeServiceRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
string service = 3;
}
@ -452,8 +480,8 @@ message GetNodeServiceResponse {
}
message GetNodeServiceFileRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
string service = 3;
string file = 4;
}
@ -463,8 +491,8 @@ message GetNodeServiceFileResponse {
}
message SetNodeServiceRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
string service = 3;
repeated string startup = 4;
repeated string validate = 5;
@ -476,8 +504,8 @@ message SetNodeServiceResponse {
}
message SetNodeServiceFileRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
string service = 3;
string file = 4;
bytes data = 5;
@ -488,10 +516,10 @@ message SetNodeServiceFileResponse {
}
message ServiceActionRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
string service = 3;
ServiceAction action = 4;
ServiceAction.Enum action = 4;
}
message ServiceActionResponse {
@ -499,8 +527,8 @@ message ServiceActionResponse {
}
message GetWlanConfigRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
}
message GetWlanConfigResponse {
@ -508,8 +536,8 @@ message GetWlanConfigResponse {
}
message SetWlanConfigRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
map<string, string> config = 3;
}
@ -518,7 +546,7 @@ message SetWlanConfigResponse {
}
message GetEmaneConfigRequest {
int32 session = 1;
int32 session_id = 1;
}
message GetEmaneConfigResponse {
@ -526,7 +554,7 @@ message GetEmaneConfigResponse {
}
message SetEmaneConfigRequest {
int32 session = 1;
int32 session_id = 1;
map<string, string> config = 2;
}
@ -535,7 +563,7 @@ message SetEmaneConfigResponse {
}
message GetEmaneModelsRequest {
int32 session = 1;
int32 session_id = 1;
}
message GetEmaneModelsResponse {
@ -543,8 +571,8 @@ message GetEmaneModelsResponse {
}
message GetEmaneModelConfigRequest {
int32 session = 1;
int32 id = 2;
int32 session_id = 1;
int32 node_id = 2;
int32 interface = 3;
string model = 4;
}
@ -554,9 +582,9 @@ message GetEmaneModelConfigResponse {
}
message SetEmaneModelConfigRequest {
int32 session = 1;
int32 id = 2;
int32 interface = 3;
int32 session_id = 1;
int32 node_id = 2;
int32 interface_id = 3;
string model = 4;
map<string, string> config = 5;
}
@ -566,7 +594,7 @@ message SetEmaneModelConfigResponse {
}
message GetEmaneModelConfigsRequest {
int32 session = 1;
int32 session_id = 1;
}
message GetEmaneModelConfigsResponse {
@ -578,7 +606,7 @@ message GetEmaneModelConfigsResponse {
}
message SaveXmlRequest {
int32 session = 1;
int32 session_id = 1;
}
message SaveXmlResponse {
@ -591,82 +619,98 @@ message OpenXmlRequest {
message OpenXmlResponse {
bool result = 1;
int32 session = 2;
int32 session_id = 2;
}
// data structures for messages below
enum MessageType {
MESSAGE_NONE = 0;
MESSAGE_ADD = 1;
MESSAGE_DELETE = 2;
MESSAGE_CRI = 4;
MESSAGE_LOCAL = 8;
MESSAGE_STRING = 16;
MESSAGE_TEXT = 32;
MESSAGE_TTY = 64;
message MessageType {
enum Enum {
NONE = 0;
ADD = 1;
DELETE = 2;
CRI = 4;
LOCAL = 8;
STRING = 16;
TEXT = 32;
TTY = 64;
}
}
enum LinkType {
LINK_WIRELESS = 0;
LINK_WIRED = 1;
message LinkType {
enum Enum {
WIRELESS = 0;
WIRED = 1;
}
}
enum SessionState {
STATE_NONE = 0;
STATE_DEFINITION = 1;
STATE_CONFIGURATION = 2;
STATE_INSTANTIATION = 3;
STATE_RUNTIME = 4;
STATE_DATACOLLECT = 5;
STATE_SHUTDOWN = 6;
message SessionState {
enum Enum {
NONE = 0;
DEFINITION = 1;
CONFIGURATION = 2;
INSTANTIATION = 3;
RUNTIME = 4;
DATACOLLECT = 5;
SHUTDOWN = 6;
}
}
enum NodeType {
NODE_DEFAULT = 0;
NODE_PHYSICAL = 1;
NODE_TBD = 3;
NODE_SWITCH = 4;
NODE_HUB = 5;
NODE_WIRELESS_LAN = 6;
NODE_RJ45 = 7;
NODE_TUNNEL = 8;
NODE_KTUNNEL = 9;
NODE_EMANE = 10;
NODE_TAP_BRIDGE = 11;
NODE_PEER_TO_PEER = 12;
NODE_CONTROL_NET = 13;
NODE_EMANE_NET = 14;
message NodeType {
enum Enum {
DEFAULT = 0;
PHYSICAL = 1;
TBD = 3;
SWITCH = 4;
HUB = 5;
WIRELESS_LAN = 6;
RJ45 = 7;
TUNNEL = 8;
KTUNNEL = 9;
EMANE = 10;
TAP_BRIDGE = 11;
PEER_TO_PEER = 12;
CONTROL_NET = 13;
EMANE_NET = 14;
}
}
enum ServiceValidationMode {
VALIDATION_BLOCKING = 0;
VALIDATION_NON_BLOCKING = 1;
VALIDATION_TIMER = 2;
message ServiceValidationMode {
enum Enum {
BLOCKING = 0;
NON_BLOCKING = 1;
TIMER = 2;
}
}
enum ServiceAction {
SERVICE_START = 0;
SERVICE_STOP = 1;
SERVICE_RESTART = 2;
SERVICE_VALIDATE = 3;
message ServiceAction {
enum Enum {
START = 0;
STOP = 1;
RESTART = 2;
VALIDATE = 3;
}
}
enum MobilityAction {
MOBILITY_START = 0;
MOBILITY_PAUSE = 1;
MOBILITY_STOP = 2;
message MobilityAction {
enum Enum {
START = 0;
PAUSE = 1;
STOP = 2;
}
}
enum ExceptionLevel {
EXCEPTION_DEFAULT = 0;
EXCEPTION_FATAL = 1;
EXCEPTION_ERROR = 2;
EXCEPTION_WARNING = 3;
EXCEPTION_NOTICE = 4;
message ExceptionLevel {
enum Enum {
DEFAULT = 0;
FATAL = 1;
ERROR = 2;
WARNING = 3;
NOTICE = 4;
}
}
message Hook {
SessionState state = 1;
SessionState.Enum state = 1;
string file = 2;
bytes data = 3;
}
@ -688,7 +732,7 @@ message NodeServiceData {
repeated string configs = 4;
repeated string startup = 5;
repeated string validate = 6;
ServiceValidationMode validation_mode = 7;
ServiceValidationMode.Enum validation_mode = 7;
int32 validation_timer = 8;
repeated string shutdown = 9;
string meta = 10;
@ -709,21 +753,21 @@ message ConfigOption {
message Session {
int32 id = 1;
SessionState state = 2;
SessionState.Enum state = 2;
repeated Node nodes = 3;
repeated Link links = 4;
}
message SessionSummary {
int32 id = 1;
SessionState state = 2;
SessionState.Enum state = 2;
int32 nodes = 3;
}
message Node {
int32 id = 1;
string name = 2;
NodeType type = 3;
NodeType.Enum type = 3;
string model = 4;
Position position = 5;
repeated string services = 6;
@ -733,9 +777,9 @@ message Node {
}
message Link {
int32 node_one = 1;
int32 node_two = 2;
LinkType type = 3;
int32 node_one_id = 1;
int32 node_two_id = 2;
LinkType.Enum type = 3;
Interface interface_one = 4;
Interface interface_two = 5;
LinkOptions options = 6;

View file

@ -57,7 +57,8 @@ def cored(cfg):
# initialize grpc api
if cfg["grpc"] == "True":
grpc_server = CoreGrpcServer(server.coreemu)
grpc_thread = threading.Thread(target=grpc_server.listen)
grpc_address = "%s:%s" % (cfg["grpcaddress"], cfg["grpcport"])
grpc_thread = threading.Thread(target=grpc_server.listen, args=(grpc_address,))
grpc_thread.daemon = True
grpc_thread.start()
@ -80,6 +81,8 @@ def get_merged_config(filename):
"listenaddr": "localhost",
"xmlfilever": "1.0",
"numthreads": "1",
"grpcport": "50051",
"grpcaddress": "localhost"
}
parser = argparse.ArgumentParser(
@ -92,6 +95,10 @@ def get_merged_config(filename):
help="number of server threads; default = %s" % defaults["numthreads"])
parser.add_argument("--ovs", action="store_true", help="enable experimental ovs mode, default is false")
parser.add_argument("--grpc", action="store_true", help="enable grpc api, default is false")
parser.add_argument("--grpc-port", dest="grpcport",
help="grpc port to listen on; default %s" % defaults["grpcport"])
parser.add_argument("--grpc-address", dest="grpcaddress",
help="grpc address to listen on; default %s" % defaults["grpcaddress"])
# parse command line options
args = parser.parse_args()

View file

@ -58,7 +58,6 @@ setup(
description="Python components of CORE",
url="https://github.com/coreemu/core",
author="Boeing Research & Technology",
author_email="core-dev@nrl.navy.mil",
license="BSD",
long_description="Python scripts and modules for building virtual emulated networks.",
)

View file

@ -212,7 +212,7 @@ class CoreServerTest(object):
def grpc_server():
coremu = CoreEmu()
grpc_server = CoreGrpcServer(coremu)
thread = threading.Thread(target=grpc_server.listen)
thread = threading.Thread(target=grpc_server.listen, args=("localhost:50051",))
thread.daemon = True
thread.start()
time.sleep(0.1)

View file

@ -1,15 +1,16 @@
import time
from builtins import int
from queue import Queue
import grpc
import pytest
from builtins import int
from queue import Queue
from core.api.grpc import core_pb2
from core.api.grpc.client import CoreGrpcClient
from core.config import ConfigShim
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.emulator.data import EventData
from core.emulator.emudata import NodeOptions
from core.emulator.enumerations import NodeTypes, EventTypes, ConfigFlags, ExceptionLevels
from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility
@ -25,13 +26,13 @@ class TestGrpc:
response = client.create_session(session_id)
# then
assert isinstance(response.id, int)
assert isinstance(response.session_id, int)
assert isinstance(response.state, int)
session = grpc_server.coreemu.sessions.get(response.id)
session = grpc_server.coreemu.sessions.get(response.session_id)
assert session is not None
assert session.state == response.state
if session_id is not None:
assert response.id == session_id
assert response.session_id == session_id
assert session.id == session_id
@pytest.mark.parametrize("session_id, expected", [
@ -65,7 +66,7 @@ class TestGrpc:
response = client.get_session(session.id)
# then
assert response.session.state == core_pb2.STATE_DEFINITION
assert response.session.state == core_pb2.SessionState.DEFINITION
assert len(response.session.nodes) == 1
assert len(response.session.links) == 0
@ -164,11 +165,11 @@ class TestGrpc:
# then
with client.context_connect():
response = client.set_session_state(session.id, core_pb2.STATE_DEFINITION)
response = client.set_session_state(session.id, core_pb2.SessionState.DEFINITION)
# then
assert response.result is True
assert session.state == core_pb2.STATE_DEFINITION
assert session.state == core_pb2.SessionState.DEFINITION
def test_add_node(self, grpc_server):
# given
@ -181,8 +182,8 @@ class TestGrpc:
response = client.add_node(session.id, node)
# then
assert response.id is not None
assert session.get_node(response.id) is not None
assert response.node_id is not None
assert session.get_node(response.node_id) is not None
def test_get_node(self, grpc_server):
# given
@ -239,6 +240,40 @@ class TestGrpc:
with pytest.raises(KeyError):
assert session.get_node(node.id)
def test_node_command(self, grpc_server):
# given
client = CoreGrpcClient()
session = grpc_server.coreemu.create_session()
session.set_state(EventTypes.CONFIGURATION_STATE)
node_options = NodeOptions(model="Host")
node = session.add_node(node_options=node_options)
session.instantiate()
output = "hello world"
# then
command = "echo %s" % output
with client.context_connect():
response = client.node_command(session.id, node.id, command)
# then
assert response.output == output
def test_get_node_terminal(self, grpc_server):
# given
client = CoreGrpcClient()
session = grpc_server.coreemu.create_session()
session.set_state(EventTypes.CONFIGURATION_STATE)
node_options = NodeOptions(model="Host")
node = session.add_node(node_options=node_options)
session.instantiate()
# then
with client.context_connect():
response = client.get_node_terminal(session.id, node.id)
# then
assert response.terminal is not None
def test_get_hooks(self, grpc_server):
# given
client = CoreGrpcClient()
@ -254,7 +289,7 @@ class TestGrpc:
# then
assert len(response.hooks) == 1
hook = response.hooks[0]
assert hook.state == EventTypes.RUNTIME_STATE.value
assert hook.state == core_pb2.SessionState.RUNTIME
assert hook.file == file_name
assert hook.data == file_data
@ -267,7 +302,7 @@ class TestGrpc:
file_name = "test"
file_data = "echo hello"
with client.context_connect():
response = client.add_hook(session.id, core_pb2.STATE_RUNTIME, file_name, file_data)
response = client.add_hook(session.id, core_pb2.SessionState.RUNTIME, file_name, file_data)
# then
assert response.result is True
@ -298,7 +333,7 @@ class TestGrpc:
# then
assert response.result is True
assert response.session is not None
assert response.session_id is not None
def test_get_node_links(self, grpc_server, ip_prefixes):
# given
@ -373,7 +408,7 @@ class TestGrpc:
# then
with client.context_connect():
response = client.edit_link(session.id, node.id, switch.id, options, interface_one=interface.id)
response = client.edit_link(session.id, node.id, switch.id, options, interface_one_id=interface.id)
# then
assert response.result is True
@ -591,7 +626,7 @@ class TestGrpc:
# then
with client.context_connect():
response = client.mobility_action(session.id, wlan.id, core_pb2.MOBILITY_STOP)
response = client.mobility_action(session.id, wlan.id, core_pb2.MobilityAction.STOP)
# then
assert response.result is True
@ -666,16 +701,16 @@ class TestGrpc:
session = grpc_server.coreemu.create_session()
node = session.add_node()
service_name = "IPForward"
validate = ("echo hello",)
validate = ["echo hello"]
# then
with client.context_connect():
response = client.set_node_service(session.id, node.id, service_name, (), validate, ())
response = client.set_node_service(session.id, node.id, service_name, [], validate, [])
# then
assert response.result is True
service = session.services.get_service(node.id, service_name, default_service=True)
assert service.validate == validate
assert service.validate == tuple(validate)
def test_set_node_service_file(self, grpc_server):
# given
@ -704,7 +739,7 @@ class TestGrpc:
# then
with client.context_connect():
response = client.service_action(session.id, node.id, service_name, core_pb2.SERVICE_STOP)
response = client.service_action(session.id, node.id, service_name, core_pb2.ServiceAction.STOP)
# then
assert response.result is True
@ -718,11 +753,12 @@ class TestGrpc:
queue = Queue()
def handle_event(event_data):
assert event_data.HasField("node_event")
queue.put(event_data)
# then
with client.context_connect():
client.node_events(session.id, handle_event)
client.events(session.id, handle_event)
time.sleep(0.1)
session.broadcast_node(node_data)
@ -741,17 +777,35 @@ class TestGrpc:
queue = Queue()
def handle_event(event_data):
assert event_data.HasField("link_event")
queue.put(event_data)
# then
with client.context_connect():
client.link_events(session.id, handle_event)
client.events(session.id, handle_event)
time.sleep(0.1)
session.broadcast_link(link_data)
# then
queue.get(timeout=5)
def test_throughputs(self, grpc_server):
# given
client = CoreGrpcClient()
session = grpc_server.coreemu.create_session()
queue = Queue()
def handle_event(event_data):
queue.put(event_data)
# then
with client.context_connect():
client.throughputs(handle_event)
time.sleep(0.1)
# then
queue.get(timeout=5)
def test_session_events(self, grpc_server):
# given
client = CoreGrpcClient()
@ -759,11 +813,12 @@ class TestGrpc:
queue = Queue()
def handle_event(event_data):
assert event_data.HasField("session_event")
queue.put(event_data)
# then
with client.context_connect():
client.session_events(session.id, handle_event)
client.events(session.id, handle_event)
time.sleep(0.1)
event = EventData(event_type=EventTypes.RUNTIME_STATE.value, time="%s" % time.time())
session.broadcast_event(event)
@ -778,11 +833,12 @@ class TestGrpc:
queue = Queue()
def handle_event(event_data):
assert event_data.HasField("config_event")
queue.put(event_data)
# then
with client.context_connect():
client.config_events(session.id, handle_event)
client.events(session.id, handle_event)
time.sleep(0.1)
session_config = session.options.get_configs()
config_data = ConfigShim.config_data(0, None, ConfigFlags.UPDATE.value, session.options, session_config)
@ -798,11 +854,12 @@ class TestGrpc:
queue = Queue()
def handle_event(event_data):
assert event_data.HasField("exception_event")
queue.put(event_data)
# then
with client.context_connect():
client.exception_events(session.id, handle_event)
client.events(session.id, handle_event)
time.sleep(0.1)
session.exception(ExceptionLevels.FATAL, "test", None, "exception message")
@ -817,11 +874,12 @@ class TestGrpc:
queue = Queue()
def handle_event(event_data):
assert event_data.HasField("file_event")
queue.put(event_data)
# then
with client.context_connect():
client.file_events(session.id, handle_event)
client.events(session.id, handle_event)
time.sleep(0.1)
file_data = session.services.get_service_file(node, "IPForward", "ipforward.sh")
session.broadcast_file(file_data)