Merge pull request #451 from coreemu/enhancement/grpc-wlan-links

Enhancement/grpc wlan links
This commit is contained in:
bharnden 2020-05-20 11:40:46 -07:00 committed by GitHub
commit 19ee367dc5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 101 additions and 26 deletions

View file

@ -89,6 +89,8 @@ from core.api.grpc.wlan_pb2 import (
SetWlanConfigRequest, SetWlanConfigRequest,
SetWlanConfigResponse, SetWlanConfigResponse,
WlanConfig, WlanConfig,
WlanLinkRequest,
WlanLinkResponse,
) )
@ -1204,6 +1206,18 @@ class CoreGrpcClient:
request = ExecuteScriptRequest(script=script) request = ExecuteScriptRequest(script=script)
return self.stub.ExecuteScript(request) return self.stub.ExecuteScript(request)
def wlan_link(
self, session_id: int, wlan: int, node_one: int, node_two: int, linked: bool
) -> WlanLinkResponse:
request = WlanLinkRequest(
session_id=session_id,
wlan=wlan,
node_one=node_one,
node_two=node_two,
linked=linked,
)
return self.stub.WlanLink(request)
def connect(self) -> None: def connect(self) -> None:
""" """
Open connection to server, must be closed manually. Open connection to server, must be closed manually.

View file

@ -6,7 +6,7 @@ import tempfile
import threading import threading
import time import time
from concurrent import futures from concurrent import futures
from typing import Type from typing import Type, TypeVar
import grpc import grpc
from grpc import ServicerContext from grpc import ServicerContext
@ -102,6 +102,8 @@ from core.api.grpc.wlan_pb2 import (
GetWlanConfigsResponse, GetWlanConfigsResponse,
SetWlanConfigRequest, SetWlanConfigRequest,
SetWlanConfigResponse, SetWlanConfigResponse,
WlanLinkRequest,
WlanLinkResponse,
) )
from core.emulator.coreemu import CoreEmu from core.emulator.coreemu import CoreEmu
from core.emulator.data import LinkData from core.emulator.data import LinkData
@ -110,11 +112,13 @@ from core.emulator.enumerations import EventTypes, LinkTypes, MessageFlags
from core.emulator.session import Session from core.emulator.session import Session
from core.errors import CoreCommandError, CoreError from core.errors import CoreCommandError, CoreError
from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility
from core.nodes.base import CoreNodeBase, NodeBase from core.nodes.base import CoreNode, CoreNodeBase, NodeBase
from core.nodes.network import WlanNode
from core.services.coreservices import ServiceManager from core.services.coreservices import ServiceManager
_ONE_DAY_IN_SECONDS = 60 * 60 * 24 _ONE_DAY_IN_SECONDS = 60 * 60 * 24
_INTERFACE_REGEX = re.compile(r"veth(?P<node>[0-9a-fA-F]+)") _INTERFACE_REGEX = re.compile(r"veth(?P<node>[0-9a-fA-F]+)")
T = TypeVar("T")
class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
@ -170,19 +174,34 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
return session return session
def get_node( def get_node(
self, session: Session, node_id: int, context: ServicerContext self,
) -> NodeBase: session: Session,
node_id: int,
context: ServicerContext,
node_class: Type[T],
) -> T:
""" """
Retrieve node given session and node id Retrieve node given session and node id
:param session: session that has the node :param session: session that has the node
:param node_id: node id :param node_id: node id
:param context: :param context: request
:param node_class: type of node we are expecting
:return: node object that satisfies. If node not found then raise an exception. :return: node object that satisfies. If node not found then raise an exception.
:raises Exception: raises grpc exception when node does not exist :raises Exception: raises grpc exception when node does not exist
""" """
try: try:
return session.get_node(node_id) node = session.get_node(node_id)
if isinstance(node, node_class):
return node
else:
actual = node.__class__.__name__
expected = node_class.__name__
context.abort(
grpc.StatusCode.NOT_FOUND,
f"node({node_id}) class({actual}) "
f"was not expected class({expected})",
)
except CoreError: except CoreError:
context.abort(grpc.StatusCode.NOT_FOUND, f"node {node_id} not found") context.abort(grpc.StatusCode.NOT_FOUND, f"node {node_id} not found")
@ -261,7 +280,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
# config service configs # config service configs
for config in request.config_service_configs: for config in request.config_service_configs:
node = self.get_node(session, config.node_id, context) node = self.get_node(session, config.node_id, context, CoreNode)
service = node.config_services[config.name] service = node.config_services[config.name]
if config.config: if config.config:
service.set_config(config.config) service.set_config(config.config)
@ -678,7 +697,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
""" """
logging.debug("get node: %s", request) logging.debug("get node: %s", request)
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, NodeBase)
interfaces = [] interfaces = []
for interface_id in node._netif: for interface_id in node._netif:
interface = node._netif[interface_id] interface = node._netif[interface_id]
@ -699,7 +718,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
""" """
logging.debug("edit node: %s", request) logging.debug("edit node: %s", request)
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, NodeBase)
options = NodeOptions() options = NodeOptions()
options.icon = request.icon options.icon = request.icon
if request.HasField("position"): if request.HasField("position"):
@ -751,7 +770,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
""" """
logging.debug("sending node command: %s", request) logging.debug("sending node command: %s", request)
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, CoreNode)
try: try:
output = node.cmd(request.command) output = node.cmd(request.command)
except CoreCommandError as e: except CoreCommandError as e:
@ -770,7 +789,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
""" """
logging.debug("getting node terminal: %s", request) logging.debug("getting node terminal: %s", request)
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, CoreNode)
terminal = node.termcmdstring("/bin/bash") terminal = node.termcmdstring("/bin/bash")
return core_pb2.GetNodeTerminalResponse(terminal=terminal) return core_pb2.GetNodeTerminalResponse(terminal=terminal)
@ -786,7 +805,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
""" """
logging.debug("get node links: %s", request) logging.debug("get node links: %s", request)
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, NodeBase)
links = get_links(node) links = get_links(node)
return core_pb2.GetNodeLinksResponse(links=links) return core_pb2.GetNodeLinksResponse(links=links)
@ -803,8 +822,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
logging.debug("add link: %s", request) logging.debug("add link: %s", request)
# validate session and nodes # validate session and nodes
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
self.get_node(session, request.link.node_one_id, context) self.get_node(session, request.link.node_one_id, context, NodeBase)
self.get_node(session, request.link.node_two_id, context) self.get_node(session, request.link.node_two_id, context, NodeBase)
node_one_id = request.link.node_one_id node_one_id = request.link.node_one_id
node_two_id = request.link.node_two_id node_two_id = request.link.node_two_id
@ -994,7 +1013,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
""" """
logging.debug("mobility action: %s", request) logging.debug("mobility action: %s", request)
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, WlanNode)
result = True result = True
if request.action == MobilityAction.START: if request.action == MobilityAction.START:
node.mobility.start() node.mobility.start()
@ -1121,7 +1140,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
""" """
logging.debug("get node service file: %s", request) logging.debug("get node service file: %s", request)
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, CoreNode)
file_data = session.services.get_service_file( file_data = session.services.get_service_file(
node, request.service, request.file node, request.service, request.file
) )
@ -1176,7 +1195,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
""" """
logging.debug("service action: %s", request) logging.debug("service action: %s", request)
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, CoreNode)
service = None service = None
for current_service in node.services: for current_service in node.services:
if current_service.name == request.service: if current_service.name == request.service:
@ -1265,7 +1284,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
wlan_config.node_id, BasicRangeModel.name, wlan_config.config wlan_config.node_id, BasicRangeModel.name, wlan_config.config
) )
if session.state == EventTypes.RUNTIME_STATE: if session.state == EventTypes.RUNTIME_STATE:
node = self.get_node(session, wlan_config.node_id, context) node = self.get_node(session, wlan_config.node_id, context, WlanNode)
node.updatemodel(wlan_config.config) node.updatemodel(wlan_config.config)
return SetWlanConfigResponse(result=True) return SetWlanConfigResponse(result=True)
@ -1546,7 +1565,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
:return: get node config service response :return: get node config service response
""" """
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, CoreNode)
self.validate_service(request.name, context) self.validate_service(request.name, context)
service = node.config_services.get(request.name) service = node.config_services.get(request.name)
if service: if service:
@ -1628,7 +1647,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
:return: get node config services response :return: get node config services response
""" """
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, CoreNode)
services = node.config_services.keys() services = node.config_services.keys()
return GetNodeConfigServicesResponse(services=services) return GetNodeConfigServicesResponse(services=services)
@ -1643,7 +1662,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
:return: set node config service response :return: set node config service response
""" """
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context, CoreNode)
self.validate_service(request.name, context) self.validate_service(request.name, context)
service = node.config_services.get(request.name) service = node.config_services.get(request.name)
if service: if service:
@ -1684,3 +1703,35 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
if new_sessions: if new_sessions:
new_session = new_sessions[0] new_session = new_sessions[0]
return ExecuteScriptResponse(session_id=new_session) return ExecuteScriptResponse(session_id=new_session)
def WlanLink(
self, request: WlanLinkRequest, context: ServicerContext
) -> WlanLinkResponse:
session = self.get_session(request.session_id, context)
wlan = self.get_node(session, request.wlan, context, WlanNode)
if not isinstance(wlan, WlanNode):
context.abort(
grpc.StatusCode.NOT_FOUND, f"wlan id {request.wlan} is not a wlan node"
)
if not isinstance(wlan.model, BasicRangeModel):
context.abort(
grpc.StatusCode.NOT_FOUND,
f"wlan node {request.wlan} does not using BasicRangeModel",
)
n1 = self.get_node(session, request.node_one, context, CoreNode)
n2 = self.get_node(session, request.node_two, context, CoreNode)
n1_netif, n2_netif = None, None
for net, netif1, netif2 in n1.commonnets(n2):
if net == wlan:
n1_netif = netif1
n2_netif = netif2
break
result = False
if n1_netif and n2_netif:
if request.linked:
wlan.link(n1_netif, n2_netif)
else:
wlan.unlink(n1_netif, n2_netif)
wlan.model.sendlinkmsg(n1_netif, n2_netif, unlink=not request.linked)
result = True
return WlanLinkResponse(result=result)

View file

@ -509,11 +509,7 @@ class BasicRangeModel(WirelessModel):
:param unlink: unlink or not :param unlink: unlink or not
:return: nothing :return: nothing
""" """
if unlink: message_type = MessageFlags.DELETE if unlink else MessageFlags.ADD
message_type = MessageFlags.DELETE
else:
message_type = MessageFlags.ADD
link_data = self.create_link_data(netif, netif2, message_type) link_data = self.create_link_data(netif, netif2, message_type)
self.session.broadcast_link(link_data) self.session.broadcast_link(link_data)

View file

@ -129,6 +129,8 @@ service CoreApi {
} }
rpc SetWlanConfig (wlan.SetWlanConfigRequest) returns (wlan.SetWlanConfigResponse) { rpc SetWlanConfig (wlan.SetWlanConfigRequest) returns (wlan.SetWlanConfigResponse) {
} }
rpc WlanLink (wlan.WlanLinkRequest) returns (wlan.WlanLinkResponse) {
}
// emane rpc // emane rpc
rpc GetEmaneConfig (emane.GetEmaneConfigRequest) returns (emane.GetEmaneConfigResponse) { rpc GetEmaneConfig (emane.GetEmaneConfigRequest) returns (emane.GetEmaneConfigResponse) {

View file

@ -34,3 +34,15 @@ message SetWlanConfigRequest {
message SetWlanConfigResponse { message SetWlanConfigResponse {
bool result = 1; bool result = 1;
} }
message WlanLinkRequest {
int32 session_id = 1;
int32 wlan = 2;
int32 node_one = 3;
int32 node_two = 4;
bool linked = 5;
}
message WlanLinkResponse {
bool result = 1;
}