fix code based on the new changes

This commit is contained in:
Huy Pham 2019-11-15 17:26:02 -08:00
commit 7f2a2f8043
15 changed files with 278 additions and 724 deletions

View file

@ -6,13 +6,6 @@ from coretk.dialogs.emaneconfig import EmaneConfiguration
from coretk.dialogs.nodeconfig import NodeConfigDialog from coretk.dialogs.nodeconfig import NodeConfigDialog
from coretk.dialogs.wlanconfig import WlanConfigDialog from coretk.dialogs.wlanconfig import WlanConfigDialog
# TODO, finish classifying node types
NODE_TO_TYPE = {
"router": core_pb2.NodeType.DEFAULT,
"wlan": core_pb2.NodeType.WIRELESS_LAN,
"emane": core_pb2.NodeType.EMANE,
}
class CanvasAction: class CanvasAction:
def __init__(self, master, canvas): def __init__(self, master, canvas):
@ -21,13 +14,13 @@ class CanvasAction:
self.node_to_show_config = None self.node_to_show_config = None
def display_configuration(self, canvas_node): def display_configuration(self, canvas_node):
pb_type = NODE_TO_TYPE[canvas_node.node_type] node_type = canvas_node.core_node.type
self.node_to_show_config = canvas_node self.node_to_show_config = canvas_node
if pb_type == core_pb2.NodeType.DEFAULT: if node_type == core_pb2.NodeType.DEFAULT:
self.display_node_configuration() self.display_node_configuration()
elif pb_type == core_pb2.NodeType.WIRELESS_LAN: elif node_type == core_pb2.NodeType.WIRELESS_LAN:
self.display_wlan_configuration(canvas_node) self.display_wlan_configuration(canvas_node)
elif pb_type == core_pb2.NodeType.EMANE: elif node_type == core_pb2.NodeType.EMANE:
self.display_emane_configuration() self.display_emane_configuration()
def display_node_configuration(self): def display_node_configuration(self):
@ -36,8 +29,6 @@ class CanvasAction:
self.node_to_show_config = None self.node_to_show_config = None
def display_wlan_configuration(self, canvas_node): def display_wlan_configuration(self, canvas_node):
# print(self.canvas.grpc_manager.wlanconfig_management.configurations)
wlan_config = self.master.core.wlanconfig_management.configurations[ wlan_config = self.master.core.wlanconfig_management.configurations[
canvas_node.core_id canvas_node.core_id
] ]

View file

@ -5,11 +5,10 @@ import logging
import os import os
from core.api.grpc import client, core_pb2 from core.api.grpc import client, core_pb2
from coretk.coretocanvas import CoreToCanvasMapping
from coretk.dialogs.sessions import SessionsDialog from coretk.dialogs.sessions import SessionsDialog
from coretk.emaneodelnodeconfig import EmaneModelNodeConfig from coretk.emaneodelnodeconfig import EmaneModelNodeConfig
from coretk.images import NODE_WIDTH, Images from coretk.images import NODE_WIDTH, Images
from coretk.interface import Interface, InterfaceManager from coretk.interface import InterfaceManager
from coretk.mobilitynodeconfig import MobilityNodeConfig from coretk.mobilitynodeconfig import MobilityNodeConfig
from coretk.servicefileconfig import ServiceFileConfig from coretk.servicefileconfig import ServiceFileConfig
from coretk.servicenodeconfig import ServiceNodeConfig from coretk.servicenodeconfig import ServiceNodeConfig
@ -30,47 +29,6 @@ OBSERVERS = {
} }
class Node:
def __init__(self, session_id, node_id, node_type, model, x, y, name):
"""
Create an instance of a node
:param int session_id: session id
:param int node_id: node id
:param core_pb2.NodeType node_type: node type
:param int x: x coordinate
:param int y: coordinate
:param str name: node name
"""
self.session_id = session_id
self.node_id = node_id
self.type = node_type
self.x = x
self.y = y
self.model = model
self.name = name
self.interfaces = []
class Edge:
def __init__(self, session_id, node_id_1, node_type_1, node_id_2, node_type_2):
"""
Create an instance of an edge
:param int session_id: session id
:param int node_id_1: node 1 id
:param int node_type_1: node 1 type
:param core_pb2.NodeType node_id_2: node 2 id
:param core_pb2.NodeType node_type_2: node 2 type
"""
self.session_id = session_id
self.id1 = node_id_1
self.id2 = node_id_2
self.type1 = node_type_1
self.type2 = node_type_2
self.interface_1 = None
self.interface_2 = None
class CoreServer: class CoreServer:
def __init__(self, name, address, port): def __init__(self, name, address, port):
self.name = name self.name = name
@ -113,15 +71,15 @@ class CoreClient:
self.read_config() self.read_config()
# data for managing the current session # data for managing the current session
self.canvas_nodes = {}
self.interface_to_edge = {}
self.state = None self.state = None
self.nodes = {} self.links = {}
self.edges = {}
self.hooks = {} self.hooks = {}
self.id = 1 self.id = 1
self.reusable = [] self.reusable = []
self.preexisting = set() self.preexisting = set()
self.interfaces_manager = InterfaceManager() self.interfaces_manager = InterfaceManager()
self.core_mapping = CoreToCanvasMapping()
self.wlanconfig_management = WlanNodeConfig() self.wlanconfig_management = WlanNodeConfig()
self.mobilityconfig_management = MobilityNodeConfig() self.mobilityconfig_management = MobilityNodeConfig()
self.emaneconfig_management = EmaneModelNodeConfig(app) self.emaneconfig_management = EmaneModelNodeConfig(app)
@ -183,8 +141,8 @@ class CoreClient:
# clear session data # clear session data
self.reusable.clear() self.reusable.clear()
self.preexisting.clear() self.preexisting.clear()
self.nodes.clear() self.canvas_nodes.clear()
self.edges.clear() self.links.clear()
self.hooks.clear() self.hooks.clear()
self.wlanconfig_management.configurations.clear() self.wlanconfig_management.configurations.clear()
self.mobilityconfig_management.configurations.clear() self.mobilityconfig_management.configurations.clear()
@ -207,14 +165,14 @@ class CoreClient:
for node in session.nodes: for node in session.nodes:
if node.type == core_pb2.NodeType.WIRELESS_LAN: if node.type == core_pb2.NodeType.WIRELESS_LAN:
response = self.client.get_wlan_config(self.session_id, node.id) response = self.client.get_wlan_config(self.session_id, node.id)
logging.info("wlan config(%s): %s", node.id, response) logging.debug("wlan config(%s): %s", node.id, response)
node_config = response.config node_config = response.config
config = {x: node_config[x].value for x in node_config} config = {x: node_config[x].value for x in node_config}
self.wlanconfig_management.configurations[node.id] = config self.wlanconfig_management.configurations[node.id] = config
# get mobility configs # get mobility configs
response = self.client.get_mobility_configs(self.session_id) response = self.client.get_mobility_configs(self.session_id)
logging.info("mobility configs: %s", response) logging.debug("mobility configs: %s", response)
for node_id in response.configs: for node_id in response.configs:
node_config = response.configs[node_id].config node_config = response.configs[node_id].config
config = {x: node_config[x].value for x in node_config} config = {x: node_config[x].value for x in node_config}
@ -222,7 +180,7 @@ class CoreClient:
# get emane config # get emane config
response = self.client.get_emane_config(self.session_id) response = self.client.get_emane_config(self.session_id)
logging.info("emane config: %s", response) logging.debug("emane config: %s", response)
self.emane_config = response.config self.emane_config = response.config
# get emane model config # get emane model config
@ -239,7 +197,7 @@ class CoreClient:
self.reusable.append(i) self.reusable.append(i)
# draw session # draw session
self.app.canvas.canvas_reset_and_redraw(session) self.app.canvas.reset_and_redraw(session)
# draw tool bar appropritate with session state # draw tool bar appropritate with session state
if self.is_runtime(): if self.is_runtime():
@ -343,8 +301,8 @@ class CoreClient:
logging.info("delete links %s", response) logging.info("delete links %s", response)
def start_session(self): def start_session(self):
nodes = self.get_nodes_proto() nodes = [x.core_node for x in self.canvas_nodes.values()]
links = self.get_links_proto() links = list(self.links.values())
wlan_configs = self.get_wlan_configs_proto() wlan_configs = self.get_wlan_configs_proto()
mobility_configs = self.get_mobility_configs_proto() mobility_configs = self.get_mobility_configs_proto()
emane_model_configs = self.get_emane_model_configs_proto() emane_model_configs = self.get_emane_model_configs_proto()
@ -374,23 +332,6 @@ class CoreClient:
response = self.client.stop_session(session_id=self.session_id) response = self.client.stop_session(session_id=self.session_id)
logging.debug("coregrpc.py Stop session, result: %s", response.result) logging.debug("coregrpc.py Stop session, result: %s", response.result)
# # TODO no need, might get rid of this
# def add_link(self, id1, id2, type1, type2, edge):
# """
# Grpc client request add link
#
# :param int session_id: session id
# :param int id1: node 1 core id
# :param core_pb2.NodeType type1: node 1 core node type
# :param int id2: node 2 core id
# :param core_pb2.NodeType type2: node 2 core node type
# :return: nothing
# """
# if1 = self.create_interface(type1, edge.interface_1)
# if2 = self.create_interface(type2, edge.interface_2)
# response = self.client.add_link(self.session_id, id1, id2, if1, if2)
# logging.info("created link: %s", response)
def launch_terminal(self, node_id): def launch_terminal(self, node_id):
response = self.client.get_node_terminal(self.session_id, node_id) response = self.client.get_node_terminal(self.session_id, node_id)
logging.info("get terminal %s", response.terminal) logging.info("get terminal %s", response.terminal)
@ -448,8 +389,10 @@ class CoreClient:
:return: nothing :return: nothing
""" """
node_protos = self.get_nodes_proto()
link_protos = self.get_links_proto() node_protos = [x.core_node for x in self.canvas_nodes.values()]
link_protos = list(self.links.values())
self.client.set_session_state(self.session_id, core_pb2.SessionState.DEFINITION)
for node_proto in node_protos: for node_proto in node_protos:
if node_proto.id not in self.created_nodes: if node_proto.id not in self.created_nodes:
response = self.client.add_node(self.session_id, node_proto) response = self.client.add_node(self.session_id, node_proto)
@ -482,17 +425,6 @@ class CoreClient:
logging.debug("Close grpc") logging.debug("Close grpc")
self.client.close() self.client.close()
def peek_id(self):
"""
Peek the next id to be used
:return: nothing
"""
if len(self.reusable) == 0:
return self.id
else:
return self.reusable[0]
def get_id(self): def get_id(self):
""" """
Get the next node id as well as update id status and reusable ids Get the next node id as well as update id status and reusable ids
@ -510,106 +442,91 @@ class CoreClient:
def is_model_node(self, name): def is_model_node(self, name):
return name in DEFAULT_NODES or name in self.custom_nodes return name in DEFAULT_NODES or name in self.custom_nodes
def add_graph_node(self, session_id, canvas_id, x, y, name): def create_node(self, x, y, node_type, model):
""" """
Add node, with information filled in, to grpc manager Add node, with information filled in, to grpc manager
:param int session_id: session id
:param int canvas_id: node's canvas id
:param int x: x coord :param int x: x coord
:param int y: y coord :param int y: y coord
:param str name: node type :param core_pb2.NodeType node_type: node type
:param str model: node model
:return: nothing :return: nothing
""" """
node_type = None node_id = self.get_id()
node_model = None position = core_pb2.Position(x=x, y=y)
if name in NETWORK_NODES: node = core_pb2.Node(
if name == "switch": id=node_id,
node_type = core_pb2.NodeType.SWITCH type=node_type,
elif name == "hub": name=f"n{node_id}",
node_type = core_pb2.NodeType.HUB model=model,
elif name == "wlan": position=position,
node_type = core_pb2.NodeType.WIRELESS_LAN )
elif name == "rj45":
node_type = core_pb2.NodeType.RJ45
elif name == "emane":
node_type = core_pb2.NodeType.EMANE
elif name == "tunnel":
node_type = core_pb2.NodeType.TUNNEL
elif name == "emane":
node_type = core_pb2.NodeType.EMANE
elif self.is_model_node(name):
node_type = core_pb2.NodeType.DEFAULT
node_model = name
else:
logging.error("invalid node name: %s", name)
nid = self.get_id()
create_node = Node(session_id, nid, node_type, node_model, x, y, name)
# set default configuration for wireless node # set default configuration for wireless node
self.wlanconfig_management.set_default_config(node_type, nid) self.wlanconfig_management.set_default_config(node_type, node_id)
self.mobilityconfig_management.set_default_configuration(node_type, nid) self.mobilityconfig_management.set_default_configuration(node_type, node_id)
# set default emane configuration for emane node # set default emane configuration for emane node
if node_type == core_pb2.NodeType.EMANE: if node_type == core_pb2.NodeType.EMANE:
self.emaneconfig_management.set_default_config(nid) self.emaneconfig_management.set_default_config(node_id)
# set default service configurations # set default service configurations
if node_type == core_pb2.NodeType.DEFAULT: if node_type == core_pb2.NodeType.DEFAULT:
self.serviceconfig_manager.node_default_services_configuration( self.serviceconfig_manager.node_default_services_configuration(
node_id=nid, node_model=node_model node_id=node_id, node_model=model
) )
self.nodes[canvas_id] = create_node
self.core_mapping.map_core_id_to_canvas_id(nid, canvas_id)
logging.debug( logging.debug(
"Adding node to core.. session id: %s, coords: (%s, %s), name: %s", "adding node to core session: %s, coords: (%s, %s), name: %s",
session_id, self.session_id,
x, x,
y, y,
name, node.name,
) )
return node
def delete_wanted_graph_nodes(self, canvas_ids, tokens): def delete_wanted_graph_nodes(self, node_ids, edge_tokens):
""" """
remove the nodes selected by the user and anything related to that node remove the nodes selected by the user and anything related to that node
such as link, configurations, interfaces such as link, configurations, interfaces
:param list(int) canvas_ids: list of canvas node ids :param list[int] node_ids: list of nodes to delete
:param list edge_tokens: list of edges to delete
:return: nothing :return: nothing
""" """
# keep reference to the core ids
core_node_ids = [self.nodes[x].node_id for x in canvas_ids]
node_interface_pairs = []
# delete the nodes # delete the nodes
for i in canvas_ids: for node_id in node_ids:
try: try:
n = self.nodes.pop(i) del self.canvas_nodes[node_id]
self.reusable.append(n.node_id) self.reusable.append(node_id)
except KeyError: except KeyError:
logging.error("coreclient.py INVALID NODE CANVAS ID") logging.error("invalid canvas id: %s", node_id)
self.reusable.sort() self.reusable.sort()
# delete the edges and interfaces # delete the edges and interfaces
for i in tokens: node_interface_pairs = []
for i in edge_tokens:
try: try:
e = self.edges.pop(i) link = self.links.pop(i)
if e.interface_1 is not None: if link.interface_one is not None:
node_interface_pairs.append(tuple([e.id1, e.interface_1.id])) node_interface_pairs.append(
if e.interface_2 is not None: (link.node_one_id, link.interface_one.id)
node_interface_pairs.append(tuple([e.id2, e.interface_2.id])) )
if link.interface_two is not None:
node_interface_pairs.append(
(link.node_two_id, link.interface_two.id)
)
except KeyError: except KeyError:
logging.error("coreclient.py invalid edge token ") logging.error("coreclient.py invalid edge token ")
# delete global emane config if there no longer exist any emane cloud # delete global emane config if there no longer exist any emane cloud
if core_pb2.NodeType.EMANE not in [x.type for x in self.nodes.values()]: # TODO: should not need to worry about this
node_types = [x.core_node.type for x in self.canvas_nodes.values()]
if core_pb2.NodeType.EMANE not in node_types:
self.emane_config = None self.emane_config = None
# delete any mobility configuration, wlan configuration # delete any mobility configuration, wlan configuration
for i in core_node_ids: for i in node_ids:
if i in self.mobilityconfig_management.configurations: if i in self.mobilityconfig_management.configurations:
self.mobilityconfig_management.configurations.pop(i) self.mobilityconfig_management.configurations.pop(i)
if i in self.wlanconfig_management.configurations: if i in self.wlanconfig_management.configurations:
@ -619,214 +536,82 @@ class CoreClient:
for i in node_interface_pairs: for i in node_interface_pairs:
if i in self.emaneconfig_management.configurations: if i in self.emaneconfig_management.configurations:
self.emaneconfig_management.configurations.pop(i) self.emaneconfig_management.configurations.pop(i)
for i in core_node_ids: for i in node_ids:
if tuple([i, None]) in self.emaneconfig_management.configurations: if tuple([i, None]) in self.emaneconfig_management.configurations:
self.emaneconfig_management.configurations.pop(tuple([i, None])) self.emaneconfig_management.configurations.pop(tuple([i, None]))
def add_preexisting_node(self, canvas_node, session_id, core_node, name): def create_interface(self, canvas_node):
""" interface = None
Add preexisting nodes to grpc manager core_node = canvas_node.core_node
if self.is_model_node(core_node.model):
:param str name: node_type ifid = len(canvas_node.interfaces)
:param core_pb2.Node core_node: core node grpc message name = f"eth{ifid}"
:param coretk.graph.CanvasNode canvas_node: canvas node
:param int session_id: session id
:return: nothing
"""
# update the next available id
core_id = core_node.id
if self.id is None or core_id >= self.id:
self.id = core_id + 1
self.preexisting.add(core_id)
n = Node(
session_id,
core_id,
core_node.type,
core_node.model,
canvas_node.x_coord,
canvas_node.y_coord,
name,
)
self.nodes[canvas_node.id] = n
def update_node_location(self, canvas_id, new_x, new_y):
"""
update node
:param int canvas_id: canvas id of that node
:param int new_x: new x coord
:param int new_y: new y coord
:return: nothing
"""
self.nodes[canvas_id].x = new_x
self.nodes[canvas_id].y = new_y
def update_reusable_id(self):
"""
Update available id for reuse
:return: nothing
"""
if len(self.preexisting) > 0:
for i in range(1, self.id):
if i not in self.preexisting:
self.reusable.append(i)
self.preexisting.clear()
logging.debug("Next id: %s, Reusable: %s", self.id, self.reusable)
def create_interface(self, node_type, gui_interface):
"""
create a protobuf interface given the interface object stored by the programmer
:param core_bp2.NodeType type: node type
:param coretk.interface.Interface gui_interface: the programmer's interface object
:rtype: core_bp2.Interface
:return: protobuf interface object
"""
if node_type != core_pb2.NodeType.DEFAULT:
return None
else:
interface = core_pb2.Interface( interface = core_pb2.Interface(
id=gui_interface.id, id=ifid,
name=gui_interface.name, name=name,
mac=gui_interface.mac, ip4=str(self.interfaces_manager.get_address()),
ip4=gui_interface.ipv4, ip4mask=24,
ip4mask=gui_interface.ip4prefix,
) )
logging.debug("create interface: %s", interface) canvas_node.interfaces.append(interface)
return interface
def create_edge_interface(self, edge, src_canvas_id, dst_canvas_id):
"""
Create the interface for the two end of an edge, add a copy to node's interfaces
:param coretk.coreclient.Edge edge: edge to add interfaces to
:param int src_canvas_id: canvas id for the source node
:param int dst_canvas_id: canvas id for the destination node
:return: nothing
"""
src_interface = None
dst_interface = None
print("create interface")
self.interfaces_manager.new_subnet()
src_node = self.nodes[src_canvas_id]
if self.is_model_node(src_node.model):
ifid = len(src_node.interfaces)
name = "eth" + str(ifid)
src_interface = Interface(
name=name, ifid=ifid, ipv4=str(self.interfaces_manager.get_address())
)
self.nodes[src_canvas_id].interfaces.append(src_interface)
logging.debug( logging.debug(
"Create source interface 1... IP: %s, name: %s", "create node(%s) interface IPv4: %s, name: %s",
src_interface.ipv4, core_node.name,
src_interface.name, interface.ip4,
interface.name,
) )
return interface
dst_node = self.nodes[dst_canvas_id] def create_link(self, token, canvas_node_one, canvas_node_two):
if self.is_model_node(dst_node.model):
ifid = len(dst_node.interfaces)
name = "eth" + str(ifid)
dst_interface = Interface(
name=name, ifid=ifid, ipv4=str(self.interfaces_manager.get_address())
)
self.nodes[dst_canvas_id].interfaces.append(dst_interface)
logging.debug(
"Create destination interface... IP: %s, name: %s",
dst_interface.ipv4,
dst_interface.name,
)
edge.interface_1 = src_interface
edge.interface_2 = dst_interface
return src_interface, dst_interface
def add_edge(self, session_id, token, canvas_id_1, canvas_id_2):
""" """
Add an edge to grpc manager Create core link for a pair of canvas nodes, with token referencing
the canvas edge.
:param int session_id: core session id
:param tuple(int, int) token: edge's identification in the canvas :param tuple(int, int) token: edge's identification in the canvas
:param int canvas_id_1: canvas id of source node :param canvas_node_one: canvas node one
:param int canvas_id_2: canvas_id of destination node :param canvas_node_two: canvas node two
:return: nothing :return: nothing
""" """
node_one = self.nodes[canvas_id_1] node_one = canvas_node_one.core_node
node_two = self.nodes[canvas_id_2] node_two = canvas_node_two.core_node
if canvas_id_1 in self.nodes and canvas_id_2 in self.nodes:
edge = Edge(
session_id,
node_one.node_id,
node_one.type,
node_two.node_id,
node_two.type,
)
self.edges[token] = edge
src_interface, dst_interface = self.create_edge_interface(
edge, canvas_id_1, canvas_id_2
)
node_one_id = node_one.node_id
node_two_id = node_two.node_id
# provide a way to get an edge from a core node and an interface id # create interfaces
if src_interface is not None: self.interfaces_manager.new_subnet()
self.core_mapping.map_node_and_interface_to_canvas_edge( interface_one = self.create_interface(canvas_node_one)
node_one_id, src_interface.id, token if interface_one is not None:
self.interface_to_edge[(node_one.id, interface_one.id)] = token
interface_two = self.create_interface(canvas_node_two)
if interface_two is not None:
self.interface_to_edge[(node_two.id, interface_two.id)] = token
# emane setup
# TODO: determine if this is needed
if (
node_one.type == core_pb2.NodeType.EMANE
and node_two.type == core_pb2.NodeType.DEFAULT
):
if node_two.model == "mdr":
self.emaneconfig_management.set_default_for_mdr(
node_one.node_id, node_two.node_id, interface_two.id
)
elif (
node_two.type == core_pb2.NodeType.EMANE
and node_one.type == core_pb2.NodeType.DEFAULT
):
if node_one.model == "mdr":
self.emaneconfig_management.set_default_for_mdr(
node_two.node_id, node_one.node_id, interface_one.id
) )
if dst_interface is not None: link = core_pb2.Link(
self.core_mapping.map_node_and_interface_to_canvas_edge( type=core_pb2.LinkType.WIRED,
node_two_id, dst_interface.id, token node_one_id=node_one.id,
) node_two_id=node_two.id,
interface_one=interface_one,
if ( interface_two=interface_two,
node_one.type == core_pb2.NodeType.EMANE )
and node_two.type == core_pb2.NodeType.DEFAULT self.links[token] = link
): return link
if node_two.model == "mdr":
self.emaneconfig_management.set_default_for_mdr(
node_one.node_id, node_two.node_id, dst_interface.id
)
elif (
node_two.type == core_pb2.NodeType.EMANE
and node_one.type == core_pb2.NodeType.DEFAULT
):
if node_one.model == "mdr":
self.emaneconfig_management.set_default_for_mdr(
node_two.node_id, node_one.node_id, src_interface.id
)
else:
logging.error("grpcmanagement.py INVALID CANVAS NODE ID")
def get_nodes_proto(self):
nodes = []
for node in self.nodes.values():
pos = core_pb2.Position(x=int(node.x), y=int(node.y))
proto_node = core_pb2.Node(
id=node.node_id, type=node.type, position=pos, model=node.model
)
nodes.append(proto_node)
return nodes
def get_links_proto(self):
links = []
for edge in self.edges.values():
interface_one = self.create_interface(edge.type1, edge.interface_1)
interface_two = self.create_interface(edge.type2, edge.interface_2)
link = core_pb2.Link(
node_one_id=edge.id1,
node_two_id=edge.id2,
type=core_pb2.LinkType.WIRED,
interface_one=interface_one,
interface_two=interface_two,
)
links.append(link)
return links
def get_wlan_configs_proto(self): def get_wlan_configs_proto(self):
configs = [] configs = []

View file

@ -1,34 +0,0 @@
"""
provide mapping from core to canvas
"""
import logging
class CoreToCanvasMapping:
def __init__(self):
self.core_id_to_canvas_id = {}
self.core_node_and_interface_to_canvas_edge = {}
def map_node_and_interface_to_canvas_edge(self, nid, iid, edge_token):
self.core_node_and_interface_to_canvas_edge[tuple([nid, iid])] = edge_token
def get_token_from_node_and_interface(self, nid, iid):
key = tuple([nid, iid])
if key in self.core_node_and_interface_to_canvas_edge:
return self.core_node_and_interface_to_canvas_edge[key]
else:
logging.error("invalid key")
return None
def map_core_id_to_canvas_id(self, core_nid, canvas_nid):
if core_nid not in self.core_id_to_canvas_id:
self.core_id_to_canvas_id[core_nid] = canvas_nid
else:
logging.debug("key already existed")
def get_canvas_id_from_core_id(self, core_id):
if core_id in self.core_id_to_canvas_id:
return self.core_id_to_canvas_id[core_id]
else:
logging.debug("invalid key")
return None

View file

@ -21,7 +21,7 @@ class NodeConfigDialog(Dialog):
self.image = canvas_node.image self.image = canvas_node.image
self.image_button = None self.image_button = None
self.name = tk.StringVar(value=canvas_node.name) self.name = tk.StringVar(value=canvas_node.name)
self.type = tk.StringVar(value=canvas_node.node_type) self.type = tk.StringVar(value=canvas_node.core_node.model)
self.server = tk.StringVar() self.server = tk.StringVar()
self.draw() self.draw()

View file

@ -13,14 +13,13 @@ class NodeService(Dialog):
def __init__(self, master, app, canvas_node, services=None): def __init__(self, master, app, canvas_node, services=None):
super().__init__(master, app, "Node Services", modal=True) super().__init__(master, app, "Node Services", modal=True)
self.canvas_node = canvas_node self.canvas_node = canvas_node
self.node_id = canvas_node.core_node.id
self.groups = None self.groups = None
self.services = None self.services = None
self.current = None self.current = None
if services is None: if services is None:
services = set( services = set(
app.core.serviceconfig_manager.configurations[ app.core.serviceconfig_manager.configurations[self.node_id].keys()
canvas_node.core_id
].keys()
) )
self.current_services = services self.current_services = services
self.draw() self.draw()

View file

@ -15,7 +15,7 @@ class ServiceConfiguration(Dialog):
super().__init__(master, app, f"{service_name} service", modal=True) super().__init__(master, app, f"{service_name} service", modal=True)
self.app = app self.app = app
self.canvas_node = canvas_node self.canvas_node = canvas_node
self.node_id = canvas_node.core_id self.node_id = canvas_node.core_node.id
self.service_name = service_name self.service_name = service_name
self.radiovar = tk.IntVar() self.radiovar = tk.IntVar()
self.radiovar.set(2) self.radiovar.set(2)
@ -73,22 +73,15 @@ class ServiceConfiguration(Dialog):
self.validation_mode = service_config.validation_mode self.validation_mode = service_config.validation_mode
self.validation_time = service_config.validation_timer self.validation_time = service_config.validation_timer
self.original_service_files = { self.original_service_files = {
x: self.app.core.get_node_service_file( x: self.app.core.get_node_service_file(self.node_id, self.service_name, x)
self.canvas_node.core_id, self.service_name, x
)
for x in self.filenames for x in self.filenames
} }
self.temp_service_files = { self.temp_service_files = {
x: self.original_service_files[x] for x in self.original_service_files x: self.original_service_files[x] for x in self.original_service_files
} }
configs = self.app.core.servicefileconfig_manager.configurations configs = self.app.core.servicefileconfig_manager.configurations
if ( if self.node_id in configs and self.service_name in configs[self.node_id]:
self.canvas_node.core_id in configs for file, data in configs[self.node_id][self.service_name].items():
and self.service_name in configs[self.canvas_node.core_id]
):
for file, data in configs[self.canvas_node.core_id][
self.service_name
].items():
self.temp_service_files[file] = data self.temp_service_files[file] = data
def draw(self): def draw(self):
@ -371,7 +364,7 @@ class ServiceConfiguration(Dialog):
shutdown_commands = self.shutdown_commands_listbox.get(0, "end") shutdown_commands = self.shutdown_commands_listbox.get(0, "end")
validate_commands = self.validate_commands_listbox.get(0, "end") validate_commands = self.validate_commands_listbox.get(0, "end")
self.app.core.serviceconfig_manager.node_service_custom_configuration( self.app.core.serviceconfig_manager.node_service_custom_configuration(
self.canvas_node.core_id, self.node_id,
self.service_name, self.service_name,
startup_commands, startup_commands,
validate_commands, validate_commands,
@ -379,16 +372,10 @@ class ServiceConfiguration(Dialog):
) )
for file in self.modified_files: for file in self.modified_files:
self.app.core.servicefileconfig_manager.set_custom_service_file_config( self.app.core.servicefileconfig_manager.set_custom_service_file_config(
self.canvas_node.core_id, self.node_id, self.service_name, file, self.temp_service_files[file]
self.service_name,
file,
self.temp_service_files[file],
) )
self.app.core.set_node_service_file( self.app.core.set_node_service_file(
self.canvas_node.core_id, self.node_id, self.service_name, file, self.temp_service_files[file]
self.service_name,
file,
self.temp_service_files[file],
) )
self.destroy() self.destroy()

View file

@ -9,7 +9,6 @@ from coretk.canvasaction import CanvasAction
from coretk.canvastooltip import CanvasTooltip from coretk.canvastooltip import CanvasTooltip
from coretk.graph_helper import GraphHelper, WlanAntennaManager from coretk.graph_helper import GraphHelper, WlanAntennaManager
from coretk.images import Images from coretk.images import Images
from coretk.interface import Interface
from coretk.linkinfo import LinkInfo, Throughput from coretk.linkinfo import LinkInfo, Throughput
from coretk.nodedelete import CanvasComponentManagement from coretk.nodedelete import CanvasComponentManagement
from coretk.wirelessconnection import WirelessConnection from coretk.wirelessconnection import WirelessConnection
@ -31,12 +30,6 @@ class ScaleOption(enum.Enum):
TILED = 4 TILED = 4
CORE_NODES = ["router"]
CORE_WIRED_NETWORK_NODES = []
CORE_WIRELESS_NODE = ["wlan"]
CORE_EMANE = ["emane"]
class CanvasGraph(tk.Canvas): class CanvasGraph(tk.Canvas):
def __init__(self, master, core, cnf=None, **kwargs): def __init__(self, master, core, cnf=None, **kwargs):
if cnf is None: if cnf is None:
@ -45,7 +38,8 @@ class CanvasGraph(tk.Canvas):
super().__init__(master, cnf, **kwargs) super().__init__(master, cnf, **kwargs)
self.mode = GraphMode.SELECT self.mode = GraphMode.SELECT
self.draw_node_image = None self.draw_node_image = None
self.draw_node_name = None self.draw_node_type = None
self.draw_node_model = None
self.selected = None self.selected = None
self.node_context = None self.node_context = None
self.nodes = {} self.nodes = {}
@ -89,7 +83,7 @@ class CanvasGraph(tk.Canvas):
self.node_context.add_command(label="Hide") self.node_context.add_command(label="Hide")
self.node_context.add_command(label="Services") self.node_context.add_command(label="Services")
def canvas_reset_and_redraw(self, session): def reset_and_redraw(self, session):
""" """
Reset the private variables CanvasGraph object, redraw nodes given the new grpc Reset the private variables CanvasGraph object, redraw nodes given the new grpc
client. client.
@ -103,13 +97,14 @@ class CanvasGraph(tk.Canvas):
# set the private variables to default value # set the private variables to default value
self.mode = GraphMode.SELECT self.mode = GraphMode.SELECT
self.draw_node_image = None self.draw_node_image = None
self.draw_node_name = None self.draw_node_type = None
self.draw_node_model = None
self.selected = None self.selected = None
self.node_context = None self.node_context = None
self.nodes.clear() self.nodes.clear()
self.edges.clear() self.edges.clear()
self.drawing_edge = None self.drawing_edge = None
self.draw_existing_component(session) self.draw_session(session)
def setup_bindings(self): def setup_bindings(self):
""" """
@ -149,95 +144,71 @@ class CanvasGraph(tk.Canvas):
self.tag_lower("gridline") self.tag_lower("gridline")
self.tag_lower(self.grid) self.tag_lower(self.grid)
def draw_existing_component(self, session): def draw_session(self, session):
""" """
Draw existing node and update the information in grpc manager to match Draw existing session.
:return: nothing :return: nothing
""" """
core_id_to_canvas_id = {} # draw existing nodes
# redraw existing nodes for core_node in session.nodes:
for node in session.nodes:
# peer to peer node is not drawn on the GUI # peer to peer node is not drawn on the GUI
if node.type != core_pb2.NodeType.PEER_TO_PEER: if core_node.type == core_pb2.NodeType.PEER_TO_PEER:
# draw nodes on the canvas continue
image, name = Images.node_icon(node.type, node.model)
n = CanvasNode(
node.position.x, node.position.y, image, name, self.master, node.id
)
self.nodes[n.id] = n
core_id_to_canvas_id[node.id] = n.id
# store the node in grpc manager # draw nodes on the canvas
self.core.add_preexisting_node(n, session.id, node, name) image = Images.node_icon(core_node.type, core_node.model)
position = core_node.position
node = CanvasNode(position.x, position.y, image, self.master, core_node)
self.nodes[node.id] = node
self.core.canvas_nodes[core_node.id] = node
# draw existing links # draw existing links
for link in session.links: for link in session.links:
n1 = self.nodes[core_id_to_canvas_id[link.node_one_id]] canvas_node_one = self.core.canvas_nodes[link.node_one_id]
n2 = self.nodes[core_id_to_canvas_id[link.node_two_id]] canvas_node_two = self.core.canvas_nodes[link.node_two_id]
if link.type == core_pb2.LinkType.WIRED: is_wired = link.type == core_pb2.LinkType.WIRED
e = CanvasEdge( edge = CanvasEdge(
n1.x_coord, canvas_node_one.x_coord,
n1.y_coord, canvas_node_one.y_coord,
n2.x_coord, canvas_node_two.x_coord,
n2.y_coord, canvas_node_two.y_coord,
n1.id, canvas_node_one.id,
self, self,
is_wired=True, is_wired=is_wired,
) )
elif link.type == core_pb2.LinkType.WIRELESS: edge.token = tuple(sorted((canvas_node_one.id, canvas_node_two.id)))
e = CanvasEdge( edge.dst = canvas_node_two.id
n1.x_coord, canvas_node_one.edges.add(edge)
n1.y_coord, canvas_node_two.edges.add(edge)
n2.x_coord, self.edges[edge.token] = edge
n2.y_coord, self.core.links[edge.token] = link
n1.id, self.helper.redraw_antenna(link, canvas_node_one, canvas_node_two)
self,
is_wired=False,
)
edge_token = tuple(sorted((n1.id, n2.id)))
e.token = edge_token
e.dst = n2.id
n1.edges.add(e)
n2.edges.add(e)
self.edges[e.token] = e
self.core.add_edge(session.id, e.token, n1.id, n2.id)
self.helper.redraw_antenna(link, n1, n2)
# TODO add back the link info to grpc manager also redraw # TODO add back the link info to grpc manager also redraw
grpc_if1 = link.interface_one # TODO will include throughput and ipv6 in the future
grpc_if2 = link.interface_two interface_one = link.interface_one
interface_two = link.interface_two
ip4_src = None ip4_src = None
ip4_dst = None ip4_dst = None
ip6_src = None ip6_src = None
ip6_dst = None ip6_dst = None
if grpc_if1 is not None: if interface_one is not None:
ip4_src = grpc_if1.ip4 ip4_src = interface_one.ip4
ip6_src = grpc_if1.ip6 ip6_src = interface_one.ip6
if grpc_if2 is not None: if interface_two is not None:
ip4_dst = grpc_if2.ip4 ip4_dst = interface_two.ip4
ip6_dst = grpc_if2.ip6 ip6_dst = interface_two.ip6
e.link_info = LinkInfo( edge.link_info = LinkInfo(
canvas=self, canvas=self,
edge=e, edge=edge,
ip4_src=ip4_src, ip4_src=ip4_src,
ip6_src=ip6_src, ip6_src=ip6_src,
ip4_dst=ip4_dst, ip4_dst=ip4_dst,
ip6_dst=ip6_dst, ip6_dst=ip6_dst,
) )
canvas_node_one.interfaces.append(interface_one)
# TODO will include throughput and ipv6 in the future canvas_node_two.interfaces.append(interface_two)
if1 = Interface(grpc_if1.name, grpc_if1.ip4, ifid=grpc_if1.id)
if2 = Interface(grpc_if2.name, grpc_if2.ip4, ifid=grpc_if2.id)
self.core.edges[e.token].interface_1 = if1
self.core.edges[e.token].interface_2 = if2
self.core.nodes[core_id_to_canvas_id[link.node_one_id]].interfaces.append(
if1
)
self.core.nodes[core_id_to_canvas_id[link.node_two_id]].interfaces.append(
if2
)
# raise the nodes so they on top of the links # raise the nodes so they on top of the links
self.tag_raise("node") self.tag_raise("node")
@ -296,7 +267,13 @@ class CanvasGraph(tk.Canvas):
self.handle_edge_release(event) self.handle_edge_release(event)
elif self.mode == GraphMode.NODE: elif self.mode == GraphMode.NODE:
x, y = self.canvas_xy(event) x, y = self.canvas_xy(event)
self.add_node(x, y, self.draw_node_image, self.draw_node_name) self.add_node(
x,
y,
self.draw_node_image,
self.draw_node_type,
self.draw_node_model,
)
elif self.mode == GraphMode.PICKNODE: elif self.mode == GraphMode.PICKNODE:
self.mode = GraphMode.NODE self.mode = GraphMode.NODE
@ -319,6 +296,7 @@ class CanvasGraph(tk.Canvas):
# edge dst is same as src, delete edge # edge dst is same as src, delete edge
if edge.src == self.selected: if edge.src == self.selected:
edge.delete() edge.delete()
return
# set dst node and snap edge to center # set dst node and snap edge to center
x, y = self.coords(self.selected) x, y = self.coords(self.selected)
@ -332,20 +310,17 @@ class CanvasGraph(tk.Canvas):
node_src.edges.add(edge) node_src.edges.add(edge)
node_dst = self.nodes[edge.dst] node_dst = self.nodes[edge.dst]
node_dst.edges.add(edge) node_dst.edges.add(edge)
link = self.core.create_link(edge.token, node_src, node_dst)
self.core.add_edge(
self.core.session_id, edge.token, node_src.id, node_dst.id
)
# draw link info on the edge # draw link info on the edge
if1 = self.core.edges[edge.token].interface_1
if2 = self.core.edges[edge.token].interface_2
ip4_and_prefix_1 = None ip4_and_prefix_1 = None
ip4_and_prefix_2 = None ip4_and_prefix_2 = None
if if1 is not None: if link.HasField("interface_one"):
ip4_and_prefix_1 = if1.ip4_and_prefix if1 = link.interface_one
if if2 is not None: ip4_and_prefix_1 = f"{if1.ip4}/{if1.ip4mask}"
ip4_and_prefix_2 = if2.ip4_and_prefix if link.HasField("interface_two"):
if2 = link.interface_two
ip4_and_prefix_2 = f"{if2.ip4}/{if2.ip4mask}"
edge.link_info = LinkInfo( edge.link_info = LinkInfo(
self, self,
edge, edge,
@ -410,8 +385,10 @@ class CanvasGraph(tk.Canvas):
) )
# delete nodes and link info stored in CanvasGraph object # delete nodes and link info stored in CanvasGraph object
node_ids = []
for nid in to_delete_nodes: for nid in to_delete_nodes:
self.nodes.pop(nid) canvas_node = self.nodes.pop(nid)
node_ids.append(canvas_node.core_node.id)
for token in to_delete_edge_tokens: for token in to_delete_edge_tokens:
self.edges.pop(token) self.edges.pop(token)
@ -425,15 +402,16 @@ class CanvasGraph(tk.Canvas):
self.nodes[nid].edges.remove(edge) self.nodes[nid].edges.remove(edge)
# delete the related data from core # delete the related data from core
self.core.delete_wanted_graph_nodes(to_delete_nodes, to_delete_edge_tokens) self.core.delete_wanted_graph_nodes(node_ids, to_delete_edge_tokens)
def add_node(self, x, y, image, node_name): def add_node(self, x, y, image, node_type, model):
plot_id = self.find_all()[0] plot_id = self.find_all()[0]
logging.info("add node event: %s - %s", plot_id, self.selected) logging.info("add node event: %s - %s", plot_id, self.selected)
if self.selected == plot_id: if self.selected == plot_id:
node = CanvasNode(x, y, image, node_name, self.master, self.core.peek_id()) core_node = self.core.create_node(int(x), int(y), node_type, model)
node = CanvasNode(x, y, image, self.master, core_node)
self.core.canvas_nodes[core_node.id] = node
self.nodes[node.id] = node self.nodes[node.id] = node
self.core.add_graph_node(self.core.session_id, node.id, x, y, node_name)
return node return node
def width_and_height(self): def width_and_height(self):
@ -500,7 +478,6 @@ class CanvasGraph(tk.Canvas):
""" """
scale image based on canvas dimension scale image based on canvas dimension
:param Image img: image object
:return: nothing :return: nothing
""" """
canvas_w, canvas_h = self.width_and_height() canvas_w, canvas_h = self.width_and_height()
@ -620,18 +597,17 @@ class CanvasEdge:
class CanvasNode: class CanvasNode:
def __init__(self, x, y, image, node_type, app, core_id): def __init__(self, x, y, image, app, core_node):
self.image = image self.image = image
self.node_type = node_type
self.app = app self.app = app
self.canvas = app.canvas self.canvas = app.canvas
self.id = self.canvas.create_image( self.id = self.canvas.create_image(
x, y, anchor=tk.CENTER, image=self.image, tags="node" x, y, anchor=tk.CENTER, image=self.image, tags="node"
) )
self.core_id = core_id self.core_node = core_node
self.name = core_node.name
self.x_coord = x self.x_coord = x
self.y_coord = y self.y_coord = y
self.name = f"N{self.core_id}"
self.text_id = self.canvas.create_text( self.text_id = self.canvas.create_text(
x, y + 20, text=self.name, tags="nodename" x, y + 20, text=self.name, tags="nodename"
) )
@ -647,6 +623,7 @@ class CanvasNode:
self.canvas.tag_bind(self.id, "<Leave>", self.on_leave) self.canvas.tag_bind(self.id, "<Leave>", self.on_leave)
self.edges = set() self.edges = set()
self.interfaces = []
self.wlans = [] self.wlans = []
self.moving = None self.moving = None
@ -654,7 +631,7 @@ class CanvasNode:
if self.app.core.is_runtime() and self.app.core.observer: if self.app.core.is_runtime() and self.app.core.observer:
self.tooltip.text.set("waiting...") self.tooltip.text.set("waiting...")
self.tooltip.on_enter(event) self.tooltip.on_enter(event)
output = self.app.core.run(self.core_id) output = self.app.core.run(self.core_node.id)
self.tooltip.text.set(output) self.tooltip.text.set(output)
def on_leave(self, event): def on_leave(self, event):
@ -664,23 +641,15 @@ class CanvasNode:
print("click") print("click")
def double_click(self, event): def double_click(self, event):
node_id = self.canvas.core.nodes[self.id].node_id if self.app.core.is_runtime():
state = self.canvas.core.get_session_state() self.canvas.core.launch_terminal(self.core_node.id)
if state == core_pb2.SessionState.RUNTIME:
self.canvas.core.launch_terminal(node_id)
else: else:
self.canvas.canvas_action.display_configuration(self) self.canvas.canvas_action.display_configuration(self)
# if self.node_type in CORE_NODES:
# self.canvas.canvas_action.node_to_show_config = self
# self.canvas.canvas_action.display_node_configuration()
# elif self.node_type in CORE_WIRED_NETWORK_NODES:
# return
# elif self.node_type in CORE_WIRELESS_NODE:
# return
# elif self
def update_coords(self): def update_coords(self):
self.x_coord, self.y_coord = self.canvas.coords(self.id) self.x_coord, self.y_coord = self.canvas.coords(self.id)
self.core_node.position.x = int(self.x_coord)
self.core_node.position.y = int(self.y_coord)
def click_press(self, event): def click_press(self, event):
logging.debug(f"node click press {self.name}: {event}") logging.debug(f"node click press {self.name}: {event}")
@ -691,7 +660,6 @@ class CanvasNode:
def click_release(self, event): def click_release(self, event):
logging.debug(f"node click release {self.name}: {event}") logging.debug(f"node click release {self.name}: {event}")
self.update_coords() self.update_coords()
self.canvas.core.update_node_location(self.id, self.x_coord, self.y_coord)
self.moving = None self.moving = None
def motion(self, event): def motion(self, event):
@ -711,7 +679,7 @@ class CanvasNode:
new_x, new_y = self.canvas.coords(self.id) new_x, new_y = self.canvas.coords(self.id)
if self.canvas.core.get_session_state() == core_pb2.SessionState.RUNTIME: if self.canvas.core.get_session_state() == core_pb2.SessionState.RUNTIME:
self.canvas.core.edit_node(self.core_id, int(new_x), int(new_y)) self.canvas.core.edit_node(self.core_node.id, int(new_x), int(new_y))
for edge in self.edges: for edge in self.edges:
x1, y1, x2, y2 = self.canvas.coords(edge.id) x1, y1, x2, y2 = self.canvas.coords(edge.id)

View file

@ -29,29 +29,31 @@ class GraphHelper:
self.canvas.delete(i) self.canvas.delete(i)
def draw_wireless_case(self, src_id, dst_id, edge): def draw_wireless_case(self, src_id, dst_id, edge):
src_node_name = self.canvas.nodes[src_id].node_type src_node_type = self.canvas.nodes[src_id].core_node.type
dst_node_name = self.canvas.nodes[dst_id].node_type dst_node_type = self.canvas.nodes[dst_id].core_node.type
is_src_wlan = src_node_type == core_pb2.NodeType.WIRELESS_LAN
if src_node_name == "wlan" or dst_node_name == "wlan": is_dst_wlan = dst_node_type == core_pb2.NodeType.WIRELESS_LAN
if is_src_wlan or is_dst_wlan:
self.canvas.itemconfig(edge.id, state=tk.HIDDEN) self.canvas.itemconfig(edge.id, state=tk.HIDDEN)
edge.wired = False edge.wired = False
if edge.token not in self.canvas.edges: if edge.token not in self.canvas.edges:
if src_node_name == "wlan" and dst_node_name == "wlan": if is_src_wlan and is_dst_wlan:
self.canvas.nodes[src_id].antenna_draw.add_antenna() self.canvas.nodes[src_id].antenna_draw.add_antenna()
elif src_node_name == "wlan": elif is_src_wlan:
self.canvas.nodes[dst_id].antenna_draw.add_antenna() self.canvas.nodes[dst_id].antenna_draw.add_antenna()
else: else:
self.canvas.nodes[src_id].antenna_draw.add_antenna() self.canvas.nodes[src_id].antenna_draw.add_antenna()
edge.wired = True edge.wired = True
def redraw_antenna(self, link, node_one, node_two): def redraw_antenna(self, link, node_one, node_two):
is_node_one_wlan = node_one.core_node.type == core_pb2.NodeType.WIRELESS_LAN
is_node_two_wlan = node_two.core_node.type == core_pb2.NodeType.WIRELESS_LAN
if link.type == core_pb2.LinkType.WIRELESS: if link.type == core_pb2.LinkType.WIRELESS:
if node_one.node_type == "wlan" and node_two.node_type == "wlan": if is_node_one_wlan and is_node_two_wlan:
node_one.antenna_draw.add_antenna() node_one.antenna_draw.add_antenna()
elif node_one.node_type == "wlan" and node_two.node_type != "wlan": elif is_node_one_wlan and not is_node_two_wlan:
node_two.antenna_draw.add_antenna() node_two.antenna_draw.add_antenna()
elif node_one.node_type != "wlan" and node_two.node_type == "wlan": elif not is_node_one_wlan and is_node_two_wlan:
node_one.antenna_draw.add_antenna() node_one.antenna_draw.add_antenna()
else: else:
logging.error( logging.error(
@ -122,91 +124,3 @@ class WlanAntennaManager:
""" """
for i in self.antennas: for i in self.antennas:
self.canvas.delete(i) self.canvas.delete(i)
# class WlanConnection:
# def __init__(self, canvas, grpc):
# """
# create in
# :param canvas:
# """
# self.canvas = canvas
# self.core_grpc = grpc
# self.throughput_on = False
# self.map_node_link = {}
# self.links = []
#
# def wireless_nodes(self):
# """
# retrieve all the wireless clouds in the canvas
#
# :return: list(coretk.graph.CanvasNode)
# """
# wireless_nodes = []
# for n in self.canvas.nodes.values():
# if n.node_type == "wlan":
# wireless_nodes.append(n)
# return wireless_nodes
#
# def draw_wireless_link(self, src, dst):
# """
# draw a line between 2 nodes that are connected to the same wireless cloud
#
# :param coretk.graph.CanvasNode src: source node
# :param coretk.graph.CanvasNode dst: destination node
# :return: nothing
# """
# cid = self.canvas.create_line(src.x_coord, src.y_coord, dst.x_coord, dst.y_coord, tags="wlanconnection")
# if src.id not in self.map_node_link:
# self.map_node_link[src.id] = []
# if dst.id not in self.map_node_link:
# self.map_node_link[dst.id] = []
# self.map_node_link[src.id].append(cid)
# self.map_node_link[dst.id].append(cid)
# self.links.append(cid)
#
# def subnet_wireless_connection(self, wlan_node):
# """
# retrieve all the non-wireless nodes connected to wireless_node and create line (represent wireless connection) between each pair of nodes
# :param coretk.grpah.CanvasNode wlan_node: wireless node
#
# :return: nothing
# """
# non_wlan_nodes = []
# for e in wlan_node.edges:
# src = self.canvas.nodes[e.src]
# dst = self.canvas.nodes[e.dst]
# if src.node_type == "wlan" and dst.node_type != "wlan":
# non_wlan_nodes.append(dst)
# elif src.node_type != "wlan" and dst.node_type == "wlan":
# non_wlan_nodes.append(src)
#
# size = len(non_wlan_nodes)
# for i in range(size):
# for j in range(i+1, size):
# self.draw_wireless_link(non_wlan_nodes[i], non_wlan_nodes[j])
#
# def session_wireless_connection(self):
# """
# draw all the wireless connection in the canvas
#
# :return: nothing
# """
# wlan_nodes = self.wireless_nodes()
# for n in wlan_nodes:
# self.subnet_wireless_connection(n)
#
# def show_links(self):
# """
# show all the links
# """
# for l in self.links:
# self.canvas.itemconfig(l, state=tk.NORMAL)
#
# def hide_links(self):
# """
# hide all the links
# :return:
# """
# for l in self.links:
# self.canvas.itemconfig(l, state=tk.HIDDEN)

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

BIN
coretk/coretk/icons/lxc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

View file

@ -31,7 +31,7 @@ class Images:
return cls.create(file_path, width, height) return cls.create(file_path, width, height)
@classmethod @classmethod
def get_custom(cls, name, width, height): def get_custom(cls, name, width, height=None):
file_path = cls.images[name] file_path = cls.images[name]
return cls.create(file_path, width, height) return cls.create(file_path, width, height)
@ -41,52 +41,38 @@ class Images:
Retrieve image based on type and model Retrieve image based on type and model
:param core_pb2.NodeType node_type: core node type :param core_pb2.NodeType node_type: core node type
:param string node_model: the node model :param string node_model: the node model
:return: core node icon
:rtype: tuple(PhotoImage, str) :rtype: PhotoImage
:return: the matching image and its name
""" """
image_enum = ImageEnum.ROUTER image_enum = ImageEnum.ROUTER
name = "unknown"
if node_type == core_pb2.NodeType.SWITCH: if node_type == core_pb2.NodeType.SWITCH:
image_enum = ImageEnum.SWITCH image_enum = ImageEnum.SWITCH
name = "switch"
elif node_type == core_pb2.NodeType.HUB: elif node_type == core_pb2.NodeType.HUB:
image_enum = ImageEnum.HUB image_enum = ImageEnum.HUB
name = "hub"
elif node_type == core_pb2.NodeType.WIRELESS_LAN: elif node_type == core_pb2.NodeType.WIRELESS_LAN:
image_enum = ImageEnum.WLAN image_enum = ImageEnum.WLAN
name = "wlan"
elif node_type == core_pb2.NodeType.EMANE: elif node_type == core_pb2.NodeType.EMANE:
image_enum = ImageEnum.EMANE image_enum = ImageEnum.EMANE
name = "emane"
elif node_type == core_pb2.NodeType.RJ45: elif node_type == core_pb2.NodeType.RJ45:
image_enum = ImageEnum.RJ45 image_enum = ImageEnum.RJ45
name = "rj45"
elif node_type == core_pb2.NodeType.TUNNEL: elif node_type == core_pb2.NodeType.TUNNEL:
image_enum = ImageEnum.TUNNEL image_enum = ImageEnum.TUNNEL
name = "tunnel"
elif node_type == core_pb2.NodeType.DEFAULT: elif node_type == core_pb2.NodeType.DEFAULT:
if node_model == "router": if node_model == "router":
image_enum = ImageEnum.ROUTER image_enum = ImageEnum.ROUTER
name = "router"
elif node_model == "host": elif node_model == "host":
image_enum = ImageEnum.HOST image_enum = ImageEnum.HOST
name = "host"
elif node_model == "PC": elif node_model == "PC":
image_enum = ImageEnum.PC image_enum = ImageEnum.PC
name = "PC"
elif node_model == "mdr": elif node_model == "mdr":
image_enum = ImageEnum.MDR image_enum = ImageEnum.MDR
name = "mdr"
elif node_model == "prouter": elif node_model == "prouter":
image_enum = ImageEnum.PROUTER image_enum = ImageEnum.PROUTER
name = "prouter"
else: else:
logging.error("invalid node model: %s", node_model) logging.error("invalid node model: %s", node_model)
else: else:
logging.error("invalid node type: %s", node_type) logging.error("invalid node type: %s", node_type)
return Images.get(image_enum, NODE_WIDTH)
return Images.get(image_enum, NODE_WIDTH), name
class ImageEnum(Enum): class ImageEnum(Enum):
@ -121,3 +107,5 @@ class ImageEnum(Enum):
FILEOPEN = "fileopen" FILEOPEN = "fileopen"
EDITDELETE = "edit-delete" EDITDELETE = "edit-delete"
ANTENNA = "antenna" ANTENNA = "antenna"
DOCKER = "docker"
LXC = "lxc"

View file

@ -1,35 +1,4 @@
import ipaddress import ipaddress
import random
class Interface:
def __init__(self, name, ipv4, ifid=None):
"""
Create an interface instance
:param str name: interface name
:param str ip4: IPv4
:param str mac: MAC address
:param int ifid: interface id
"""
self.name = name
self.ipv4 = ipv4
self.ip4prefix = 24
self.ip4_and_prefix = ipv4 + "/" + str(self.ip4prefix)
self.mac = self.random_mac_address()
self.id = ifid
def random_mac_address(self):
"""
create a random MAC address for an interface
:return: nothing
"""
return "02:00:00:%02x:%02x:%02x" % (
random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 225),
)
class SubnetAddresses: class SubnetAddresses:
@ -46,18 +15,13 @@ class SubnetAddresses:
class InterfaceManager: class InterfaceManager:
def __init__(self): def __init__(self):
# self.prefix = None
self.core_subnets = list( self.core_subnets = list(
ipaddress.ip_network("10.0.0.0/12").subnets(prefixlen_diff=12) ipaddress.ip_network("10.0.0.0/12").subnets(prefixlen_diff=12)
) )
self.subnet_index = 0 self.subnet_index = 0
self.address_index = 0 self.address_index = 0
# self.network = ipaddress.ip_network("10.0.0.0/24")
# self.addresses = list(self.network.hosts())
self.network = None self.network = None
self.addresses = None self.addresses = None
# self.start_interface_manager()
def start_interface_manager(self): def start_interface_manager(self):
self.subnet_index = 0 self.subnet_index = 0
@ -72,24 +36,10 @@ class InterfaceManager:
:return: :return:
""" """
# i = self.index
# self.address_index = self.index + 1
# return self.addresses[i]
ipaddr = self.addresses[self.address_index] ipaddr = self.addresses[self.address_index]
self.address_index = self.address_index + 1 self.address_index = self.address_index + 1
return ipaddr return ipaddr
def new_subnet(self): def new_subnet(self):
self.network = self.core_subnets[self.subnet_index] self.network = self.core_subnets[self.subnet_index]
# self.subnet_index = self.subnet_index + 1
self.addresses = list(self.network.hosts()) self.addresses = list(self.network.hosts())
# self.address_index = 0
# def new_subnet(self):
# """
# retrieve a new subnet
# :return:
# """
# if self.prefix is None:
# self.prefix =
# self.addresses = list(ipaddress.ip_network("10.0.0.0/24").hosts())

View file

@ -4,8 +4,6 @@ Link information, such as IPv4, IPv6 and throughput drawn in the canvas
import logging import logging
import math import math
WIRELESS_DEF = ["mdr", "wlan"]
class LinkInfo: class LinkInfo:
def __init__(self, canvas, edge, ip4_src, ip6_src, ip4_dst, ip6_dst): def __init__(self, canvas, edge, ip4_src, ip6_src, ip4_dst, ip6_dst):
@ -129,8 +127,7 @@ class Throughput:
nid = t.node_id nid = t.node_id
iid = t.interface_id iid = t.interface_id
tp = t.throughput tp = t.throughput
# token = self.grpc_manager.node_id_and_interface_to_edge_token[nid, iid] token = self.core.interface_to_edge[(nid, iid)]
token = self.core.core_mapping.get_token_from_node_and_interface(nid, iid)
print(token) print(token)
edge_id = self.canvas.edges[token].id edge_id = self.canvas.edges[token].id

View file

@ -3,6 +3,7 @@ import tkinter as tk
from functools import partial from functools import partial
from tkinter import ttk from tkinter import ttk
from core.api.grpc import core_pb2
from coretk.dialogs.customnodes import CustomNodesDialog from coretk.dialogs.customnodes import CustomNodesDialog
from coretk.graph import GraphMode from coretk.graph import GraphMode
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
@ -129,22 +130,32 @@ class Toolbar(ttk.Frame):
self.hide_pickers() self.hide_pickers()
self.node_picker = ttk.Frame(self.master) self.node_picker = ttk.Frame(self.master)
nodes = [ nodes = [
(ImageEnum.ROUTER, "router"), (ImageEnum.ROUTER, core_pb2.NodeType.DEFAULT, "router"),
(ImageEnum.HOST, "host"), (ImageEnum.HOST, core_pb2.NodeType.DEFAULT, "host"),
(ImageEnum.PC, "PC"), (ImageEnum.PC, core_pb2.NodeType.DEFAULT, "PC"),
(ImageEnum.MDR, "mdr"), (ImageEnum.MDR, core_pb2.NodeType.DEFAULT, "mdr"),
(ImageEnum.PROUTER, "prouter"), (ImageEnum.PROUTER, core_pb2.NodeType.DEFAULT, "prouter"),
(ImageEnum.DOCKER, core_pb2.NodeType.DOCKER, "Docker"),
(ImageEnum.LXC, core_pb2.NodeType.LXC, "LXC"),
] ]
# draw default nodes # draw default nodes
for image_enum, tooltip in nodes: for image_enum, node_type, model in nodes:
image = icon(image_enum) image = icon(image_enum)
func = partial(self.update_button, self.node_button, image, tooltip) func = partial(
self.create_picker_button(image, func, self.node_picker, tooltip) self.update_button, self.node_button, image, node_type, model
)
self.create_picker_button(image, func, self.node_picker, model)
# draw custom nodes # draw custom nodes
for name in sorted(self.app.core.custom_nodes): for name in sorted(self.app.core.custom_nodes):
custom_node = self.app.core.custom_nodes[name] custom_node = self.app.core.custom_nodes[name]
image = custom_node.image image = custom_node.image
func = partial(self.update_button, self.node_button, image, name) func = partial(
self.update_button,
self.node_button,
image,
core_pb2.NodeType.DEFAULT,
name,
)
self.create_picker_button(image, func, self.node_picker, name) self.create_picker_button(image, func, self.node_picker, name)
# draw edit node # draw edit node
image = icon(ImageEnum.EDITNODE) image = icon(ImageEnum.EDITNODE)
@ -216,14 +227,15 @@ class Toolbar(ttk.Frame):
dialog = CustomNodesDialog(self.app, self.app) dialog = CustomNodesDialog(self.app, self.app)
dialog.show() dialog.show()
def update_button(self, button, image, name): def update_button(self, button, image, node_type, model=None):
logging.info("update button(%s): %s", button, name) logging.info("update button(%s): %s", button, node_type)
self.hide_pickers() self.hide_pickers()
button.configure(image=image) button.configure(image=image)
button.image = image button.image = image
self.app.canvas.mode = GraphMode.NODE self.app.canvas.mode = GraphMode.NODE
self.app.canvas.draw_node_image = image self.app.canvas.draw_node_image = image
self.app.canvas.draw_node_name = name self.app.canvas.draw_node_type = node_type
self.app.canvas.draw_node_model = model
def hide_pickers(self): def hide_pickers(self):
logging.info("hiding pickers") logging.info("hiding pickers")
@ -260,18 +272,18 @@ class Toolbar(ttk.Frame):
self.hide_pickers() self.hide_pickers()
self.network_picker = ttk.Frame(self.master) self.network_picker = ttk.Frame(self.master)
nodes = [ nodes = [
(ImageEnum.HUB, "hub", "ethernet hub"), (ImageEnum.HUB, core_pb2.NodeType.HUB, "ethernet hub"),
(ImageEnum.SWITCH, "switch", "ethernet switch"), (ImageEnum.SWITCH, core_pb2.NodeType.SWITCH, "ethernet switch"),
(ImageEnum.WLAN, "wlan", "wireless LAN"), (ImageEnum.WLAN, core_pb2.NodeType.WIRELESS_LAN, "wireless LAN"),
(ImageEnum.EMANE, "emane", "EMANE"), (ImageEnum.EMANE, core_pb2.NodeType.EMANE, "EMANE"),
(ImageEnum.RJ45, "rj45", "rj45 physical interface tool"), (ImageEnum.RJ45, core_pb2.NodeType.RJ45, "rj45 physical interface tool"),
(ImageEnum.TUNNEL, "tunnel", "tunnel tool"), (ImageEnum.TUNNEL, core_pb2.NodeType.TUNNEL, "tunnel tool"),
] ]
for image_enum, name, tooltip in nodes: for image_enum, node_type, tooltip in nodes:
image = icon(image_enum) image = icon(image_enum)
self.create_picker_button( self.create_picker_button(
image, image,
partial(self.update_button, self.network_button, image, name), partial(self.update_button, self.network_button, image, node_type),
self.network_picker, self.network_picker,
tooltip, tooltip,
) )
@ -367,6 +379,7 @@ class Toolbar(ttk.Frame):
""" """
logging.debug("Click on STOP button ") logging.debug("Click on STOP button ")
self.app.core.stop_session() self.app.core.stop_session()
self.app.canvas.delete("wireless")
self.design_frame.tkraise() self.design_frame.tkraise()
def update_annotation(self, image): def update_annotation(self, image):

View file

@ -7,35 +7,31 @@ from core.api.grpc import core_pb2
class WirelessConnection: class WirelessConnection:
def __init__(self, canvas, core): def __init__(self, canvas, core):
self.canvas = canvas self.canvas = canvas
self.core_mapping = core.core_mapping self.core = core
# map a (node_one_id, node_two_id) to a wlan canvas id # map a (node_one_id, node_two_id) to a wlan canvas id
self.map = {} self.map = {}
def add_wlan_connection(self, node_one_id, node_two_id): def add_wlan_connection(self, node_one_id, node_two_id):
canvas_id_one = self.core_mapping.get_canvas_id_from_core_id(node_one_id) canvas_node_one = self.core.canvas_nodes[node_one_id]
canvas_id_two = self.core_mapping.get_canvas_id_from_core_id(node_two_id) canvas_node_two = self.core.canvas_nodes[node_two_id]
key = tuple(sorted((node_one_id, node_two_id))) key = tuple(sorted((node_one_id, node_two_id)))
if key not in self.map: if key not in self.map:
x1, y1 = self.canvas.coords(canvas_id_one) x1, y1 = self.canvas.coords(canvas_node_one.id)
x2, y2 = self.canvas.coords(canvas_id_two) x2, y2 = self.canvas.coords(canvas_node_two.id)
wlan_canvas_id = self.canvas.create_line( wlan_canvas_id = self.canvas.create_line(
x1, y1, x2, y2, fill="#009933", tags="wlan", width=1.5 x1, y1, x2, y2, fill="#009933", tags="wireless", width=1.5
) )
self.map[key] = wlan_canvas_id self.map[key] = wlan_canvas_id
self.canvas.nodes[canvas_id_one].wlans.append(wlan_canvas_id) canvas_node_one.wlans.append(wlan_canvas_id)
self.canvas.nodes[canvas_id_two].wlans.append(wlan_canvas_id) canvas_node_two.wlans.append(wlan_canvas_id)
def delete_wlan_connection(self, node_one_id, node_two_id): def delete_wlan_connection(self, node_one_id, node_two_id):
canvas_id_one = self.core_mapping.get_canvas_id_from_core_id(node_one_id) canvas_node_one = self.core.canvas_nodes[node_one_id]
canvas_id_two = self.core_mapping.get_canvas_id_from_core_id(node_two_id) canvas_node_two = self.core.canvas_nodes[node_two_id]
key = tuple(sorted((node_one_id, node_two_id))) key = tuple(sorted((node_one_id, node_two_id)))
wlan_canvas_id = self.map[key] wlan_canvas_id = self.map[key]
canvas_node_one.wlans.remove(wlan_canvas_id)
self.canvas.nodes[canvas_id_one].wlans.remove(wlan_canvas_id) canvas_node_two.wlans.remove(wlan_canvas_id)
self.canvas.nodes[canvas_id_two].wlans.remove(wlan_canvas_id)
self.canvas.delete(wlan_canvas_id) self.canvas.delete(wlan_canvas_id)
self.map.pop(key, None) self.map.pop(key, None)