def create_link( self, edge: CanvasEdge, canvas_src_node: CanvasNode, canvas_dst_node: CanvasNode ): """ Create core link for a pair of canvas nodes, with token referencing the canvas edge. """ src_node = canvas_src_node.core_node dst_node = canvas_dst_node.core_node # determine subnet self.interfaces_manager.determine_subnets(canvas_src_node, canvas_dst_node) src_interface = None if NodeUtils.is_container_node(src_node.type): src_interface = self.create_interface(canvas_src_node) edge.src_interface = src_interface self.interface_to_edge[(src_node.id, src_interface.id)] = edge.token dst_interface = None if NodeUtils.is_container_node(dst_node.type): dst_interface = self.create_interface(canvas_dst_node) edge.dst_interface = dst_interface self.interface_to_edge[(dst_node.id, dst_interface.id)] = edge.token link = core_pb2.Link( type=core_pb2.LinkType.WIRED, node_one_id=src_node.id, node_two_id=dst_node.id, interface_one=src_interface, interface_two=dst_interface, ) edge.set_link(link) self.links[edge.token] = edge logging.info("Add link between %s and %s", src_node.name, dst_node.name)
def create_link(self, edge: CanvasEdge, canvas_src_node: CanvasNode, canvas_dst_node: CanvasNode) -> None: """ Create core link for a pair of canvas nodes, with token referencing the canvas edge. """ src_node = canvas_src_node.core_node dst_node = canvas_dst_node.core_node self.ifaces_manager.determine_subnets(canvas_src_node, canvas_dst_node) src_iface = None if NodeUtils.is_container_node(src_node.type): src_iface = self.create_iface(canvas_src_node) self.iface_to_edge[(src_node.id, src_iface.id)] = edge.token edge.src_iface = src_iface canvas_src_node.ifaces[src_iface.id] = src_iface dst_iface = None if NodeUtils.is_container_node(dst_node.type): dst_iface = self.create_iface(canvas_dst_node) self.iface_to_edge[(dst_node.id, dst_iface.id)] = edge.token edge.dst_iface = dst_iface canvas_dst_node.ifaces[dst_iface.id] = dst_iface link = Link( type=LinkType.WIRED, node1_id=src_node.id, node2_id=dst_node.id, iface1=src_iface, iface2=dst_iface, ) edge.set_link(link) self.links[edge.token] = edge logging.info("added link between %s and %s", src_node.name, dst_node.name)
def click_apply(self) -> None: error = False # update core node self.node.name = self.name.get() if NodeUtils.is_image_node(self.node.type): self.node.image = self.container_image.get() server = self.server.get() if NodeUtils.is_container_node(self.node.type): if server == DEFAULT_SERVER: self.node.server = None else: self.node.server = server # set custom icon if self.image_file: self.node.icon = self.image_file # update canvas node self.canvas_node.image = self.image # update node interface data for iface in self.canvas_node.ifaces.values(): data = self.ifaces[iface.id] error = not data.validate(self, iface) if error: break # redraw if not error: self.canvas_node.redraw() self.destroy()
def __init__( self, master: Any, app: "Application", canvas_node: "CanvasNode", services: Set[str] = None, ): title = f"{canvas_node.core_node.name} Services" super().__init__(master, app, title, modal=True) self.app = app self.canvas_node = canvas_node self.node_id = canvas_node.core_node.id self.groups = None self.services = None self.current = None if services is None: services = canvas_node.core_node.services model = canvas_node.core_node.model if len(services) == 0: # not custom node type and node's services haven't been modified before if not NodeUtils.is_custom( canvas_node.core_node.model ) and not self.app.core.service_been_modified(self.node_id): services = set(self.app.core.default_services[model]) # services of default type nodes were modified to be empty elif canvas_node.core_node.id in self.app.core.modified_service_nodes: services = set() else: services = set( NodeUtils.get_custom_node_services( self.app.guiconfig, model)) else: services = set(services) self.current_services = services self.draw()
def __init__(self, proxy: bool): super().__init__(master=None) # load node icons NodeUtils.setup() # widgets self.menubar = None self.toolbar = None self.canvas = None self.statusbar = None self.validation = None # fonts self.fonts_size = None self.icon_text_font = None self.edge_font = None # setup self.guiconfig = appconfig.read() self.app_scale = self.guiconfig["scale"] self.setup_scaling() self.style = ttk.Style() self.setup_theme() self.core = CoreClient(self, proxy) self.setup_app() self.draw() self.core.setup()
def __init__(self, proxy: bool, session_id: int = None) -> None: super().__init__() # load node icons NodeUtils.setup() # widgets self.menubar: Optional[Menubar] = None self.toolbar: Optional[Toolbar] = None self.right_frame: Optional[ttk.Frame] = None self.canvas: Optional[CanvasGraph] = None self.statusbar: Optional[StatusBar] = None self.progress: Optional[Progressbar] = None self.infobar: Optional[ttk.Frame] = None self.info_frame: Optional[InfoFrameBase] = None self.show_infobar: tk.BooleanVar = tk.BooleanVar(value=False) # fonts self.fonts_size: Dict[str, int] = {} self.icon_text_font: Optional[font.Font] = None self.edge_font: Optional[font.Font] = None # setup self.guiconfig: GuiConfig = appconfig.read() self.app_scale: float = self.guiconfig.scale self.setup_scaling() self.style: ttk.Style = ttk.Style() self.setup_theme() self.core: CoreClient = CoreClient(self, proxy) self.setup_app() self.draw() self.core.setup(session_id)
def show_context(self, event: tk.Event) -> None: # clear existing menu self.context.delete(0, tk.END) is_wlan = self.core_node.type == NodeType.WIRELESS_LAN is_emane = self.core_node.type == NodeType.EMANE if self.app.core.is_runtime(): self.context.add_command(label="Configure", command=self.show_config) if is_emane: self.context.add_command( label="EMANE Config", command=self.show_emane_config ) if is_wlan: self.context.add_command( label="WLAN Config", command=self.show_wlan_config ) if is_wlan and self.core_node.id in self.app.core.mobility_players: self.context.add_command( label="Mobility Player", command=self.show_mobility_player ) else: self.context.add_command(label="Configure", command=self.show_config) if NodeUtils.is_container_node(self.core_node.type): self.context.add_command(label="Services", command=self.show_services) self.context.add_command( label="Config Services", command=self.show_config_services ) if is_emane: self.context.add_command( label="EMANE Config", command=self.show_emane_config ) if is_wlan: self.context.add_command( label="WLAN Config", command=self.show_wlan_config ) self.context.add_command( label="Mobility Config", command=self.show_mobility_config ) if NodeUtils.is_wireless_node(self.core_node.type): self.context.add_command( label="Link To Selected", command=self.wireless_link_selected ) unlink_menu = tk.Menu(self.context) for edge in self.edges: other_id = edge.src if self.id == other_id: other_id = edge.dst other_node = self.canvas.nodes[other_id] func_unlink = functools.partial(self.click_unlink, edge) unlink_menu.add_command( label=other_node.core_node.name, command=func_unlink ) themes.style_menu(unlink_menu) self.context.add_cascade(label="Unlink", menu=unlink_menu) edit_menu = tk.Menu(self.context) themes.style_menu(edit_menu) edit_menu.add_command(label="Cut", command=self.click_cut) edit_menu.add_command(label="Copy", command=self.canvas_copy) edit_menu.add_command(label="Delete", command=self.canvas_delete) self.context.add_cascade(label="Edit", menu=edit_menu) self.context.tk_popup(event.x_root, event.y_root)
def create_link(self, edge: CanvasEdge, canvas_src_node: CanvasNode, canvas_dst_node: CanvasNode) -> Link: """ Create core link for a pair of canvas nodes, with token referencing the canvas edge. """ src_node = canvas_src_node.core_node dst_node = canvas_dst_node.core_node self.ifaces_manager.determine_subnets(canvas_src_node, canvas_dst_node) src_iface = None if NodeUtils.is_container_node(src_node.type): src_iface = self.create_iface(canvas_src_node) dst_iface = None if NodeUtils.is_container_node(dst_node.type): dst_iface = self.create_iface(canvas_dst_node) link = Link( type=LinkType.WIRED, node1_id=src_node.id, node2_id=dst_node.id, iface1=src_iface, iface2=dst_iface, ) logging.info("added link between %s and %s", src_node.name, dst_node.name) return link
def __init__(self, proxy: bool) -> None: super().__init__() # load node icons NodeUtils.setup() # widgets self.menubar = None self.toolbar = None self.right_frame = None self.canvas = None self.statusbar = None self.progress = None # fonts self.fonts_size = None self.icon_text_font = None self.edge_font = None # setup self.guiconfig = appconfig.read() self.app_scale = self.guiconfig.scale self.setup_scaling() self.style = ttk.Style() self.setup_theme() self.core = CoreClient(self, proxy) self.setup_app() self.draw() self.core.setup()
def is_wireless(self): src_node = self.canvas.nodes[self.src] dst_node = self.canvas.nodes[self.dst] src_node_type = src_node.core_node.type dst_node_type = dst_node.core_node.type is_src_wireless = NodeUtils.is_wireless_node(src_node_type) is_dst_wireless = NodeUtils.is_wireless_node(dst_node_type) return is_src_wireless or is_dst_wireless
def create_context(self) -> tk.Menu: is_wlan = self.core_node.type == NodeType.WIRELESS_LAN is_emane = self.core_node.type == NodeType.EMANE context = tk.Menu(self.canvas) themes.style_menu(context) if self.app.core.is_runtime(): context.add_command(label="Configure", command=self.show_config) if NodeUtils.is_container_node(self.core_node.type): context.add_command(label="Services", state=tk.DISABLED) context.add_command(label="Config Services", state=tk.DISABLED) if is_wlan: context.add_command(label="WLAN Config", command=self.show_wlan_config) if is_wlan and self.core_node.id in self.app.core.mobility_players: context.add_command( label="Mobility Player", command=self.show_mobility_player ) context.add_command(label="Select Adjacent", state=tk.DISABLED) context.add_command(label="Hide", state=tk.DISABLED) if NodeUtils.is_container_node(self.core_node.type): context.add_command(label="Shell Window", state=tk.DISABLED) context.add_command(label="Tcpdump", state=tk.DISABLED) context.add_command(label="Tshark", state=tk.DISABLED) context.add_command(label="Wireshark", state=tk.DISABLED) context.add_command(label="View Log", state=tk.DISABLED) else: context.add_command(label="Configure", command=self.show_config) if NodeUtils.is_container_node(self.core_node.type): context.add_command(label="Services", command=self.show_services) context.add_command( label="Config Services", command=self.show_config_services ) if is_emane: context.add_command( label="EMANE Config", command=self.show_emane_config ) if is_wlan: context.add_command(label="WLAN Config", command=self.show_wlan_config) context.add_command( label="Mobility Config", command=self.show_mobility_config ) if NodeUtils.is_wireless_node(self.core_node.type): context.add_command( label="Link To Selected", command=self.wireless_link_selected ) context.add_command(label="Select Members", state=tk.DISABLED) context.add_command(label="Select Adjacent", state=tk.DISABLED) context.add_command(label="Create Link To", state=tk.DISABLED) context.add_command(label="Assign To", state=tk.DISABLED) context.add_command(label="Move To", state=tk.DISABLED) context.add_command(label="Cut", state=tk.DISABLED) context.add_command(label="Copy", state=tk.DISABLED) context.add_command(label="Paste", state=tk.DISABLED) context.add_command(label="Delete", state=tk.DISABLED) context.add_command(label="Hide", state=tk.DISABLED) return context
def save_edge(self, edge: CanvasEdge, canvas_src_node: CanvasNode, canvas_dst_node: CanvasNode) -> None: self.links[edge.token] = edge src_node = canvas_src_node.core_node dst_node = canvas_dst_node.core_node if NodeUtils.is_container_node(src_node.type): src_iface_id = edge.link.iface1.id self.iface_to_edge[(src_node.id, src_iface_id)] = edge if NodeUtils.is_container_node(dst_node.type): dst_iface_id = edge.link.iface2.id self.iface_to_edge[(dst_node.id, dst_iface_id)] = edge
def create_node(self, x: float, y: float, node_type: NodeType, model: str) -> Optional[Node]: """ Add node, with information filled in, to grpc manager """ node_id = self.next_node_id() position = Position(x=x, y=y) image = None if NodeUtils.is_image_node(node_type): image = "ubuntu:latest" emane = None if node_type == NodeType.EMANE: if not self.session.emane_models: dialog = EmaneInstallDialog(self.app) dialog.show() return emane = self.session.emane_models[0] name = f"emane{node_id}" elif node_type == NodeType.WIRELESS_LAN: name = f"wlan{node_id}" elif node_type in [NodeType.RJ45, NodeType.TUNNEL]: name = "unassigned" else: name = f"n{node_id}" node = Node( id=node_id, type=node_type, name=name, model=model, position=position, image=image, emane=emane, ) if NodeUtils.is_custom(node_type, model): services = NodeUtils.get_custom_node_services( self.app.guiconfig, model) node.services[:] = services # assign default services to CORE node else: services = self.session.default_services.get(model) if services: node.services = services.copy() logging.info( "add node(%s) to session(%s), coordinates(%s, %s)", node.name, self.session.id, x, y, ) self.session.nodes[node.id] = node return node
def _check_antenna(self) -> None: src_node = self.canvas.nodes[self.src] dst_node = self.canvas.nodes[self.dst] src_node_type = src_node.core_node.type dst_node_type = dst_node.core_node.type is_src_wireless = NodeUtils.is_wireless_node(src_node_type) is_dst_wireless = NodeUtils.is_wireless_node(dst_node_type) if is_src_wireless or is_dst_wireless: if is_src_wireless and not is_dst_wireless: dst_node.add_antenna() elif not is_src_wireless and is_dst_wireless: src_node.add_antenna() else: src_node.add_antenna()
def _check_antenna(self): src_node = self.canvas.nodes[self.src] dst_node = self.canvas.nodes[self.dst] src_node_type = src_node.core_node.type dst_node_type = dst_node.core_node.type is_src_wireless = NodeUtils.is_wireless_node(src_node_type) is_dst_wireless = NodeUtils.is_wireless_node(dst_node_type) if is_src_wireless or is_dst_wireless: if is_src_wireless and not is_dst_wireless: dst_node.add_antenna() elif not is_src_wireless and is_dst_wireless: src_node.add_antenna() # TODO: remove this? dont allow linking wireless nodes? else: src_node.add_antenna()
def create_node(self, x, y, node_type, model): """ Add node, with information filled in, to grpc manager :param int x: x coord :param int y: y coord :param core_pb2.NodeType node_type: node type :param str model: node model :return: nothing """ node_id = self.next_node_id() position = core_pb2.Position(x=x, y=y) image = None if NodeUtils.is_image_node(node_type): image = "ubuntu:latest" emane = None if node_type == core_pb2.NodeType.EMANE: emane = self.emane_models[0] node = core_pb2.Node( id=node_id, type=node_type, name=f"n{node_id}", model=model, position=position, image=image, emane=emane, ) logging.debug( "adding node to core session: %s, coords: (%s, %s), name: %s", self.session_id, x, y, node.name, ) return node
def store_nodes(self) -> None: """ store all CORE nodes (nodes that execute commands) from all existing nodes """ for nid, node in self.app.core.canvas_nodes.items(): if NodeUtils.is_container_node(node.core_node.type): self.executable_nodes[node.core_node.name] = nid
def store_nodes(self) -> None: """ store all CORE nodes (nodes that execute commands) from all existing nodes """ for node in self.app.core.session.nodes.values(): if NodeUtils.is_container_node(node.type): self.executable_nodes[node.name] = node.id
def show_mobility_players(self) -> None: for node in self.session.nodes.values(): if not NodeUtils.is_mobility(node): continue if node.mobility_config: mobility_player = MobilityPlayer(self.app, node) self.mobility_players[node.id] = mobility_player mobility_player.show()
def delete_edge(self, edge: CanvasEdge): edge.delete() del self.edges[edge.token] src_node = self.nodes[edge.src] src_node.edges.discard(edge) if edge.src_interface in src_node.interfaces: src_node.interfaces.remove(edge.src_interface) dst_node = self.nodes[edge.dst] dst_node.edges.discard(edge) if edge.dst_interface in dst_node.interfaces: dst_node.interfaces.remove(edge.dst_interface) src_wireless = NodeUtils.is_wireless_node(src_node.core_node.type) if src_wireless: dst_node.delete_antenna() dst_wireless = NodeUtils.is_wireless_node(dst_node.core_node.type) if dst_wireless: src_node.delete_antenna() self.core.deleted_graph_edges([edge])
def delete_edge(self, edge: CanvasEdge) -> None: edge.delete() del self.edges[edge.token] src_node = self.nodes[edge.src] src_node.edges.discard(edge) if edge.src_iface: del src_node.ifaces[edge.src_iface.id] dst_node = self.nodes[edge.dst] dst_node.edges.discard(edge) if edge.dst_iface: del dst_node.ifaces[edge.dst_iface.id] src_wireless = NodeUtils.is_wireless_node(src_node.core_node.type) if src_wireless: dst_node.delete_antenna() dst_wireless = NodeUtils.is_wireless_node(dst_node.core_node.type) if dst_wireless: src_node.delete_antenna() self.core.deleted_canvas_edges([edge])
def is_wireless(self) -> bool: src_node = self.canvas.nodes[self.src] dst_node = self.canvas.nodes[self.dst] src_node_type = src_node.core_node.type dst_node_type = dst_node.core_node.type is_src_wireless = NodeUtils.is_wireless_node(src_node_type) is_dst_wireless = NodeUtils.is_wireless_node(dst_node_type) # update the wlan/EMANE network wlan_network = self.canvas.wireless_network if is_src_wireless and not is_dst_wireless: if self.src not in wlan_network: wlan_network[self.src] = set() wlan_network[self.src].add(self.dst) elif not is_src_wireless and is_dst_wireless: if self.dst not in wlan_network: wlan_network[self.dst] = set() wlan_network[self.dst].add(self.src) return is_src_wireless or is_dst_wireless
def create_link( self, edge: CanvasEdge, canvas_src_node: CanvasNode, canvas_dst_node: CanvasNode ) -> None: """ Create core link for a pair of canvas nodes, with token referencing the canvas edge. """ src_node = canvas_src_node.core_node dst_node = canvas_dst_node.core_node # determine subnet self.ifaces_manager.determine_subnets(canvas_src_node, canvas_dst_node) src_iface = None if NodeUtils.is_container_node(src_node.type): src_iface = self.create_iface(canvas_src_node) self.iface_to_edge[(src_node.id, src_iface.id)] = edge.token dst_iface = None if NodeUtils.is_container_node(dst_node.type): dst_iface = self.create_iface(canvas_dst_node) self.iface_to_edge[(dst_node.id, dst_iface.id)] = edge.token link = Link( type=LinkType.WIRED, node1_id=src_node.id, node2_id=dst_node.id, iface1=src_iface, iface2=dst_iface, ) # assign after creating link proto, since interfaces are copied if src_iface: iface1 = link.iface1 edge.src_iface = iface1 canvas_src_node.ifaces[iface1.id] = iface1 if dst_iface: iface2 = link.iface2 edge.dst_iface = iface2 canvas_dst_node.ifaces[iface2.id] = iface2 edge.set_link(link) self.links[edge.token] = edge logging.info("Add link between %s and %s", src_node.name, dst_node.name)
def handle_edge_release(self, _event: tk.Event) -> None: edge = self.drawing_edge self.drawing_edge = None # not drawing edge return if edge is None: return # edge dst must be a node logging.debug("current selected: %s", self.selected) src_node = self.nodes.get(edge.src) dst_node = self.nodes.get(self.selected) if not dst_node or not src_node: edge.delete() return # edge dst is same as src, delete edge if edge.src == self.selected: edge.delete() return # ignore repeated edges token = create_edge_token(edge.src, self.selected) if token in self.edges: edge.delete() return # rj45 nodes can only support one link if NodeUtils.is_rj45_node(src_node.core_node.type) and src_node.edges: edge.delete() return if NodeUtils.is_rj45_node(dst_node.core_node.type) and dst_node.edges: edge.delete() return # set dst node and snap edge to center edge.complete(self.selected) self.edges[edge.token] = edge src_node.edges.add(edge) dst_node.edges.add(edge) self.core.create_link(edge, src_node, dst_node)
def next_index(self, node: Node) -> int: if NodeUtils.is_router_node(node): index = 1 else: index = 20 while True: if index not in self.current_subnets.used_indexes: self.current_subnets.used_indexes.add(index) break index += 1 return index
def __init__(self, proxy: bool): super().__init__(master=None) # load node icons NodeUtils.setup() # widgets self.menubar = None self.toolbar = None self.canvas = None self.statusbar = None self.validation = None # setup self.guiconfig = appconfig.read() self.style = ttk.Style() self.setup_theme() self.core = CoreClient(self, proxy) self.setup_app() self.draw() self.core.set_up()
def config_apply(self): # update core node self.node.name = self.name.get() if NodeUtils.is_image_node(self.node.type): self.node.image = self.container_image.get() server = self.server.get() if NodeUtils.is_container_node( self.node.type) and server != "localhost": self.node.server = server # set custom icon if self.image_file: self.node.icon = self.image_file # update canvas node self.canvas_node.image = self.image # redraw self.canvas_node.redraw() self.destroy()
def create_node( self, x: float, y: float, node_type: core_pb2.NodeType, model: str ) -> core_pb2.Node: """ Add node, with information filled in, to grpc manager """ node_id = self.next_node_id() position = core_pb2.Position(x=x, y=y) image = None if NodeUtils.is_image_node(node_type): image = "ubuntu:latest" emane = None if node_type == core_pb2.NodeType.EMANE: emane = self.emane_models[0] name = f"EMANE{node_id}" elif node_type == core_pb2.NodeType.WIRELESS_LAN: name = f"WLAN{node_id}" elif node_type in [core_pb2.NodeType.RJ45, core_pb2.NodeType.TUNNEL]: name = "UNASSIGNED" else: name = f"n{node_id}" node = core_pb2.Node( id=node_id, type=node_type, name=name, model=model, position=position, image=image, emane=emane, ) if NodeUtils.is_custom(node_type, model): services = NodeUtils.get_custom_node_services(self.app.guiconfig, model) node.services[:] = services logging.info( "add node(%s) to session(%s), coordinates(%s, %s)", node.name, self.session_id, x, y, ) return node
def create_link(self, edge, canvas_src_node, canvas_dst_node): """ Create core link for a pair of canvas nodes, with token referencing the canvas edge. :param edge: edge for link :param canvas_src_node: canvas node one :param canvas_dst_node: canvas node two :return: nothing """ src_node = canvas_src_node.core_node dst_node = canvas_dst_node.core_node # determine subnet self.interfaces_manager.determine_subnet(canvas_src_node, canvas_dst_node) src_interface = None if NodeUtils.is_container_node(src_node.type): src_interface = self.create_interface(canvas_src_node) edge.src_interface = src_interface self.interface_to_edge[(src_node.id, src_interface.id)] = edge.token dst_interface = None if NodeUtils.is_container_node(dst_node.type): dst_interface = self.create_interface(canvas_dst_node) edge.dst_interface = dst_interface self.interface_to_edge[(dst_node.id, dst_interface.id)] = edge.token link = core_pb2.Link( type=core_pb2.LinkType.WIRED, node_one_id=src_node.id, node_two_id=dst_node.id, interface_one=src_interface, interface_two=dst_interface, ) edge.set_link(link) self.links[edge.token] = edge
def on_enter(self, event: tk.Event) -> None: is_runtime = self.app.core.is_runtime() has_observer = self.app.core.observer is not None is_container = NodeUtils.is_container_node(self.core_node.type) if is_runtime and has_observer and is_container: self.tooltip.text.set("waiting...") self.tooltip.on_enter(event) try: output = self.app.core.run(self.core_node.id) self.tooltip.text.set(output) except grpc.RpcError as e: self.app.show_grpc_exception("Observer Error", e)