Exemple #1
0
 def save_edge(self, edge: CanvasEdge) -> None:
     self.links[edge.token] = edge
     src_node = edge.src.core_node
     dst_node = edge.dst.core_node
     if nutils.is_container(src_node):
         src_iface_id = edge.link.iface1.id
         self.iface_to_edge[(src_node.id, src_iface_id)] = edge
     if nutils.is_container(dst_node):
         dst_iface_id = edge.link.iface2.id
         self.iface_to_edge[(dst_node.id, dst_iface_id)] = edge
Exemple #2
0
    def click_apply(self) -> None:
        error = False

        # update core node
        self.node.name = self.name.get()
        if nutils.has_image(self.node.type):
            self.node.image = self.container_image.get()
        server = self.server.get()
        if nutils.is_container(self.node):
            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()
Exemple #3
0
 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 nutils.is_container(node):
             self.executable_nodes[node.name] = node.id
Exemple #4
0
 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 = nutils.is_container(self.core_node)
     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)
Exemple #5
0
 def get_service_file_configs(self) -> List[ServiceFileConfig]:
     configs = []
     for node in self.session.nodes.values():
         if not nutils.is_container(node):
             continue
         if not node.service_file_configs:
             continue
         for service, file_configs in node.service_file_configs.items():
             for file, data in file_configs.items():
                 config = ServiceFileConfig(node.id, service, file, data)
                 configs.append(config)
     return configs
Exemple #6
0
 def create_link(self, edge: CanvasEdge) -> Link:
     """
     Create core link for a given edge based on src/dst nodes.
     """
     src_node = edge.src.core_node
     dst_node = edge.dst.core_node
     self.determine_subnets(edge.src, edge.dst)
     src_iface = None
     if nutils.is_container(src_node):
         src_iface = self.create_iface(edge.src, edge.linked_wireless)
     dst_iface = None
     if nutils.is_container(dst_node):
         dst_iface = self.create_iface(edge.dst, edge.linked_wireless)
     link = Link(
         type=LinkType.WIRED,
         node1_id=src_node.id,
         node2_id=dst_node.id,
         iface1=src_iface,
         iface2=dst_iface,
     )
     logger.info("added link between %s and %s", src_node.name, dst_node.name)
     return link
Exemple #7
0
 def draw(self) -> None:
     self.columnconfigure(0, weight=1)
     node = self.canvas_node.core_node
     frame = DetailsFrame(self)
     frame.grid(sticky=tk.EW)
     frame.add_detail("ID", str(node.id))
     frame.add_detail("Name", node.name)
     if nutils.is_model(node):
         frame.add_detail("Type", node.model)
     if nutils.is_container(node):
         for index, service in enumerate(sorted(node.services)):
             if index == 0:
                 frame.add_detail("Services", service)
             else:
                 frame.add_detail("", service)
     if node.type == NodeType.EMANE:
         emane = "".join(node.emane.split("_")[1:])
         frame.add_detail("EMANE", emane)
     if nutils.has_image(node.type):
         frame.add_detail("Image", node.image)
     if nutils.is_container(node):
         server = node.server if node.server else "localhost"
         frame.add_detail("Server", server)
Exemple #8
0
 def determine_subnets(
     self, canvas_src_node: CanvasNode, canvas_dst_node: CanvasNode
 ) -> None:
     src_node = canvas_src_node.core_node
     dst_node = canvas_dst_node.core_node
     is_src_container = nutils.is_container(src_node)
     is_dst_container = nutils.is_container(dst_node)
     if is_src_container and is_dst_container:
         self.current_subnets = self.next_subnets()
     elif is_src_container and not is_dst_container:
         subnets = self.find_subnets(canvas_dst_node, visited={src_node.id})
         if subnets:
             self.current_subnets = subnets
         else:
             self.current_subnets = self.next_subnets()
     elif not is_src_container and is_dst_container:
         subnets = self.find_subnets(canvas_src_node, visited={dst_node.id})
         if subnets:
             self.current_subnets = subnets
         else:
             self.current_subnets = self.next_subnets()
     else:
         logger.info("ignoring subnet change for link between network nodes")
Exemple #9
0
 def get_service_file_configs_proto(
         self) -> List[services_pb2.ServiceFileConfig]:
     configs = []
     for node in self.session.nodes.values():
         if not nutils.is_container(node):
             continue
         if not node.service_file_configs:
             continue
         for service, file_configs in node.service_file_configs.items():
             for file, data in file_configs.items():
                 config_proto = services_pb2.ServiceFileConfig(
                     node_id=node.id, service=service, file=file, data=data)
                 configs.append(config_proto)
     return configs
Exemple #10
0
 def get_config_service_configs_proto(
         self) -> List[configservices_pb2.ConfigServiceConfig]:
     config_service_protos = []
     for node in self.session.nodes.values():
         if not nutils.is_container(node):
             continue
         if not node.config_service_configs:
             continue
         for name, service_config in node.config_service_configs.items():
             config_proto = configservices_pb2.ConfigServiceConfig(
                 node_id=node.id,
                 name=name,
                 templates=service_config.templates,
                 config=service_config.config,
             )
             config_service_protos.append(config_proto)
     return config_service_protos
Exemple #11
0
 def get_service_configs(self) -> List[ServiceConfig]:
     configs = []
     for node in self.session.nodes.values():
         if not nutils.is_container(node):
             continue
         if not node.service_configs:
             continue
         for name, config in node.service_configs.items():
             config = ServiceConfig(
                 node_id=node.id,
                 service=name,
                 files=config.configs,
                 directories=config.dirs,
                 startup=config.startup,
                 validate=config.validate,
                 shutdown=config.shutdown,
             )
             configs.append(config)
     return configs
Exemple #12
0
    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
        is_mobility = is_wlan or is_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_mobility and self.core_node.id in self.app.core.mobility_players:
                self.context.add_command(
                    label="Mobility Player", command=self.show_mobility_player
                )
            if nutils.is_container(self.core_node):
                services_menu = tk.Menu(self.context)
                for service in sorted(self.core_node.config_services):
                    service_menu = tk.Menu(services_menu)
                    themes.style_menu(service_menu)
                    start_func = functools.partial(self.start_service, service)
                    service_menu.add_command(label="Start", command=start_func)
                    stop_func = functools.partial(self.stop_service, service)
                    service_menu.add_command(label="Stop", command=stop_func)
                    restart_func = functools.partial(self.restart_service, service)
                    service_menu.add_command(label="Restart", command=restart_func)
                    validate_func = functools.partial(self.validate_service, service)
                    service_menu.add_command(label="Validate", command=validate_func)
                    services_menu.add_cascade(label=service, menu=service_menu)
                themes.style_menu(services_menu)
                self.context.add_cascade(label="Services", menu=services_menu)
        else:
            self.context.add_command(label="Configure", command=self.show_config)
            if nutils.is_container(self.core_node):
                self.context.add_command(
                    label="Config Services", command=self.show_config_services
                )
                self.context.add_command(
                    label="Services (Deprecated)", command=self.show_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
                )
            if is_mobility:
                self.context.add_command(
                    label="Mobility Config", command=self.show_mobility_config
                )
            if nutils.is_wireless(self.core_node):
                self.context.add_command(
                    label="Link To Selected", command=self.wireless_link_selected
                )

            link_menu = tk.Menu(self.context)
            for canvas in self.app.manager.all():
                canvas_menu = tk.Menu(link_menu)
                themes.style_menu(canvas_menu)
                for node in canvas.nodes.values():
                    if not self.is_linkable(node):
                        continue
                    func_link = functools.partial(self.click_link, node)
                    canvas_menu.add_command(
                        label=node.core_node.name, command=func_link
                    )
                link_menu.add_cascade(label=f"Canvas {canvas.id}", menu=canvas_menu)
            themes.style_menu(link_menu)
            self.context.add_cascade(label="Link", menu=link_menu)

            unlink_menu = tk.Menu(self.context)
            for edge in self.edges:
                other_node = edge.other_node(self)
                other_iface = edge.other_iface(self)
                label = other_node.core_node.name
                if other_iface:
                    label = f"{label}:{other_iface.name}"
                func_unlink = functools.partial(self.click_unlink, edge)
                unlink_menu.add_command(label=label, 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)
            edit_menu.add_command(label="Hide", command=self.click_hide)
            self.context.add_cascade(label="Edit", menu=edit_menu)
        self.context.tk_popup(event.x_root, event.y_root)
Exemple #13
0
 def double_click(self, event: tk.Event) -> None:
     if self.app.core.is_runtime():
         if nutils.is_container(self.core_node):
             self.canvas.core.launch_terminal(self.core_node.id)
     else:
         self.show_config()
Exemple #14
0
    def draw(self) -> None:
        self.top.columnconfigure(0, weight=1)
        row = 0

        # field states
        state = tk.DISABLED if self.app.core.is_runtime() else tk.NORMAL
        combo_state = tk.DISABLED if self.app.core.is_runtime() else "readonly"

        # field frame
        frame = ttk.Frame(self.top)
        frame.grid(sticky=tk.EW)
        frame.columnconfigure(1, weight=1)

        # icon field
        label = ttk.Label(frame, text="Icon")
        label.grid(row=row, column=0, sticky=tk.EW, padx=PADX, pady=PADY)
        self.image_button = ttk.Button(
            frame,
            text="Icon",
            image=self.image,
            compound=tk.NONE,
            command=self.click_icon,
        )
        self.image_button.grid(row=row, column=1, sticky=tk.EW)
        row += 1

        # name field
        label = ttk.Label(frame, text="Name")
        label.grid(row=row, column=0, sticky=tk.EW, padx=PADX, pady=PADY)
        entry = validation.NodeNameEntry(frame,
                                         textvariable=self.name,
                                         state=state)
        entry.grid(row=row, column=1, sticky=tk.EW)
        row += 1

        # node type field
        if nutils.is_model(self.node):
            label = ttk.Label(frame, text="Type")
            label.grid(row=row, column=0, sticky=tk.EW, padx=PADX, pady=PADY)
            combobox = ttk.Combobox(
                frame,
                textvariable=self.type,
                values=list(nutils.NODE_MODELS),
                state=combo_state,
            )
            combobox.grid(row=row, column=1, sticky=tk.EW)
            row += 1

        # container image field
        if nutils.has_image(self.node.type):
            label = ttk.Label(frame, text="Image")
            label.grid(row=row, column=0, sticky=tk.EW, padx=PADX, pady=PADY)
            entry = ttk.Entry(frame,
                              textvariable=self.container_image,
                              state=state)
            entry.grid(row=row, column=1, sticky=tk.EW)
            row += 1

        if nutils.is_container(self.node):
            # server
            frame.grid(sticky=tk.EW)
            frame.columnconfigure(1, weight=1)
            label = ttk.Label(frame, text="Server")
            label.grid(row=row, column=0, sticky=tk.EW, padx=PADX, pady=PADY)
            servers = [DEFAULT_SERVER]
            servers.extend(list(sorted(self.app.core.servers.keys())))
            combobox = ttk.Combobox(frame,
                                    textvariable=self.server,
                                    values=servers,
                                    state=combo_state)
            combobox.grid(row=row, column=1, sticky=tk.EW)
            row += 1

        if nutils.is_rj45(self.node):
            ifaces = self.app.core.client.get_ifaces()
            logger.debug("host machine available interfaces: %s", ifaces)
            ifaces_scroll = ListboxScroll(frame)
            ifaces_scroll.listbox.config(state=state)
            ifaces_scroll.grid(row=row,
                               column=0,
                               columnspan=2,
                               sticky=tk.EW,
                               padx=PADX,
                               pady=PADY)
            for inf in sorted(ifaces):
                ifaces_scroll.listbox.insert(tk.END, inf)
            row += 1
            ifaces_scroll.listbox.bind("<<ListboxSelect>>", self.iface_select)

        # interfaces
        if self.canvas_node.ifaces:
            self.draw_ifaces()

        self.draw_spacer()
        self.draw_buttons()