daemon: updated IpPrefixes and InterfaceHelper to remove duplicate code

This commit is contained in:
Blake Harnden 2020-06-09 18:40:50 -07:00
parent 21da670698
commit d71d84fae7
4 changed files with 53 additions and 106 deletions

View file

@ -8,9 +8,7 @@ from contextlib import contextmanager
from typing import Any, Callable, Dict, Generator, Iterable, List
import grpc
import netaddr
from core import utils
from core.api.grpc import configservices_pb2, core_pb2, core_pb2_grpc
from core.api.grpc.configservices_pb2 import (
GetConfigServiceDefaultsRequest,
@ -94,6 +92,7 @@ from core.api.grpc.wlan_pb2 import (
WlanLinkRequest,
WlanLinkResponse,
)
from core.emulator.emudata import IpPrefixes
class InterfaceHelper:
@ -109,78 +108,20 @@ class InterfaceHelper:
:param ip6_prefix: ip6 prefix to use for generation
:raises ValueError: when both ip4 and ip6 prefixes have not been provided
"""
if not ip4_prefix and not ip6_prefix:
raise ValueError("ip4 or ip6 must be provided")
self.ip4 = None
if ip4_prefix:
self.ip4 = netaddr.IPNetwork(ip4_prefix)
self.ip6 = None
if ip6_prefix:
self.ip6 = netaddr.IPNetwork(ip6_prefix)
def ip4_address(self, node_id: int) -> str:
"""
Convenience method to return the IP4 address for a node.
:param node_id: node id to get IP4 address for
:return: IP4 address or None
"""
if not self.ip4:
raise ValueError("ip4 prefixes have not been set")
return str(self.ip4[node_id])
def ip6_address(self, node_id: int) -> str:
"""
Convenience method to return the IP6 address for a node.
:param node_id: node id to get IP6 address for
:return: IP4 address or None
"""
if not self.ip6:
raise ValueError("ip6 prefixes have not been set")
return str(self.ip6[node_id])
self.prefixes = IpPrefixes(ip4_prefix, ip6_prefix)
def create_interface(
self, node_id: int, interface_id: int, name: str = None, mac: str = None
) -> core_pb2.Interface:
"""
Creates interface data for linking nodes, using the nodes unique id for
generation, along with a random mac address, unless provided.
:param node_id: node id to create interface for
:param interface_id: interface id for interface
:param name: name to set for interface, default is eth{id}
:param mac: mac address to use for this interface, default is random
generation
:return: new interface data for the provided node
"""
# generate ip4 data
ip4 = None
ip4_mask = None
if self.ip4:
ip4 = self.ip4_address(node_id)
ip4_mask = self.ip4.prefixlen
# generate ip6 data
ip6 = None
ip6_mask = None
if self.ip6:
ip6 = self.ip6_address(node_id)
ip6_mask = self.ip6.prefixlen
# random mac
if not mac:
mac = utils.random_mac()
interface_data = self.prefixes.gen_interface(node_id, name, mac)
return core_pb2.Interface(
id=interface_id,
name=name,
ip4=ip4,
ip4mask=ip4_mask,
ip6=ip6,
ip6mask=ip6_mask,
mac=str(mac),
name=interface_data.name,
ip4=interface_data.ip4,
ip4mask=interface_data.ip4_mask,
ip6=interface_data.ip6,
ip6mask=interface_data.ip6_mask,
mac=interface_data.mac,
)

View file

@ -133,27 +133,60 @@ class IpPrefixes:
if ip6_prefix:
self.ip6 = netaddr.IPNetwork(ip6_prefix)
def ip4_address(self, node: "CoreNode") -> str:
def ip4_address(self, node_id: int) -> str:
"""
Convenience method to return the IP4 address for a node.
:param node: node to get IP4 address for
:param node_id: node id to get IP4 address for
:return: IP4 address or None
"""
if not self.ip4:
raise ValueError("ip4 prefixes have not been set")
return str(self.ip4[node.id])
return str(self.ip4[node_id])
def ip6_address(self, node: "CoreNode") -> str:
def ip6_address(self, node_id: int) -> str:
"""
Convenience method to return the IP6 address for a node.
:param node: node to get IP6 address for
:param node_id: node id to get IP6 address for
:return: IP4 address or None
"""
if not self.ip6:
raise ValueError("ip6 prefixes have not been set")
return str(self.ip6[node.id])
return str(self.ip6[node_id])
def gen_interface(self, node_id: int, name: str = None, mac: str = None):
"""
Creates interface data for linking nodes, using the nodes unique id for
generation, along with a random mac address, unless provided.
:param node_id: node id to create an interface for
:param name: name to set for interface, default is eth{id}
:param mac: mac address to use for this interface, default is random
generation
:return: new interface data for the provided node
"""
# generate ip4 data
ip4 = None
ip4_mask = None
if self.ip4:
ip4 = self.ip4_address(node_id)
ip4_mask = self.ip4.prefixlen
# generate ip6 data
ip6 = None
ip6_mask = None
if self.ip6:
ip6 = self.ip6_address(node_id)
ip6_mask = self.ip6.prefixlen
# random mac
if not mac:
mac = utils.random_mac()
return InterfaceData(
name=name, ip4=ip4, ip4_mask=ip4_mask, ip6=ip6, ip6_mask=ip6_mask, mac=mac
)
def create_interface(
self, node: "CoreNode", name: str = None, mac: str = None
@ -168,33 +201,6 @@ class IpPrefixes:
generation
:return: new interface data for the provided node
"""
# interface id
inteface_id = node.newifindex()
# generate ip4 data
ip4 = None
ip4_mask = None
if self.ip4:
ip4 = self.ip4_address(node)
ip4_mask = self.ip4.prefixlen
# generate ip6 data
ip6 = None
ip6_mask = None
if self.ip6:
ip6 = self.ip6_address(node)
ip6_mask = self.ip6.prefixlen
# random mac
if not mac:
mac = utils.random_mac()
return InterfaceData(
id=inteface_id,
name=name,
ip4=ip4,
ip4_mask=ip4_mask,
ip6=ip6,
ip6_mask=ip6_mask,
mac=mac,
)
interface = self.gen_interface(node.id, name, mac)
interface.id = node.newifindex()
return interface

View file

@ -32,7 +32,7 @@ _DIR = os.path.dirname(os.path.abspath(__file__))
def ping(
from_node: CoreNode, to_node: CoreNode, ip_prefixes: IpPrefixes, count: int = 3
):
address = ip_prefixes.ip4_address(to_node)
address = ip_prefixes.ip4_address(to_node.id)
try:
from_node.cmd(f"ping -c {count} {address}")
status = 0

View file

@ -22,7 +22,7 @@ _WIRED = [PtpNet, HubNode, SwitchNode]
def ping(from_node: CoreNode, to_node: CoreNode, ip_prefixes: IpPrefixes):
address = ip_prefixes.ip4_address(to_node)
address = ip_prefixes.ip4_address(to_node.id)
try:
from_node.cmd(f"ping -c 1 {address}")
status = 0