updates to add reuse of deleted subnets

This commit is contained in:
bharnden 2019-11-22 23:48:10 -08:00
parent e8f8fa3bd5
commit 4e32c9c13c
4 changed files with 83 additions and 43 deletions

View file

@ -469,38 +469,64 @@ class CoreClient:
) )
return node return node
def delete_graph_nodes(self, node_ids, edges): def delete_graph_nodes(self, canvas_nodes):
""" """
remove the nodes selected by the user and anything related to that node remove the nodes selected by the user and anything related to that node
such as link, configurations, interfaces such as link, configurations, interfaces
:param list[int] node_ids: list of nodes to delete :param list canvas_nodes: list of nodes to delete
:param list edges: list of edges to delete
:return: nothing :return: nothing
""" """
# delete the nodes edges = set()
for i in node_ids: for canvas_node in canvas_nodes:
try: node_id = canvas_node.core_node.id
del self.canvas_nodes[i] if node_id not in self.canvas_nodes:
self.reusable.append(i) logging.error("unknown node: %s", node_id)
if i in self.mobility_configs: continue
del self.mobility_configs[i] del self.canvas_nodes[node_id]
if i in self.wlan_configs: self.reusable.append(node_id)
del self.wlan_configs[i] if node_id in self.mobility_configs:
for key in list(self.emane_model_configs): del self.mobility_configs[node_id]
node_id, _, _ = key if node_id in self.wlan_configs:
if node_id == i: del self.wlan_configs[node_id]
del self.emane_model_configs[key] for key in list(self.emane_model_configs):
except KeyError: node_id, _, _ = key
logging.error("invalid canvas id: %s", i) if node_id == node_id:
self.reusable.sort() del self.emane_model_configs[key]
# delete the edges and interfaces deleted_cidrs = set()
for edge in edges: keep_cidrs = set()
try: for edge in canvas_node.edges:
self.links.pop(edge.token) if edge in edges:
except KeyError: continue
logging.error("invalid edge token: %s", edge.token) edges.add(edge)
if edge.token not in self.links:
logging.error("unknown edge: %s", edge.token)
del self.links[edge.token]
other_id = edge.src
other_interface = edge.src_interface
interface = edge.dst_interface
if canvas_node.id == edge.src:
other_id = edge.dst
other_interface = edge.dst_interface
interface = edge.src_interface
other_node = self.app.canvas.nodes.get(other_id)
if not other_node:
continue
if other_interface:
cidr = self.interfaces_manager.get_cidr(other_interface)
deleted_cidrs.add(cidr)
else:
cidr = self.interfaces_manager.find_subnet(other_node)
if cidr:
keep_cidrs.add(cidr)
else:
cidr = self.interfaces_manager.get_cidr(interface)
deleted_cidrs.add(cidr)
deleted_cidrs = deleted_cidrs - keep_cidrs
for cidr in deleted_cidrs:
self.interfaces_manager.deleted_cidr(cidr)
self.reusable.sort()
def create_interface(self, canvas_node): def create_interface(self, canvas_node):
node = canvas_node.core_node node = canvas_node.core_node

View file

@ -389,10 +389,10 @@ class CanvasGraph(tk.Canvas):
:return: :return:
""" """
# delete canvas data # delete canvas data
node_ids, edges = self.canvas_management.delete_selected_nodes() nodes = self.canvas_management.delete_selected_nodes()
# delete core data # delete core data
self.core.delete_graph_nodes(node_ids, edges) self.core.delete_graph_nodes(nodes)
def add_node(self, x, y): def add_node(self, x, y):
plot_id = self.find_all()[0] plot_id = self.find_all()[0]

View file

@ -29,12 +29,22 @@ class InterfaceManager:
return str(ip4), str(ip6), self.current.prefixlen return str(ip4), str(ip6), self.current.prefixlen
def next_subnet(self): def next_subnet(self):
if self.current: if self.deleted:
self.cidr = self.cidr.next() return self.deleted.pop(0)
return self.cidr else:
if self.current:
self.cidr = self.cidr.next()
return self.cidr
def deleted_interface(self, interface): def deleted_cidr(self, cidr):
logging.info("deleted interface: %s", interface) logging.info("deleted cidr: %s", cidr)
if cidr not in self.deleted:
self.deleted.append(cidr)
self.deleted.sort()
@classmethod
def get_cidr(cls, interface):
return IPNetwork(f"{interface.ip4}/{interface.ip4mask}").cidr
def determine_subnet(self, canvas_src_node, canvas_dst_node): def determine_subnet(self, canvas_src_node, canvas_dst_node):
src_node = canvas_src_node.core_node src_node = canvas_src_node.core_node
@ -49,21 +59,21 @@ class InterfaceManager:
self.current = cidr self.current = cidr
else: else:
self.current = self.next_subnet() self.current = self.next_subnet()
# else:
# self.current = self.cidr
elif not is_src_container and is_dst_container: elif not is_src_container and is_dst_container:
cidr = self.find_subnet(canvas_src_node, visited={dst_node.id}) cidr = self.find_subnet(canvas_src_node, visited={dst_node.id})
if cidr: if cidr:
self.current = self.cidr self.current = cidr
else: else:
self.current = self.next_subnet() self.current = self.next_subnet()
else: else:
logging.info("ignoring subnet change for link between network nodes") logging.info("ignoring subnet change for link between network nodes")
def find_subnet(self, canvas_node, visited): def find_subnet(self, canvas_node, visited=None):
logging.info("finding subnet for node: %s", canvas_node.core_node.name) logging.info("finding subnet for node: %s", canvas_node.core_node.name)
canvas = self.app.canvas canvas = self.app.canvas
cidr = None cidr = None
if not visited:
visited = set()
visited.add(canvas_node.core_node.id) visited.add(canvas_node.core_node.id)
for edge in canvas_node.edges: for edge in canvas_node.edges:
src_node = canvas.nodes[edge.src] src_node = canvas.nodes[edge.src]
@ -77,9 +87,10 @@ class InterfaceManager:
continue continue
visited.add(check_node.core_node.id) visited.add(check_node.core_node.id)
if interface: if interface:
logging.info("found interface: %s", interface) cidr = self.get_cidr(interface)
cidr = IPNetwork(f"{interface.ip4}/{interface.ip4mask}").cidr
break
else: else:
cidr = self.find_subnet(check_node, visited) cidr = self.find_subnet(check_node, visited)
if cidr:
logging.info("found subnet: %s", cidr)
break
return cidr return cidr

View file

@ -40,11 +40,11 @@ class CanvasComponentManagement:
def delete_selected_nodes(self): def delete_selected_nodes(self):
edges = set() edges = set()
node_ids = [] nodes = []
for node_id in list(self.selected): for node_id in list(self.selected):
bbox_id = self.selected[node_id] bbox_id = self.selected[node_id]
canvas_node = self.canvas.nodes.pop(node_id) canvas_node = self.canvas.nodes.pop(node_id)
node_ids.append(canvas_node.core_node.id) nodes.append(canvas_node)
self.canvas.delete(node_id) self.canvas.delete(node_id)
self.canvas.delete(bbox_id) self.canvas.delete(bbox_id)
self.canvas.delete(canvas_node.text_id) self.canvas.delete(canvas_node.text_id)
@ -63,6 +63,9 @@ class CanvasComponentManagement:
other_interface = edge.dst_interface other_interface = edge.dst_interface
other_node = self.canvas.nodes[other_id] other_node = self.canvas.nodes[other_id]
other_node.edges.remove(edge) other_node.edges.remove(edge)
other_node.interfaces.remove(other_interface) try:
other_node.interfaces.remove(other_interface)
except ValueError:
pass
self.selected.clear() self.selected.clear()
return node_ids, edges return nodes