some work on grpc add nodes and links, some work on query session, redraw nodes
This commit is contained in:
		
							parent
							
								
									cbd593eed6
								
							
						
					
					
						commit
						cb03aa261a
					
				
					 6 changed files with 387 additions and 137 deletions
				
			
		|  | @ -16,16 +16,20 @@ class Application(tk.Frame): | ||||||
|         self.setup_app() |         self.setup_app() | ||||||
|         self.menubar = None |         self.menubar = None | ||||||
|         self.canvas = None |         self.canvas = None | ||||||
|  | 
 | ||||||
|  |         # start grpc | ||||||
|         self.core_grpc = CoreGrpc() |         self.core_grpc = CoreGrpc() | ||||||
|  | 
 | ||||||
|         self.create_menu() |         self.create_menu() | ||||||
|         self.create_widgets() |         self.create_widgets() | ||||||
| 
 | 
 | ||||||
|     def load_images(self): |     def load_images(self): | ||||||
|  |         """ | ||||||
|  |         Load core images | ||||||
|  |         :return: | ||||||
|  |         """ | ||||||
|         images.load_core_images(Images) |         images.load_core_images(Images) | ||||||
| 
 | 
 | ||||||
|     def close_grpc(self): |  | ||||||
|         self.core_grpc.close() |  | ||||||
| 
 |  | ||||||
|     def setup_app(self): |     def setup_app(self): | ||||||
|         self.master.title("CORE") |         self.master.title("CORE") | ||||||
|         self.master.geometry("1000x800") |         self.master.geometry("1000x800") | ||||||
|  | @ -47,8 +51,8 @@ class Application(tk.Frame): | ||||||
|         core_editbar.create_toolbar() |         core_editbar.create_toolbar() | ||||||
| 
 | 
 | ||||||
|         self.canvas = CanvasGraph( |         self.canvas = CanvasGraph( | ||||||
|             grpc=self.core_grpc, |  | ||||||
|             master=self, |             master=self, | ||||||
|  |             grpc=self.core_grpc, | ||||||
|             background="#cccccc", |             background="#cccccc", | ||||||
|             scrollregion=(0, 0, 1000, 1000), |             scrollregion=(0, 0, 1000, 1000), | ||||||
|         ) |         ) | ||||||
|  | @ -79,4 +83,3 @@ if __name__ == "__main__": | ||||||
|     logging.basicConfig(level=logging.DEBUG) |     logging.basicConfig(level=logging.DEBUG) | ||||||
|     app = Application() |     app = Application() | ||||||
|     app.mainloop() |     app.mainloop() | ||||||
|     app.close_grpc() |  | ||||||
|  |  | ||||||
|  | @ -14,18 +14,20 @@ class CoreGrpc: | ||||||
|         self.core = client.CoreGrpcClient() |         self.core = client.CoreGrpcClient() | ||||||
|         self.session_id = None |         self.session_id = None | ||||||
|         self.set_up() |         self.set_up() | ||||||
|  |         self.interface_helper = None | ||||||
| 
 | 
 | ||||||
|     def log_event(self, event): |     def log_event(self, event): | ||||||
|         logging.info("event: %s", event) |         logging.info("event: %s", event) | ||||||
| 
 | 
 | ||||||
|     def set_up(self): |     def redraw_canvas(self): | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |     def create_new_session(self): | ||||||
|         """ |         """ | ||||||
|         Create session, handle events session may broadcast, change session state |         Create a new session | ||||||
| 
 | 
 | ||||||
|         :return: nothing |         :return: nothing | ||||||
|         """ |         """ | ||||||
|         self.core.connect() |  | ||||||
|         # create session |  | ||||||
|         response = self.core.create_session() |         response = self.core.create_session() | ||||||
|         logging.info("created session: %s", response) |         logging.info("created session: %s", response) | ||||||
| 
 | 
 | ||||||
|  | @ -33,39 +35,67 @@ class CoreGrpc: | ||||||
|         self.session_id = response.session_id |         self.session_id = response.session_id | ||||||
|         self.core.events(self.session_id, self.log_event) |         self.core.events(self.session_id, self.log_event) | ||||||
| 
 | 
 | ||||||
|         # change session state |     def query_existing_sessions(self, sessions): | ||||||
|  |         """ | ||||||
|  |         Query for existing sessions and prompt to join one | ||||||
|  | 
 | ||||||
|  |         :param repeated core_pb2.SessionSummary sessions: summaries of all the existing sessions | ||||||
|  | 
 | ||||||
|  |         :return: nothing | ||||||
|  |         """ | ||||||
|  |         for session in sessions: | ||||||
|  |             logging.info("Session id: %s, Session state: %s", session.id, session.state) | ||||||
|  |         logging.info("Input a session you want to enter from the keyboard:") | ||||||
|  |         usr_input = int(input()) | ||||||
|  |         if usr_input == 0: | ||||||
|  |             self.create_new_session() | ||||||
|  |         else: | ||||||
|  |             response = self.core.get_session(usr_input) | ||||||
|  |             self.session_id = usr_input | ||||||
|  |             # self.core.events(self.session_id, self.log_event) | ||||||
|  |             logging.info("Entering session_id %s.... Result: %s", usr_input, response) | ||||||
|  | 
 | ||||||
|  |     def set_up(self): | ||||||
|  |         """ | ||||||
|  |         Query sessions, if there exist any, promt whether to join one | ||||||
|  | 
 | ||||||
|  |         :return: nothing | ||||||
|  |         """ | ||||||
|  |         self.core.connect() | ||||||
|  | 
 | ||||||
|  |         response = self.core.get_sessions() | ||||||
|  |         logging.info("all sessions: %s", response) | ||||||
|  | 
 | ||||||
|  |         # if there are no sessions, create a new session, else join a session | ||||||
|  |         sessions = response.sessions | ||||||
|  | 
 | ||||||
|  |         if len(sessions) == 0: | ||||||
|  |             self.create_new_session() | ||||||
|  |         else: | ||||||
|  |             # self.create_new_session() | ||||||
|  |             self.query_existing_sessions(sessions) | ||||||
|  | 
 | ||||||
|  |     def set_configuration_state(self): | ||||||
|         response = self.core.set_session_state( |         response = self.core.set_session_state( | ||||||
|             self.session_id, core_pb2.SessionState.CONFIGURATION |             self.session_id, core_pb2.SessionState.CONFIGURATION | ||||||
|         ) |         ) | ||||||
|         logging.info("set session state: %s", response) |         logging.info("set session state: %s", response) | ||||||
| 
 | 
 | ||||||
|  |     def set_instantiate_state(self): | ||||||
|  |         response = self.core.set_session_state( | ||||||
|  |             self.session_id, core_pb2.SessionState.INSTANTIATION | ||||||
|  |         ) | ||||||
|  |         logging.info("set session state: %s", response) | ||||||
|  | 
 | ||||||
|     def get_session_id(self): |     def get_session_id(self): | ||||||
|         return self.session_id |         return self.session_id | ||||||
| 
 | 
 | ||||||
|     # TODO add checkings to the function |     def add_node(self, node_type, model, x, y, name): | ||||||
|     def add_node(self, x, y, node_name): |         logging.info("ADD NODE %s", name) | ||||||
|         link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel"] |         position = core_pb2.Position(x=x, y=y) | ||||||
|         network_layer_nodes = ["default"] |         node = core_pb2.Node(type=node_type, position=position, model=model, image=name) | ||||||
|         node = None |  | ||||||
|         if node_name in link_layer_nodes: |  | ||||||
|             if node_name == "switch": |  | ||||||
|                 node = core_pb2.Node(type=core_pb2.NodeType.SWITCH) |  | ||||||
|             elif node_name == "hub": |  | ||||||
|                 node = core_pb2.Node(type=core_pb2.NodeType.HUB) |  | ||||||
|             elif node_name == "wlan": |  | ||||||
|                 node = core_pb2.Node(type=core_pb2.NodeType.WIRELESS_LAN) |  | ||||||
|             elif node_name == "rj45": |  | ||||||
|                 node = core_pb2.Node(type=core_pb2.NodeType.RJ45) |  | ||||||
|             elif node_name == "tunnel": |  | ||||||
|                 node = core_pb2.Node(type=core_pb2.NodeType.TUNNEL) |  | ||||||
| 
 |  | ||||||
|         elif node_name in network_layer_nodes: |  | ||||||
|             position = core_pb2.Position(x=x, y=y) |  | ||||||
|             node = core_pb2.Node(position=position) |  | ||||||
|         else: |  | ||||||
|             return |  | ||||||
|         response = self.core.add_node(self.session_id, node) |         response = self.core.add_node(self.session_id, node) | ||||||
|         logging.info("created %s: %s", node_name, response) |         logging.info("created node: %s", response) | ||||||
|         return response.node_id |         return response.node_id | ||||||
| 
 | 
 | ||||||
|     def edit_node(self, session_id, node_id, x, y): |     def edit_node(self, session_id, node_id, x, y): | ||||||
|  | @ -73,6 +103,34 @@ class CoreGrpc: | ||||||
|         response = self.core.edit_node(session_id, node_id, position) |         response = self.core.edit_node(session_id, node_id, position) | ||||||
|         logging.info("updated node id %s: %s", node_id, response) |         logging.info("updated node id %s: %s", node_id, response) | ||||||
| 
 | 
 | ||||||
|  |     # def create_interface_helper(self): | ||||||
|  |     #     self.interface_helper = self.core.InterfaceHelper(ip4_prefix="10.83.0.0/16") | ||||||
|  | 
 | ||||||
|  |     # TODO case for other core_pb2.NodeType | ||||||
|  |     def add_link(self, id1, id2, type1, type2): | ||||||
|  |         """ | ||||||
|  |         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 | ||||||
|  |         """ | ||||||
|  |         if not self.interface_helper: | ||||||
|  |             logging.debug("INTERFACE HELPER NOT CREATED YET, CREATING ONE...") | ||||||
|  |             self.interface_helper = client.InterfaceHelper(ip4_prefix="10.83.0.0/16") | ||||||
|  | 
 | ||||||
|  |         interface1 = None | ||||||
|  |         interface2 = None | ||||||
|  |         if type1 == core_pb2.NodeType.DEFAULT: | ||||||
|  |             interface1 = self.interface_helper.create_interface(id1, 0) | ||||||
|  |         if type2 == core_pb2.NodeType.DEFAULT: | ||||||
|  |             interface2 = self.interface_helper.create_interface(id2, 0) | ||||||
|  |         response = self.core.add_link(self.session_id, id1, id2, interface1, interface2) | ||||||
|  |         logging.info("created link: %s", response) | ||||||
|  | 
 | ||||||
|     def close(self): |     def close(self): | ||||||
|         """ |         """ | ||||||
|         Clean ups when done using grpc |         Clean ups when done using grpc | ||||||
|  |  | ||||||
|  | @ -27,7 +27,6 @@ class CoreToolbar(object): | ||||||
|         self.width = 32 |         self.width = 32 | ||||||
|         self.height = 32 |         self.height = 32 | ||||||
| 
 | 
 | ||||||
|         # Used for drawing the horizontally displayed menu items for network-layer nodes and link-layer node |  | ||||||
|         self.selection_tool_button = None |         self.selection_tool_button = None | ||||||
| 
 | 
 | ||||||
|         # Reference to the option menus |         # Reference to the option menus | ||||||
|  | @ -35,8 +34,6 @@ class CoreToolbar(object): | ||||||
|         self.marker_option_menu = None |         self.marker_option_menu = None | ||||||
|         self.network_layer_option_menu = None |         self.network_layer_option_menu = None | ||||||
| 
 | 
 | ||||||
|         # variables used by canvas graph |  | ||||||
|         self.image_to_draw = None |  | ||||||
|         self.canvas = None |         self.canvas = None | ||||||
| 
 | 
 | ||||||
|     def update_canvas(self, canvas): |     def update_canvas(self, canvas): | ||||||
|  | @ -151,63 +148,79 @@ class CoreToolbar(object): | ||||||
|         logging.debug("Click SELECTION TOOL") |         logging.debug("Click SELECTION TOOL") | ||||||
|         self.canvas.mode = GraphMode.SELECT |         self.canvas.mode = GraphMode.SELECT | ||||||
| 
 | 
 | ||||||
|     def click_start_stop_session_tool(self): |     def click_start_session_tool(self): | ||||||
|         logging.debug("Click START STOP SESSION button") |         logging.debug("Click START STOP SESSION button") | ||||||
|         self.destroy_children_widgets(self.edit_frame) |         self.destroy_children_widgets(self.edit_frame) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.SELECT) |         self.canvas.mode = GraphMode.SELECT | ||||||
|         self.create_runtime_toolbar() |         self.create_runtime_toolbar() | ||||||
| 
 | 
 | ||||||
|  |         # set configuration state | ||||||
|  |         self.canvas.core_grpc.set_configuration_state() | ||||||
|  | 
 | ||||||
|  |         # grpc client requests creating nodes | ||||||
|  |         for node in self.canvas.grpc_manager.nodes_to_create.values(): | ||||||
|  |             self.canvas.core_grpc.add_node( | ||||||
|  |                 node.type, node.model, int(node.x), int(node.y), node.name | ||||||
|  |             ) | ||||||
|  |         self.canvas.grpc_manager.nodes_to_create.clear() | ||||||
|  | 
 | ||||||
|  |         for edge in self.canvas.grpc_manager.edges_to_create.values(): | ||||||
|  |             self.canvas.core_grpc.add_link(edge.id1, edge.id2, edge.type1, edge.type2) | ||||||
|  |         self.canvas.grpc_manager.edges_to_create.clear() | ||||||
|  | 
 | ||||||
|  |         self.canvas.core_grpc.set_instantiate_state() | ||||||
|  | 
 | ||||||
|     def click_link_tool(self): |     def click_link_tool(self): | ||||||
|         logging.debug("Click LINK button") |         logging.debug("Click LINK button") | ||||||
|         self.canvas.set_canvas_mode(GraphMode.EDGE) |         self.canvas.mode = GraphMode.EDGE | ||||||
| 
 | 
 | ||||||
|     def pick_router(self, main_button): |     def pick_router(self, main_button): | ||||||
|         logging.debug("Pick router option") |         logging.debug("Pick router option") | ||||||
|         self.network_layer_option_menu.destroy() |         self.network_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("router")) |         main_button.configure(image=Images.get("router")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("router")) |         self.canvas.draw_node_image = Images.get("router") | ||||||
|         self.canvas.set_drawing_name("default") |         self.canvas.draw_node_name = "router" | ||||||
| 
 | 
 | ||||||
|     def pick_host(self, main_button): |     def pick_host(self, main_button): | ||||||
|         logging.debug("Pick host option") |         logging.debug("Pick host option") | ||||||
|         self.network_layer_option_menu.destroy() |         self.network_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("host")) |         main_button.configure(image=Images.get("host")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("host")) |         self.canvas.draw_node_image = Images.get("host") | ||||||
|         self.canvas.set_drawing_name("default") |         self.canvas.draw_node_name = "host" | ||||||
| 
 | 
 | ||||||
|     def pick_pc(self, main_button): |     def pick_pc(self, main_button): | ||||||
|         logging.debug("Pick PC option") |         logging.debug("Pick PC option") | ||||||
|         self.network_layer_option_menu.destroy() |         self.network_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("pc")) |         main_button.configure(image=Images.get("pc")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("pc")) |         self.canvas.draw_node_image = Images.get("pc") | ||||||
|         self.canvas.set_drawing_name("default") |         self.canvas.draw_node_name = "PC" | ||||||
| 
 | 
 | ||||||
|     def pick_mdr(self, main_button): |     def pick_mdr(self, main_button): | ||||||
|         logging.debug("Pick MDR option") |         logging.debug("Pick MDR option") | ||||||
|         self.network_layer_option_menu.destroy() |         self.network_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("mdr")) |         main_button.configure(image=Images.get("mdr")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("mdr")) |         self.canvas.draw_node_image = Images.get("mdr") | ||||||
|         self.canvas.set_drawing_name("default") |         self.canvas.draw_node_name = "mdr" | ||||||
| 
 | 
 | ||||||
|     def pick_prouter(self, main_button): |     def pick_prouter(self, main_button): | ||||||
|         logging.debug("Pick prouter option") |         logging.debug("Pick prouter option") | ||||||
|         self.network_layer_option_menu.destroy() |         self.network_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("prouter")) |         main_button.configure(image=Images.get("prouter")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("prouter")) |         self.canvas.draw_node_image = Images.get("prouter") | ||||||
|         self.canvas.set_drawing_name("default") |         self.canvas.draw_node_name = "prouter" | ||||||
| 
 | 
 | ||||||
|     def pick_ovs(self, main_button): |     def pick_ovs(self, main_button): | ||||||
|         logging.debug("Pick OVS option") |         logging.debug("Pick OVS option") | ||||||
|         self.network_layer_option_menu.destroy() |         self.network_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("ovs")) |         main_button.configure(image=Images.get("ovs")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("ovs")) |         self.canvas.draw_node_image = Images.get("ovs") | ||||||
|         self.canvas.set_drawing_name("default") |         self.canvas.draw_node_name = "OVS" | ||||||
| 
 | 
 | ||||||
|     # TODO what graph node is this |     # TODO what graph node is this | ||||||
|     def pick_editnode(self, main_button): |     def pick_editnode(self, main_button): | ||||||
|  | @ -294,40 +307,41 @@ class CoreToolbar(object): | ||||||
|         logging.debug("Pick link-layer node HUB") |         logging.debug("Pick link-layer node HUB") | ||||||
|         self.link_layer_option_menu.destroy() |         self.link_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("hub")) |         main_button.configure(image=Images.get("hub")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("hub")) |         self.canvas.draw_node_image = Images.get("hub") | ||||||
|         self.canvas.set_drawing_name("hub") |         self.canvas.draw_node_name = "hub" | ||||||
| 
 | 
 | ||||||
|     def pick_switch(self, main_button): |     def pick_switch(self, main_button): | ||||||
|         logging.debug("Pick link-layer node SWITCH") |         logging.debug("Pick link-layer node SWITCH") | ||||||
|         self.link_layer_option_menu.destroy() |         self.link_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("switch")) |         main_button.configure(image=Images.get("switch")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("switch")) |         self.canvas.draw_node_image = Images.get("switch") | ||||||
|         self.canvas.set_drawing_name("switch") |         self.canvas.draw_node_name = "switch" | ||||||
| 
 | 
 | ||||||
|     def pick_wlan(self, main_button): |     def pick_wlan(self, main_button): | ||||||
|         logging.debug("Pick link-layer node WLAN") |         logging.debug("Pick link-layer node WLAN") | ||||||
|         self.link_layer_option_menu.destroy() |         self.link_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("wlan")) |         main_button.configure(image=Images.get("wlan")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("wlan")) |         self.canvas.draw_node_image = Images.get("wlan") | ||||||
|         self.canvas.set_drawing_name("wlan") |         self.canvas.draw_node_name = "wlan" | ||||||
| 
 | 
 | ||||||
|     def pick_rj45(self, main_button): |     def pick_rj45(self, main_button): | ||||||
|         logging.debug("Pick link-layer node RJ45") |         logging.debug("Pick link-layer node RJ45") | ||||||
|         self.link_layer_option_menu.destroy() |         self.link_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("rj45")) |         main_button.configure(image=Images.get("rj45")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("rj45")) |         self.canvas.draw_node_image = Images.get("rj45") | ||||||
|  |         self.canvas.draw_node_name = "rj45" | ||||||
| 
 | 
 | ||||||
|     def pick_tunnel(self, main_button): |     def pick_tunnel(self, main_button): | ||||||
|         logging.debug("Pick link-layer node TUNNEL") |         logging.debug("Pick link-layer node TUNNEL") | ||||||
|         self.link_layer_option_menu.destroy() |         self.link_layer_option_menu.destroy() | ||||||
|         main_button.configure(image=Images.get("tunnel")) |         main_button.configure(image=Images.get("tunnel")) | ||||||
|         self.canvas.set_canvas_mode(GraphMode.PICKNODE) |         self.canvas.mode = GraphMode.PICKNODE | ||||||
|         self.canvas.set_drawing_image(Images.get("tunnel")) |         self.canvas.draw_node_image = Images.get("tunnel") | ||||||
|         self.canvas.set_drawing_image(Images.get("tunnel")) |         self.canvas.draw_node_name = "tunnel" | ||||||
| 
 | 
 | ||||||
|     def draw_link_layer_options(self, link_layer_button): |     def draw_link_layer_options(self, link_layer_button): | ||||||
|         """ |         """ | ||||||
|  | @ -476,11 +490,10 @@ class CoreToolbar(object): | ||||||
|         CreateToolTip(marker_main_button, "background annotation tools") |         CreateToolTip(marker_main_button, "background annotation tools") | ||||||
| 
 | 
 | ||||||
|     def create_toolbar(self): |     def create_toolbar(self): | ||||||
|         # self.load_toolbar_images() |  | ||||||
|         self.create_regular_button( |         self.create_regular_button( | ||||||
|             self.edit_frame, |             self.edit_frame, | ||||||
|             Images.get("start"), |             Images.get("start"), | ||||||
|             self.click_start_stop_session_tool, |             self.click_start_session_tool, | ||||||
|             "start the session", |             "start the session", | ||||||
|         ) |         ) | ||||||
|         self.create_radio_button( |         self.create_radio_button( | ||||||
|  |  | ||||||
|  | @ -2,6 +2,9 @@ import enum | ||||||
| import logging | import logging | ||||||
| import tkinter as tk | import tkinter as tk | ||||||
| 
 | 
 | ||||||
|  | from coretk.grpcmanagement import GrpcManager | ||||||
|  | from coretk.images import Images | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class GraphMode(enum.Enum): | class GraphMode(enum.Enum): | ||||||
|     SELECT = 0 |     SELECT = 0 | ||||||
|  | @ -12,12 +15,11 @@ class GraphMode(enum.Enum): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class CanvasGraph(tk.Canvas): | class CanvasGraph(tk.Canvas): | ||||||
|     def __init__(self, grpc=None, master=None, cnf=None, **kwargs): |     def __init__(self, master=None, grpc=None, cnf=None, **kwargs): | ||||||
|         if cnf is None: |         if cnf is None: | ||||||
|             cnf = {} |             cnf = {} | ||||||
|         kwargs["highlightthickness"] = 0 |         kwargs["highlightthickness"] = 0 | ||||||
|         super().__init__(master, cnf, **kwargs) |         super().__init__(master, cnf, **kwargs) | ||||||
|         self.core_grpc = grpc |  | ||||||
|         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_name = None | ||||||
|  | @ -26,19 +28,32 @@ class CanvasGraph(tk.Canvas): | ||||||
|         self.nodes = {} |         self.nodes = {} | ||||||
|         self.edges = {} |         self.edges = {} | ||||||
|         self.drawing_edge = None |         self.drawing_edge = None | ||||||
| 
 |  | ||||||
|         self.setup_menus() |         self.setup_menus() | ||||||
|         self.setup_bindings() |         self.setup_bindings() | ||||||
|         self.draw_grid() |         self.draw_grid() | ||||||
|  |         self.core_grpc = grpc | ||||||
|  |         self.grpc_manager = GrpcManager() | ||||||
|  |         self.draw_existing_node() | ||||||
| 
 | 
 | ||||||
|     def set_canvas_mode(self, mode): |     def setup_menus(self): | ||||||
|         self.mode = mode |         self.node_context = tk.Menu(self.master) | ||||||
|  |         self.node_context.add_command(label="One") | ||||||
|  |         self.node_context.add_command(label="Two") | ||||||
|  |         self.node_context.add_command(label="Three") | ||||||
| 
 | 
 | ||||||
|     def set_drawing_image(self, img): |     def setup_bindings(self): | ||||||
|         self.draw_node_image = img |         """ | ||||||
|  |         Bind any mouse events or hot keys to the matching action | ||||||
| 
 | 
 | ||||||
|     def set_drawing_name(self, name): |         :return: nothing | ||||||
|         self.draw_node_name = name |         """ | ||||||
|  |         self.bind("<ButtonPress-1>", self.click_press) | ||||||
|  |         self.bind("<ButtonRelease-1>", self.click_release) | ||||||
|  |         self.bind("<B1-Motion>", self.click_motion) | ||||||
|  |         self.bind("<Button-3>", self.context) | ||||||
|  |         # self.bind("e", self.set_mode) | ||||||
|  |         # self.bind("s", self.set_mode) | ||||||
|  |         # self.bind("n", self.set_mode) | ||||||
| 
 | 
 | ||||||
|     def draw_grid(self, width=1000, height=750): |     def draw_grid(self, width=1000, height=750): | ||||||
|         """ |         """ | ||||||
|  | @ -65,25 +80,20 @@ class CanvasGraph(tk.Canvas): | ||||||
|         for i in range(0, height, 27): |         for i in range(0, height, 27): | ||||||
|             self.create_line(0, i, width, i, dash=(2, 4), tags="grid line") |             self.create_line(0, i, width, i, dash=(2, 4), tags="grid line") | ||||||
| 
 | 
 | ||||||
|     def setup_menus(self): |     def draw_existing_node(self): | ||||||
|         self.node_context = tk.Menu(self.master) |  | ||||||
|         self.node_context.add_command(label="One") |  | ||||||
|         self.node_context.add_command(label="Two") |  | ||||||
|         self.node_context.add_command(label="Three") |  | ||||||
| 
 |  | ||||||
|     def setup_bindings(self): |  | ||||||
|         """ |         """ | ||||||
|         Bind any mouse events or hot keys to the matching action |         Draw existing node while updating the grpc manager based on that | ||||||
| 
 | 
 | ||||||
|         :return: nothing |         :return: nothing | ||||||
|         """ |         """ | ||||||
|         self.bind("<ButtonPress-1>", self.click_press) |         session_id = self.core_grpc.session_id | ||||||
|         self.bind("<ButtonRelease-1>", self.click_release) |         response = self.core_grpc.core.get_session(session_id) | ||||||
|         self.bind("<B1-Motion>", self.click_motion) |         nodes = response.session.nodes | ||||||
|         self.bind("<Button-3>", self.context) |         if len(nodes) > 0: | ||||||
|         # self.bind("e", self.set_mode) |             for node in nodes: | ||||||
|         # self.bind("s", self.set_mode) |                 image = Images.convert_type_and_model_to_image(node.type, node.model) | ||||||
|         # self.bind("n", self.set_mode) |                 return image | ||||||
|  |                 # n = CanvasNode(node.position.x, node.position.y, image, self, node.id) | ||||||
| 
 | 
 | ||||||
|     def canvas_xy(self, event): |     def canvas_xy(self, event): | ||||||
|         """ |         """ | ||||||
|  | @ -172,6 +182,10 @@ class CanvasGraph(tk.Canvas): | ||||||
|             node_dst = self.nodes[edge.dst] |             node_dst = self.nodes[edge.dst] | ||||||
|             node_dst.edges.add(edge) |             node_dst.edges.add(edge) | ||||||
| 
 | 
 | ||||||
|  |             self.grpc_manager.add_edge( | ||||||
|  |                 self.core_grpc.get_session_id(), edge.token, node_src.id, node_dst.id | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|         logging.debug(f"edges: {self.find_withtag('edge')}") |         logging.debug(f"edges: {self.find_withtag('edge')}") | ||||||
| 
 | 
 | ||||||
|     def click_press(self, event): |     def click_press(self, event): | ||||||
|  | @ -207,40 +221,14 @@ class CanvasGraph(tk.Canvas): | ||||||
|             logging.debug(f"node context: {selected}") |             logging.debug(f"node context: {selected}") | ||||||
|             self.node_context.post(event.x_root, event.y_root) |             self.node_context.post(event.x_root, event.y_root) | ||||||
| 
 | 
 | ||||||
|     # def set_mode(self, event): |  | ||||||
|     #     """ |  | ||||||
|     #     Set canvas mode according to the hot key that has been pressed |  | ||||||
|     # |  | ||||||
|     #     :param event: key event |  | ||||||
|     #     :return: nothing |  | ||||||
|     #     """ |  | ||||||
|     #     logging.debug(f"mode event: {event}") |  | ||||||
|     #     if event.char == "e": |  | ||||||
|     #         self.mode = GraphMode.EDGE |  | ||||||
|     #     elif event.char == "s": |  | ||||||
|     #         self.mode = GraphMode.SELECT |  | ||||||
|     #     elif event.char == "n": |  | ||||||
|     #         self.mode = GraphMode.NODE |  | ||||||
|     #     logging.debug(f"graph mode: {self.mode}") |  | ||||||
| 
 |  | ||||||
|     # def add_node(self, x, y, image_name): |  | ||||||
|     #     image = Images.get(image_name) |  | ||||||
|     #     node = CanvasNode(x, y, image, self) |  | ||||||
|     #     self.nodes[node.id] = node |  | ||||||
|     #     return node |  | ||||||
| 
 |  | ||||||
|     def add_node(self, x, y, image, node_name): |     def add_node(self, x, y, image, node_name): | ||||||
|         core_session_id = self.core_grpc.get_session_id() |  | ||||||
|         core_node_id = self.core_grpc.add_node(int(x), int(y), node_name) |  | ||||||
|         node = CanvasNode( |         node = CanvasNode( | ||||||
|             core_session_id=core_session_id, |             x=x, y=y, image=image, canvas=self, core_id=self.grpc_manager.peek_id() | ||||||
|             core_node_id=core_node_id, |  | ||||||
|             x=x, |  | ||||||
|             y=y, |  | ||||||
|             image=image, |  | ||||||
|             canvas=self, |  | ||||||
|         ) |         ) | ||||||
|         self.nodes[node.id] = node |         self.nodes[node.id] = node | ||||||
|  |         self.grpc_manager.add_node( | ||||||
|  |             self.core_grpc.get_session_id(), node.id, x, y, node_name | ||||||
|  |         ) | ||||||
|         return node |         return node | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -283,17 +271,16 @@ class CanvasEdge: | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class CanvasNode: | class CanvasNode: | ||||||
|     def __init__(self, core_session_id, core_node_id, x, y, image, canvas): |     def __init__(self, x, y, image, canvas, core_id): | ||||||
|         self.image = image |         self.image = image | ||||||
|         self.canvas = canvas |         self.canvas = 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.x_coord = x |         self.x_coord = x | ||||||
|         self.y_coord = y |         self.y_coord = y | ||||||
|         self.core_session_id = core_session_id |         self.name = f"Node {self.core_id}" | ||||||
|         self.core_node_id = core_node_id |  | ||||||
|         self.name = f"Node {self.core_node_id}" |  | ||||||
|         self.text_id = self.canvas.create_text(x, y + 20, text=self.name) |         self.text_id = self.canvas.create_text(x, y + 20, text=self.name) | ||||||
|         self.canvas.tag_bind(self.id, "<ButtonPress-1>", self.click_press) |         self.canvas.tag_bind(self.id, "<ButtonPress-1>", self.click_press) | ||||||
|         self.canvas.tag_bind(self.id, "<ButtonRelease-1>", self.click_release) |         self.canvas.tag_bind(self.id, "<ButtonRelease-1>", self.click_release) | ||||||
|  | @ -315,12 +302,6 @@ class CanvasNode: | ||||||
|     def click_release(self, event): |     def click_release(self, event): | ||||||
|         logging.debug(f"click release {self.name}: {event}") |         logging.debug(f"click release {self.name}: {event}") | ||||||
|         self.update_coords() |         self.update_coords() | ||||||
|         self.canvas.core_grpc.edit_node( |  | ||||||
|             self.core_session_id, |  | ||||||
|             self.core_node_id, |  | ||||||
|             int(self.x_coord), |  | ||||||
|             int(self.y_coord), |  | ||||||
|         ) |  | ||||||
|         self.moving = None |         self.moving = None | ||||||
| 
 | 
 | ||||||
|     def motion(self, event): |     def motion(self, event): | ||||||
|  |  | ||||||
							
								
								
									
										157
									
								
								coretk/coretk/grpcmanagement.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								coretk/coretk/grpcmanagement.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,157 @@ | ||||||
|  | """ | ||||||
|  | Manage useful informations about the nodes, edges and configuration | ||||||
|  | that can be useful for grpc, acts like a session class | ||||||
|  | """ | ||||||
|  | import logging | ||||||
|  | 
 | ||||||
|  | from core.api.grpc import core_pb2 | ||||||
|  | 
 | ||||||
|  | link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel"] | ||||||
|  | network_layer_nodes = ["router", "host", "PC", "mdr", "prouter", "OVS"] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Node: | ||||||
|  |     def __init__(self, session_id, node_id, 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 type: node type | ||||||
|  |         :param int x: x coordinate | ||||||
|  |         :param int y: coordinate | ||||||
|  |         """ | ||||||
|  |         self.session_id = session_id | ||||||
|  |         self.node_id = node_id | ||||||
|  |         self.type = type | ||||||
|  |         self.x = x | ||||||
|  |         self.y = y | ||||||
|  |         self.model = model | ||||||
|  |         self.name = name | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class GrpcManager: | ||||||
|  |     def __init__(self): | ||||||
|  |         self.nodes = {} | ||||||
|  |         self.edges = {} | ||||||
|  |         self.id = 1 | ||||||
|  |         # A list of id for re-use, keep in increasing order | ||||||
|  |         self.reusable = [] | ||||||
|  |         self.nodes_to_create = {} | ||||||
|  |         self.edges_to_create = {} | ||||||
|  | 
 | ||||||
|  |     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): | ||||||
|  |         """ | ||||||
|  |         Get the next node id as well as update id status and reusable ids | ||||||
|  | 
 | ||||||
|  |         :rtype: int | ||||||
|  |         :return: the next id to be used | ||||||
|  |         """ | ||||||
|  |         if len(self.reusable) == 0: | ||||||
|  |             new_id = self.id | ||||||
|  |             self.id = self.id + 1 | ||||||
|  |             return new_id | ||||||
|  |         else: | ||||||
|  |             return self.reusable.pop(0) | ||||||
|  | 
 | ||||||
|  |     # TODO figure out the name of ovs node | ||||||
|  |     def add_node(self, session_id, canvas_id, x, y, name): | ||||||
|  |         """ | ||||||
|  |         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 y: y coord | ||||||
|  |         :param str name: node type | ||||||
|  |         :return: nothing | ||||||
|  |         """ | ||||||
|  |         node_type = None | ||||||
|  |         node_model = None | ||||||
|  |         if name in link_layer_nodes: | ||||||
|  |             if name == "switch": | ||||||
|  |                 node_type = core_pb2.NodeType.SWITCH | ||||||
|  |             elif name == "hub": | ||||||
|  |                 node_type = core_pb2.NodeType.HUB | ||||||
|  |             elif name == "wlan": | ||||||
|  |                 node_type = core_pb2.NodeType.WIRELESS_LAN | ||||||
|  |             elif name == "rj45": | ||||||
|  |                 node_type = core_pb2.NodeType.RJ45 | ||||||
|  |             elif name == "tunnel": | ||||||
|  |                 node_type = core_pb2.NodeType.TUNNEL | ||||||
|  |         elif name in network_layer_nodes: | ||||||
|  |             node_type = core_pb2.NodeType.DEFAULT | ||||||
|  |             # TODO what is the model name for ovs | ||||||
|  |             node_model = name | ||||||
|  |         else: | ||||||
|  |             logging.error("grpcmanagemeny.py INVALID node name") | ||||||
|  |         create_node = Node(session_id, self.get_id(), node_type, node_model, x, y, name) | ||||||
|  |         self.nodes[canvas_id] = create_node | ||||||
|  |         self.nodes_to_create[canvas_id] = create_node | ||||||
|  |         logging.debug( | ||||||
|  |             "Adding node to GrpcManager.. Session id: %s, Coords: (%s, %s), Name: %s", | ||||||
|  |             session_id, | ||||||
|  |             x, | ||||||
|  |             y, | ||||||
|  |             name, | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def add_preexisting_node(self): | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |     def delete_node(self, canvas_id): | ||||||
|  |         """ | ||||||
|  |         Delete a node from the session | ||||||
|  | 
 | ||||||
|  |         :param int canvas_id: node's id in the canvas | ||||||
|  |         :return: thing | ||||||
|  |         """ | ||||||
|  |         try: | ||||||
|  |             self.nodes.pop(canvas_id) | ||||||
|  |             self.reuseable.append(canvas_id) | ||||||
|  |             self.reuseable.sort() | ||||||
|  |         except KeyError: | ||||||
|  |             logging.error("grpcmanagement.py INVALID NODE CANVAS ID") | ||||||
|  | 
 | ||||||
|  |     def add_edge(self, session_id, token, canvas_id_1, canvas_id_2): | ||||||
|  |         if canvas_id_1 in self.nodes and canvas_id_2 in self.nodes: | ||||||
|  |             edge = Edge( | ||||||
|  |                 session_id, | ||||||
|  |                 self.nodes[canvas_id_1].node_id, | ||||||
|  |                 self.nodes[canvas_id_1].type, | ||||||
|  |                 self.nodes[canvas_id_2].node_id, | ||||||
|  |                 self.nodes[canvas_id_2].type, | ||||||
|  |             ) | ||||||
|  |             self.edges[token] = edge | ||||||
|  |             self.edges_to_create[token] = edge | ||||||
|  |             logging.debug("Adding edge to grpc manager...") | ||||||
|  |         else: | ||||||
|  |             logging.error("grpcmanagement.py INVALID CANVAS NODE ID") | ||||||
|  | @ -1,7 +1,10 @@ | ||||||
|  | import logging | ||||||
| import os | import os | ||||||
| 
 | 
 | ||||||
| from PIL import Image, ImageTk | from PIL import Image, ImageTk | ||||||
| 
 | 
 | ||||||
|  | from core.api.grpc import core_pb2 | ||||||
|  | 
 | ||||||
| PATH = os.path.abspath(os.path.dirname(__file__)) | PATH = os.path.abspath(os.path.dirname(__file__)) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -19,6 +22,41 @@ class Images: | ||||||
|     def get(cls, name): |     def get(cls, name): | ||||||
|         return cls.images[name] |         return cls.images[name] | ||||||
| 
 | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def convert_type_and_model_to_image(cls, node_type, node_model): | ||||||
|  |         """ | ||||||
|  |                 Retrieve image based on type and model | ||||||
|  |                 :param core_pb2.NodeType node_type: core node type | ||||||
|  |                 :param string node_model: the node model | ||||||
|  | 
 | ||||||
|  |                 :return: the matching image | ||||||
|  |                 """ | ||||||
|  |         if node_type == core_pb2.NodeType.SWITCH: | ||||||
|  |             return Images.get("switch") | ||||||
|  |         if node_type == core_pb2.NodeType.HUB: | ||||||
|  |             return Images.get("hub") | ||||||
|  |         if node_type == core_pb2.NodeType.WIRELESS_LAN: | ||||||
|  |             return Images.get("wlan") | ||||||
|  |         if node_type == core_pb2.NodeType.RJ45: | ||||||
|  |             return Images.get("rj45") | ||||||
|  |         if node_type == core_pb2.NodeType.TUNNEL: | ||||||
|  |             return Images.get("tunnel") | ||||||
|  |         if node_type == core_pb2.NodeType.DEFAULT: | ||||||
|  |             if node_model == "router": | ||||||
|  |                 return Images.get("router") | ||||||
|  |             if node_model == "host": | ||||||
|  |                 return Images.get(("host")) | ||||||
|  |             if node_model == "PC": | ||||||
|  |                 return Images.get("pc") | ||||||
|  |             if node_model == "mdr": | ||||||
|  |                 return Images.get("mdr") | ||||||
|  |             if node_model == "prouter": | ||||||
|  |                 return Images.get("prouter") | ||||||
|  |             if node_model == "OVS": | ||||||
|  |                 return Images.get("ovs") | ||||||
|  |         else: | ||||||
|  |             logging.debug("INVALID INPUT OR NOT CONSIDERED YET") | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def load_core_images(images): | def load_core_images(images): | ||||||
|     images.load("core", "core-icon.png") |     images.load("core", "core-icon.png") | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue