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 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 test_delete_link(self, grpc_server: CoreGrpcServer, ip_prefixes: IpPrefixes): # given client = CoreGrpcClient() session = grpc_server.coreemu.create_session() node1 = session.add_node(CoreNode) iface1 = ip_prefixes.create_iface(node1) node2 = session.add_node(CoreNode) iface2 = ip_prefixes.create_iface(node2) session.add_link(node1.id, node2.id, iface1, iface2) link_node = None for node_id in session.nodes: node = session.nodes[node_id] if node.id not in {node1.id, node2.id}: link_node = node break assert len(link_node.links()) == 1 link = Link( node1.id, node2.id, iface1=Interface(id=iface1.id), iface2=Interface(id=iface2.id), ) # then with client.context_connect(): result = client.delete_link(session.id, link) # then assert result is True assert len(link_node.links()) == 0
def test_edit_link(self, grpc_server: CoreGrpcServer, ip_prefixes: IpPrefixes): # given client = CoreGrpcClient() session = grpc_server.coreemu.create_session() switch = session.add_node(SwitchNode) node = session.add_node(CoreNode) iface = ip_prefixes.create_iface(node) session.add_link(node.id, switch.id, iface) options = LinkOptions(bandwidth=30000) link = switch.links()[0] assert options.bandwidth != link.options.bandwidth link = Link(node.id, switch.id, iface1=Interface(id=iface.id), options=options) # then with client.context_connect(): result = client.edit_link(session.id, link) # then assert result is True link = switch.links()[0] assert options.bandwidth == link.options.bandwidth
def click_apply(self) -> None: self.app.canvas.itemconfigure(self.edge.id, width=self.width.get()) self.app.canvas.itemconfigure(self.edge.id, fill=self.color.get()) link = self.edge.link bandwidth = get_int(self.bandwidth) jitter = get_int(self.jitter) delay = get_int(self.delay) duplicate = get_int(self.duplicate) loss = get_float(self.loss) options = LinkOptions( bandwidth=bandwidth, jitter=jitter, delay=delay, dup=duplicate, loss=loss ) link.options = options iface1_id = link.iface1.id if link.iface1 else None iface2_id = link.iface2.id if link.iface2 else None if not self.is_symmetric: link.options.unidirectional = True asym_iface1 = None if iface1_id is not None: asym_iface1 = Interface(id=iface1_id) asym_iface2 = None if iface2_id is not None: asym_iface2 = Interface(id=iface2_id) down_bandwidth = get_int(self.down_bandwidth) down_jitter = get_int(self.down_jitter) down_delay = get_int(self.down_delay) down_duplicate = get_int(self.down_duplicate) down_loss = get_float(self.down_loss) options = LinkOptions( bandwidth=down_bandwidth, jitter=down_jitter, delay=down_delay, dup=down_duplicate, loss=down_loss, unidirectional=True, ) self.edge.asymmetric_link = Link( node1_id=link.node2_id, node2_id=link.node1_id, iface1=asym_iface2, iface2=asym_iface1, options=options, ) else: link.options.unidirectional = False self.edge.asymmetric_link = None if self.app.core.is_runtime() and link.options: self.app.core.edit_link(link) if self.edge.asymmetric_link: self.app.core.edit_link(self.edge.asymmetric_link) # update edge label self.edge.draw_link_options() self.destroy()
def test_add_link_exception(self, grpc_server: CoreGrpcServer): # given client = CoreGrpcClient() session = grpc_server.coreemu.create_session() node = session.add_node(CoreNode) # then link = Link(node.id, 3) with pytest.raises(grpc.RpcError): with client.context_connect(): client.add_link(session.id, link)
def test_add_link(self, grpc_server: CoreGrpcServer): # given client = CoreGrpcClient() session = grpc_server.coreemu.create_session() switch = session.add_node(SwitchNode) node = session.add_node(CoreNode) assert len(switch.links()) == 0 iface = InterfaceHelper("10.0.0.0/24").create_iface(node.id, 0) link = Link(node.id, switch.id, iface1=iface) # then with client.context_connect(): result, iface1, _ = client.add_link(session.id, link) # then assert result is True assert len(switch.links()) == 1 assert iface1.id == iface.id assert iface1.ip4 == iface.ip4
def add_link(self, session_id: int, link: wrappers.Link, source: str = None ) -> Tuple[bool, wrappers.Interface, wrappers.Interface]: """ Add a link between nodes. :param session_id: session id :param link: link to add :param source: application source :return: tuple of result and finalized interface values :raises grpc.RpcError: when session or one of the nodes don't exist """ request = core_pb2.AddLinkRequest(session_id=session_id, link=link.to_proto(), source=source) response = self.stub.AddLink(request) iface1 = wrappers.Interface.from_proto(response.iface1) iface2 = wrappers.Interface.from_proto(response.iface2) return response.result, iface1, iface2
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
def paste_selected(self, _event: tk.Event = None) -> None: if self.core.is_runtime(): logger.debug("paste is disabled during runtime state") return # maps original node canvas id to copy node canvas id copy_map = {} # the edges that will be copy over to_copy_edges = set() to_copy_ids = {x.id for x in self.to_copy} for canvas_node in self.to_copy: core_node = canvas_node.core_node actual_x = core_node.position.x + 50 actual_y = core_node.position.y + 50 scaled_x, scaled_y = self.get_scaled_coords(actual_x, actual_y) copy = self.core.create_node(actual_x, actual_y, core_node.type, core_node.model) if not copy: continue node = CanvasNode(self.app, self, scaled_x, scaled_y, copy, canvas_node.image) # copy configurations and services node.core_node.services = core_node.services.copy() node.core_node.config_services = core_node.config_services.copy() node.core_node.emane_model_configs = deepcopy( core_node.emane_model_configs) node.core_node.wlan_config = deepcopy(core_node.wlan_config) node.core_node.mobility_config = deepcopy( core_node.mobility_config) node.core_node.service_configs = deepcopy( core_node.service_configs) node.core_node.service_file_configs = deepcopy( core_node.service_file_configs) node.core_node.config_service_configs = deepcopy( core_node.config_service_configs) copy_map[canvas_node.id] = node.id self.nodes[node.id] = node self.core.set_canvas_node(copy, node) for edge in canvas_node.edges: if edge.src not in to_copy_ids or edge.dst not in to_copy_ids: if canvas_node.id == edge.src: dst_node = self.nodes[edge.dst] copy_edge = self.create_edge(node, dst_node) elif canvas_node.id == edge.dst: src_node = self.nodes[edge.src] copy_edge = self.create_edge(src_node, node) else: continue copy_link = copy_edge.link iface1_id = copy_link.iface1.id if copy_link.iface1 else None iface2_id = copy_link.iface2.id if copy_link.iface2 else None options = edge.link.options if options: copy_edge.link.options = deepcopy(options) if options and options.unidirectional: asym_iface1 = None if iface1_id is not None: asym_iface1 = Interface(id=iface1_id) asym_iface2 = None if iface2_id is not None: asym_iface2 = Interface(id=iface2_id) copy_edge.asymmetric_link = Link( node1_id=copy_link.node2_id, node2_id=copy_link.node1_id, iface1=asym_iface2, iface2=asym_iface1, options=deepcopy(edge.asymmetric_link.options), ) copy_edge.redraw() else: to_copy_edges.add(edge) # copy link and link config for edge in to_copy_edges: src_node_id = copy_map[edge.src] dst_node_id = copy_map[edge.dst] src_node_copy = self.nodes[src_node_id] dst_node_copy = self.nodes[dst_node_id] copy_edge = self.create_edge(src_node_copy, dst_node_copy) copy_link = copy_edge.link iface1_id = copy_link.iface1.id if copy_link.iface1 else None iface2_id = copy_link.iface2.id if copy_link.iface2 else None options = edge.link.options if options: copy_link.options = deepcopy(options) if options and options.unidirectional: asym_iface1 = None if iface1_id is not None: asym_iface1 = Interface(id=iface1_id) asym_iface2 = None if iface2_id is not None: asym_iface2 = Interface(id=iface2_id) copy_edge.asymmetric_link = Link( node1_id=copy_link.node2_id, node2_id=copy_link.node1_id, iface1=asym_iface2, iface2=asym_iface1, options=deepcopy(edge.asymmetric_link.options), ) copy_edge.redraw() self.itemconfig( copy_edge.id, width=self.itemcget(edge.id, "width"), fill=self.itemcget(edge.id, "fill"), ) self.tag_raise(tags.NODE)
def test_start_session(self, grpc_server: CoreGrpcServer, definition): # given client = CoreGrpcClient() with client.context_connect(): session = client.create_session() position = Position(x=50, y=100) node1 = session.add_node(1, position=position) position = Position(x=100, y=100) node2 = session.add_node(2, position=position) position = Position(x=200, y=200) wlan_node = session.add_node(3, _type=NodeType.WIRELESS_LAN, position=position) iface_helper = InterfaceHelper(ip4_prefix="10.83.0.0/16") iface1_id = 0 iface1 = iface_helper.create_iface(node1.id, iface1_id) iface2_id = 0 iface2 = iface_helper.create_iface(node2.id, iface2_id) link = Link(node1_id=node1.id, node2_id=node2.id, iface1=iface1, iface2=iface2) session.links = [link] hook = Hook(state=SessionState.RUNTIME, file="echo.sh", data="echo hello") session.hooks = {hook.file: hook} location_x = 5 location_y = 10 location_z = 15 location_lat = 20 location_lon = 30 location_alt = 40 location_scale = 5 session.location = SessionLocation( x=location_x, y=location_y, z=location_z, lat=location_lat, lon=location_lon, alt=location_alt, scale=location_scale, ) # setup wlan config wlan_config_key = "range" wlan_config_value = "333" wlan_node.set_wlan({wlan_config_key: wlan_config_value}) # setup mobility config mobility_config_key = "refresh_ms" mobility_config_value = "60" wlan_node.set_mobility({mobility_config_key: mobility_config_value}) # setup service config service_name = "DefaultRoute" service_validate = ["echo hello"] node1.service_configs[service_name] = NodeServiceData( executables=[], dependencies=[], dirs=[], configs=[], startup=[], validate=service_validate, validation_mode=ServiceValidationMode.NON_BLOCKING, validation_timer=0, shutdown=[], meta="", ) # setup service file config service_file = "defaultroute.sh" service_file_data = "echo hello" node1.service_file_configs[service_name] = { service_file: service_file_data } # setup session option option_key = "controlnet" option_value = "172.16.0.0/24" session.set_options({option_key: option_value}) # when with patch.object(CoreXmlWriter, "write"): with client.context_connect(): client.start_session(session, definition=definition) # then real_session = grpc_server.coreemu.sessions[session.id] if definition: state = EventTypes.DEFINITION_STATE else: state = EventTypes.RUNTIME_STATE assert real_session.state == state assert node1.id in real_session.nodes assert node2.id in real_session.nodes assert wlan_node.id in real_session.nodes assert iface1_id in real_session.nodes[node1.id].ifaces assert iface2_id in real_session.nodes[node2.id].ifaces hook_file, hook_data = real_session.hooks[EventTypes.RUNTIME_STATE][0] assert hook_file == hook.file assert hook_data == hook.data assert real_session.location.refxyz == (location_x, location_y, location_z) assert real_session.location.refgeo == ( location_lat, location_lon, location_alt, ) assert real_session.location.refscale == location_scale set_wlan_config = real_session.mobility.get_model_config( wlan_node.id, BasicRangeModel.name) assert set_wlan_config[wlan_config_key] == wlan_config_value set_mobility_config = real_session.mobility.get_model_config( wlan_node.id, Ns2ScriptedMobility.name) assert set_mobility_config[ mobility_config_key] == mobility_config_value service = real_session.services.get_service(node1.id, service_name, default_service=True) assert service.validate == tuple(service_validate) real_node1 = real_session.get_node(node1.id, CoreNode) service_file = real_session.services.get_service_file( real_node1, service_name, service_file) assert service_file.data == service_file_data assert option_value == real_session.options.get_config(option_key)