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,
SetWlanConfigResponse,
WlanConfig,
WlanLinkRequest,
WlanLinkResponse,
)
@ -1204,6 +1206,18 @@ class CoreGrpcClient:
request = ExecuteScriptRequest(script=script)
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:
"""
Open connection to server, must be closed manually.

View file

@ -6,7 +6,7 @@ import tempfile
import threading
import time
from concurrent import futures
from typing import Type
from typing import Type, TypeVar
import grpc
from grpc import ServicerContext
@ -102,6 +102,8 @@ from core.api.grpc.wlan_pb2 import (
GetWlanConfigsResponse,
SetWlanConfigRequest,
SetWlanConfigResponse,
WlanLinkRequest,
WlanLinkResponse,
)
from core.emulator.coreemu import CoreEmu
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.errors import CoreCommandError, CoreError
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
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_INTERFACE_REGEX = re.compile(r"veth(?P<node>[0-9a-fA-F]+)")
T = TypeVar("T")
class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
@ -170,19 +174,34 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
return session
def get_node(
self, session: Session, node_id: int, context: ServicerContext
) -> NodeBase:
self,
session: Session,
node_id: int,
context: ServicerContext,
node_class: Type[T],
) -> T:
"""
Retrieve node given session and node id
:param session: session that has the node
: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.
:raises Exception: raises grpc exception when node does not exist
"""
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:
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
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]
if config.config:
service.set_config(config.config)
@ -678,7 +697,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
"""
logging.debug("get node: %s", request)
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 = []
for interface_id in node._netif:
interface = node._netif[interface_id]
@ -699,7 +718,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
"""
logging.debug("edit node: %s", request)
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.icon = request.icon
if request.HasField("position"):
@ -751,7 +770,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
"""
logging.debug("sending node command: %s", request)
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:
output = node.cmd(request.command)
except CoreCommandError as e:
@ -770,7 +789,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
"""
logging.debug("getting node terminal: %s", request)
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")
return core_pb2.GetNodeTerminalResponse(terminal=terminal)
@ -786,7 +805,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
"""
logging.debug("get node links: %s", request)
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)
return core_pb2.GetNodeLinksResponse(links=links)
@ -803,8 +822,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
logging.debug("add link: %s", request)
# validate session and nodes
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_two_id, context)
self.get_node(session, request.link.node_one_id, context, NodeBase)
self.get_node(session, request.link.node_two_id, context, NodeBase)
node_one_id = request.link.node_one_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)
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
if request.action == MobilityAction.START:
node.mobility.start()
@ -1121,7 +1140,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
"""
logging.debug("get node service file: %s", request)
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(
node, request.service, request.file
)
@ -1176,7 +1195,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
"""
logging.debug("service action: %s", request)
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
for current_service in node.services:
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
)
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)
return SetWlanConfigResponse(result=True)
@ -1546,7 +1565,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
:return: get node config service response
"""
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)
service = node.config_services.get(request.name)
if service:
@ -1628,7 +1647,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
:return: get node config services response
"""
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()
return GetNodeConfigServicesResponse(services=services)
@ -1643,7 +1662,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
:return: set node config service response
"""
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)
service = node.config_services.get(request.name)
if service:
@ -1684,3 +1703,35 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
if new_sessions:
new_session = new_sessions[0]
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
:return: nothing
"""
if unlink:
message_type = MessageFlags.DELETE
else:
message_type = MessageFlags.ADD
message_type = MessageFlags.DELETE if unlink else MessageFlags.ADD
link_data = self.create_link_data(netif, netif2, message_type)
self.session.broadcast_link(link_data)

View file

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

View file

@ -34,3 +34,15 @@ message SetWlanConfigRequest {
message SetWlanConfigResponse {
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;
}