initial changes to mimic prior address creation
This commit is contained in:
parent
7e0ead0766
commit
9a42368221
3 changed files with 70 additions and 32 deletions
|
@ -830,6 +830,7 @@ class CoreClient:
|
||||||
such as link, configurations, interfaces
|
such as link, configurations, interfaces
|
||||||
"""
|
"""
|
||||||
edges = set()
|
edges = set()
|
||||||
|
removed_links = []
|
||||||
for canvas_node in canvas_nodes:
|
for canvas_node in canvas_nodes:
|
||||||
node_id = canvas_node.core_node.id
|
node_id = canvas_node.core_node.id
|
||||||
if node_id not in self.canvas_nodes:
|
if node_id not in self.canvas_nodes:
|
||||||
|
@ -841,11 +842,14 @@ class CoreClient:
|
||||||
if edge in edges:
|
if edge in edges:
|
||||||
continue
|
continue
|
||||||
edges.add(edge)
|
edges.add(edge)
|
||||||
self.links.pop(edge.token, None)
|
edge = self.links.pop(edge.token, None)
|
||||||
|
if edge is not None:
|
||||||
|
removed_links.append(edge.link)
|
||||||
|
self.interfaces_manager.removed(removed_links)
|
||||||
|
|
||||||
def create_interface(self, canvas_node: CanvasNode) -> core_pb2.Interface:
|
def create_interface(self, canvas_node: CanvasNode) -> core_pb2.Interface:
|
||||||
node = canvas_node.core_node
|
node = canvas_node.core_node
|
||||||
ip4, ip6 = self.interfaces_manager.get_ips(node.id)
|
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 = len(canvas_node.interfaces)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
import random
|
from typing import TYPE_CHECKING, List, Set, Tuple, Union
|
||||||
from typing import TYPE_CHECKING, Set, Union
|
|
||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
from netaddr import EUI, IPNetwork
|
from netaddr import EUI, IPNetwork
|
||||||
|
@ -14,20 +13,20 @@ if TYPE_CHECKING:
|
||||||
from core.gui.graph.node import CanvasNode
|
from core.gui.graph.node import CanvasNode
|
||||||
|
|
||||||
|
|
||||||
def random_mac():
|
|
||||||
return ("{:02x}" * 6).format(*[random.randrange(256) for _ in range(6)])
|
|
||||||
|
|
||||||
|
|
||||||
class Subnets:
|
class Subnets:
|
||||||
def __init__(self, ip4: IPNetwork, ip6: IPNetwork) -> None:
|
def __init__(self, ip4: IPNetwork, ip6: IPNetwork) -> None:
|
||||||
self.ip4 = ip4
|
self.ip4 = ip4
|
||||||
self.ip6 = ip6
|
self.ip6 = ip6
|
||||||
|
self.used_indexes = set()
|
||||||
|
|
||||||
def __eq__(self, other: "Subnets") -> bool:
|
def __eq__(self, other: "Subnets") -> bool:
|
||||||
return (self.ip4, self.ip6) == (other.ip4, other.ip6)
|
return self.key() == other.key()
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int:
|
||||||
return hash((self.ip4, self.ip6))
|
return hash(self.key())
|
||||||
|
|
||||||
|
def key(self) -> Tuple[IPNetwork, IPNetwork]:
|
||||||
|
return self.ip4, self.ip6
|
||||||
|
|
||||||
def next(self) -> "Subnets":
|
def next(self) -> "Subnets":
|
||||||
return Subnets(self.ip4.next(), self.ip6.next())
|
return Subnets(self.ip4.next(), self.ip6.next())
|
||||||
|
@ -47,6 +46,7 @@ class InterfaceManager:
|
||||||
self.mac = EUI(mac)
|
self.mac = EUI(mac)
|
||||||
self.current_mac = None
|
self.current_mac = None
|
||||||
self.current_subnets = None
|
self.current_subnets = None
|
||||||
|
self.used_subnets = {}
|
||||||
|
|
||||||
def update_ips(self, ip4: str, ip6: str) -> None:
|
def update_ips(self, ip4: str, ip6: str) -> None:
|
||||||
self.reset()
|
self.reset()
|
||||||
|
@ -65,37 +65,66 @@ class InterfaceManager:
|
||||||
return mac
|
return mac
|
||||||
|
|
||||||
def next_subnets(self) -> Subnets:
|
def next_subnets(self) -> Subnets:
|
||||||
# define currently used subnets
|
subnets = self.current_subnets
|
||||||
used_subnets = set()
|
if subnets is None:
|
||||||
for edge in self.app.core.links.values():
|
|
||||||
link = edge.link
|
|
||||||
subnets = None
|
|
||||||
if link.HasField("interface_one"):
|
|
||||||
subnets = self.get_subnets(link.interface_one)
|
|
||||||
if link.HasField("interface_two"):
|
|
||||||
subnets = self.get_subnets(link.interface_two)
|
|
||||||
if subnets:
|
|
||||||
used_subnets.add(subnets)
|
|
||||||
|
|
||||||
# find next available subnets
|
|
||||||
subnets = Subnets(self.ip4_subnets, self.ip6_subnets)
|
subnets = Subnets(self.ip4_subnets, self.ip6_subnets)
|
||||||
while subnets in used_subnets:
|
while subnets.key() in self.used_subnets:
|
||||||
subnets = subnets.next()
|
subnets = subnets.next()
|
||||||
|
self.used_subnets[subnets.key()] = subnets
|
||||||
return subnets
|
return subnets
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.current_subnets = None
|
self.current_subnets = None
|
||||||
|
self.used_subnets.clear()
|
||||||
|
|
||||||
def get_ips(self, node_id: int) -> [str, str]:
|
def removed(self, links: List["core_pb2.Link"]):
|
||||||
ip4 = self.current_subnets.ip4[node_id]
|
# get remaining subnets
|
||||||
ip6 = self.current_subnets.ip6[node_id]
|
remaining_subnets = set()
|
||||||
|
|
||||||
|
for link in links:
|
||||||
|
if link.HasField("interface_one"):
|
||||||
|
subnets = self.get_subnets(link.interface_one)
|
||||||
|
if subnets not in remaining_subnets:
|
||||||
|
self.used_subnets.pop(subnets.key(), None)
|
||||||
|
if link.HasField("interface_two"):
|
||||||
|
subnets = self.get_subnets(link.interface_two)
|
||||||
|
if subnets not in remaining_subnets:
|
||||||
|
self.used_subnets.pop(subnets.key(), None)
|
||||||
|
|
||||||
|
def initialize_links(self, links: List["core_pb2.Link"]):
|
||||||
|
for link in links:
|
||||||
|
if link.HasField("interface_one"):
|
||||||
|
subnets = self.get_subnets(link.interface_one)
|
||||||
|
if subnets.key() not in self.used_subnets:
|
||||||
|
self.used_subnets[subnets.key()] = subnets
|
||||||
|
if link.HasField("interface_two"):
|
||||||
|
subnets = self.get_subnets(link.interface_two)
|
||||||
|
if subnets.key() not in self.used_subnets:
|
||||||
|
self.used_subnets[subnets.key()] = subnets
|
||||||
|
|
||||||
|
def next_index(self, node: "core_pb2.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 get_ips(self, node: "core_pb2.Node") -> [str, str]:
|
||||||
|
index = self.next_index(node)
|
||||||
|
ip4 = self.current_subnets.ip4[index]
|
||||||
|
ip6 = self.current_subnets.ip6[index]
|
||||||
return str(ip4), str(ip6)
|
return str(ip4), str(ip6)
|
||||||
|
|
||||||
@classmethod
|
def get_subnets(self, interface: "core_pb2.Interface") -> Subnets:
|
||||||
def get_subnets(cls, interface: "core_pb2.Interface") -> Subnets:
|
|
||||||
ip4_subnet = IPNetwork(f"{interface.ip4}/{interface.ip4mask}").cidr
|
ip4_subnet = IPNetwork(f"{interface.ip4}/{interface.ip4mask}").cidr
|
||||||
ip6_subnet = IPNetwork(f"{interface.ip6}/{interface.ip6mask}").cidr
|
ip6_subnet = IPNetwork(f"{interface.ip6}/{interface.ip6mask}").cidr
|
||||||
return Subnets(ip4_subnet, ip6_subnet)
|
subnets = Subnets(ip4_subnet, ip6_subnet)
|
||||||
|
return self.used_subnets.get(subnets.key(), subnets)
|
||||||
|
|
||||||
def determine_subnets(
|
def determine_subnets(
|
||||||
self, canvas_src_node: "CanvasNode", canvas_dst_node: "CanvasNode"
|
self, canvas_src_node: "CanvasNode", canvas_dst_node: "CanvasNode"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Union
|
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Union
|
||||||
|
|
||||||
from core.api.grpc.core_pb2 import NodeType
|
from core.api.grpc.core_pb2 import Node, NodeType
|
||||||
from core.gui.images import ImageEnum, Images, TypeToImage
|
from core.gui.images import ImageEnum, Images, TypeToImage
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -64,8 +64,13 @@ class NodeUtils:
|
||||||
RJ45_NODES = {NodeType.RJ45}
|
RJ45_NODES = {NodeType.RJ45}
|
||||||
IGNORE_NODES = {NodeType.CONTROL_NET, NodeType.PEER_TO_PEER}
|
IGNORE_NODES = {NodeType.CONTROL_NET, NodeType.PEER_TO_PEER}
|
||||||
NODE_MODELS = {"router", "host", "PC", "mdr", "prouter"}
|
NODE_MODELS = {"router", "host", "PC", "mdr", "prouter"}
|
||||||
|
ROUTER_NODES = {"router", "mdr"}
|
||||||
ANTENNA_ICON = None
|
ANTENNA_ICON = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_router_node(cls, node: Node) -> bool:
|
||||||
|
return cls.is_model_node(node.type) and node.model in cls.ROUTER_NODES
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_ignore_node(cls, node_type: NodeType) -> bool:
|
def is_ignore_node(cls, node_type: NodeType) -> bool:
|
||||||
return node_type in cls.IGNORE_NODES
|
return node_type in cls.IGNORE_NODES
|
||||||
|
|
Loading…
Reference in a new issue