pygui: fixed interface creation after deletion, fixed issue reusing deleted subnets

This commit is contained in:
Blake Harnden 2020-05-16 23:35:19 -07:00
parent 91220078f1
commit 06e3d84862
5 changed files with 33 additions and 30 deletions

View file

@ -330,6 +330,9 @@ class CoreClient:
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.show_grpc_exception("Join Session Error", e) self.app.show_grpc_exception("Join Session Error", e)
# organize canvas
self.app.canvas.organize()
# update ui to represent current state # update ui to represent current state
self.app.after(0, self.app.joined_session_update) self.app.after(0, self.app.joined_session_update)
@ -388,7 +391,6 @@ class CoreClient:
self.app.canvas.shapes[shape.id] = shape self.app.canvas.shapes[shape.id] = shape
except ValueError: except ValueError:
logging.exception("unknown shape: %s", shape_type) logging.exception("unknown shape: %s", shape_type)
self.app.canvas.organize()
def create_new_session(self): def create_new_session(self):
""" """
@ -835,7 +837,7 @@ class CoreClient:
ip4, ip6 = self.interfaces_manager.get_ips(node) ip4, ip6 = self.interfaces_manager.get_ips(node)
ip4_mask = self.interfaces_manager.ip4_mask ip4_mask = self.interfaces_manager.ip4_mask
ip6_mask = self.interfaces_manager.ip6_mask ip6_mask = self.interfaces_manager.ip6_mask
interface_id = len(canvas_node.interfaces) interface_id = canvas_node.next_interface_id()
name = f"eth{interface_id}" name = f"eth{interface_id}"
interface = core_pb2.Interface( interface = core_pb2.Interface(
id=interface_id, id=interface_id,
@ -845,7 +847,8 @@ class CoreClient:
ip6=ip6, ip6=ip6,
ip6mask=ip6_mask, ip6mask=ip6_mask,
) )
logging.debug( canvas_node.interfaces[interface.id] = interface
logging.info(
"create node(%s) interface(%s) IPv4(%s) IPv6(%s)", "create node(%s) interface(%s) IPv4(%s) IPv6(%s)",
node.name, node.name,
interface.name, interface.name,
@ -870,11 +873,13 @@ class CoreClient:
src_interface = None src_interface = None
if NodeUtils.is_container_node(src_node.type): if NodeUtils.is_container_node(src_node.type):
src_interface = self.create_interface(canvas_src_node) 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 self.interface_to_edge[(src_node.id, src_interface.id)] = edge.token
dst_interface = None dst_interface = None
if NodeUtils.is_container_node(dst_node.type): if NodeUtils.is_container_node(dst_node.type):
dst_interface = self.create_interface(canvas_dst_node) 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 self.interface_to_edge[(dst_node.id, dst_interface.id)] = edge.token
link = core_pb2.Link( link = core_pb2.Link(
@ -884,12 +889,6 @@ class CoreClient:
interface_one=src_interface, interface_one=src_interface,
interface_two=dst_interface, interface_two=dst_interface,
) )
if src_interface:
edge.src_interface = link.interface_one
canvas_src_node.interfaces.append(link.interface_one)
if dst_interface:
edge.dst_interface = link.interface_two
canvas_dst_node.interfaces.append(link.interface_two)
edge.set_link(link) edge.set_link(link)
self.links[edge.token] = edge self.links[edge.token] = edge
logging.info("Add link between %s and %s", src_node.name, dst_node.name) logging.info("Add link between %s and %s", src_node.name, dst_node.name)

View file

@ -207,8 +207,8 @@ class NodeConfigDialog(Dialog):
notebook.grid(sticky="nsew", pady=PADY) notebook.grid(sticky="nsew", pady=PADY)
self.top.rowconfigure(notebook.grid_info()["row"], weight=1) self.top.rowconfigure(notebook.grid_info()["row"], weight=1)
state = tk.DISABLED if self.app.core.is_runtime() else tk.NORMAL state = tk.DISABLED if self.app.core.is_runtime() else tk.NORMAL
for interface in self.canvas_node.interfaces: for interface_id in sorted(self.canvas_node.interfaces):
logging.info("interface: %s", interface) interface = self.canvas_node.interfaces[interface_id]
tab = ttk.Frame(notebook, padding=FRAME_PAD) tab = ttk.Frame(notebook, padding=FRAME_PAD)
tab.grid(sticky="nsew", pady=PADY) tab.grid(sticky="nsew", pady=PADY)
tab.columnconfigure(1, weight=1) tab.columnconfigure(1, weight=1)
@ -309,7 +309,7 @@ class NodeConfigDialog(Dialog):
self.canvas_node.image = self.image self.canvas_node.image = self.image
# update node interface data # update node interface data
for interface in self.canvas_node.interfaces: for interface in self.canvas_node.interfaces.values():
data = self.interfaces[interface.id] data = self.interfaces[interface.id]
# validate ip4 # validate ip4

View file

@ -322,26 +322,25 @@ class CanvasGraph(tk.Canvas):
self.edges[edge.token] = edge self.edges[edge.token] = edge
self.core.links[edge.token] = edge self.core.links[edge.token] = edge
if link.HasField("interface_one"): if link.HasField("interface_one"):
interface_one = link.interface_one
self.core.interface_to_edge[ self.core.interface_to_edge[
(node_one.id, link.interface_one.id) (node_one.id, interface_one.id)
] = token ] = token
canvas_node_one.interfaces.append(link.interface_one) canvas_node_one.interfaces[interface_one.id] = interface_one
edge.src_interface = link.interface_one edge.src_interface = interface_one
if link.HasField("interface_two"): if link.HasField("interface_two"):
interface_two = link.interface_two
self.core.interface_to_edge[ self.core.interface_to_edge[
(node_two.id, link.interface_two.id) (node_two.id, interface_two.id)
] = edge.token ] = edge.token
canvas_node_two.interfaces.append(link.interface_two) canvas_node_two.interfaces[interface_two.id] = interface_two
edge.dst_interface = link.interface_two edge.dst_interface = interface_two
elif link.options.unidirectional: elif link.options.unidirectional:
edge = self.edges[token] edge = self.edges[token]
edge.asymmetric_link = link edge.asymmetric_link = link
else: else:
logging.error("duplicate link received: %s", link) logging.error("duplicate link received: %s", link)
# raise the nodes so they on top of the links
self.tag_raise(tags.NODE)
def stopped_session(self): def stopped_session(self):
# clear wireless edges # clear wireless edges
for edge in self.wireless_edges.values(): for edge in self.wireless_edges.values():
@ -522,8 +521,8 @@ class CanvasGraph(tk.Canvas):
other_interface = edge.dst_interface other_interface = edge.dst_interface
other_node = self.nodes[other_id] other_node = self.nodes[other_id]
other_node.edges.remove(edge) other_node.edges.remove(edge)
if other_interface in other_node.interfaces: if other_interface:
other_node.interfaces.remove(other_interface) del other_node.interfaces[other_interface.id]
if is_wireless: if is_wireless:
other_node.delete_antenna() other_node.delete_antenna()
@ -541,12 +540,12 @@ class CanvasGraph(tk.Canvas):
del self.edges[edge.token] del self.edges[edge.token]
src_node = self.nodes[edge.src] src_node = self.nodes[edge.src]
src_node.edges.discard(edge) src_node.edges.discard(edge)
if edge.src_interface in src_node.interfaces: if edge.src_interface:
src_node.interfaces.remove(edge.src_interface) del src_node.interfaces[edge.src_interface.id]
dst_node = self.nodes[edge.dst] dst_node = self.nodes[edge.dst]
dst_node.edges.discard(edge) dst_node.edges.discard(edge)
if edge.dst_interface in dst_node.interfaces: if edge.dst_interface:
dst_node.interfaces.remove(edge.dst_interface) del dst_node.interfaces[edge.dst_interface.id]
src_wireless = NodeUtils.is_wireless_node(src_node.core_node.type) src_wireless = NodeUtils.is_wireless_node(src_node.core_node.type)
if src_wireless: if src_wireless:
dst_node.delete_antenna() dst_node.delete_antenna()

View file

@ -55,7 +55,7 @@ class CanvasNode:
) )
self.tooltip = CanvasTooltip(self.canvas) self.tooltip = CanvasTooltip(self.canvas)
self.edges = set() self.edges = set()
self.interfaces = [] self.interfaces = {}
self.wireless_edges = set() self.wireless_edges = set()
self.antennas = [] self.antennas = []
self.antenna_images = {} self.antenna_images = {}
@ -70,6 +70,12 @@ class CanvasNode:
self.context = tk.Menu(self.canvas) self.context = tk.Menu(self.canvas)
themes.style_menu(self.context) themes.style_menu(self.context)
def next_interface_id(self) -> int:
i = 0
while i in self.interfaces:
i += 1
return i
def setup_bindings(self): def setup_bindings(self):
self.canvas.tag_bind(self.id, "<Double-Button-1>", self.double_click) self.canvas.tag_bind(self.id, "<Double-Button-1>", self.double_click)
self.canvas.tag_bind(self.id, "<Enter>", self.on_enter) self.canvas.tag_bind(self.id, "<Enter>", self.on_enter)

View file

@ -105,12 +105,11 @@ class InterfaceManager:
for interface in interfaces: for interface in interfaces:
subnets = self.get_subnets(interface) subnets = self.get_subnets(interface)
if subnets not in remaining_subnets: if subnets not in remaining_subnets:
if self.current_subnets == subnets:
self.current_subnets = None
self.used_subnets.pop(subnets.key(), None) self.used_subnets.pop(subnets.key(), None)
else: else:
index = get_index(interface) index = get_index(interface)
subnets.used_indexes.discard(index) subnets.used_indexes.discard(index)
self.current_subnets = None
def joined(self, links: List["core_pb2.Link"]) -> None: def joined(self, links: List["core_pb2.Link"]) -> None:
interfaces = [] interfaces = []