daemon: refactored usages of addr to ip and updated functions to align
This commit is contained in:
parent
d88f3a2535
commit
20feea8f12
12 changed files with 138 additions and 118 deletions
|
@ -29,7 +29,7 @@ class DefaultRouteService(ConfigService):
|
|||
ifaces = self.node.get_ifaces()
|
||||
if ifaces:
|
||||
iface = ifaces[0]
|
||||
for ip in iface.all_ips():
|
||||
for ip in iface.ips():
|
||||
net = ip.cidr
|
||||
if net.size > 1:
|
||||
router = net[1]
|
||||
|
@ -76,7 +76,7 @@ class StaticRouteService(ConfigService):
|
|||
def data(self) -> Dict[str, Any]:
|
||||
routes = []
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
for ip in iface.all_ips():
|
||||
for ip in iface.ips():
|
||||
address = str(ip.ip)
|
||||
if netaddr.valid_ipv6(address):
|
||||
dst = "3ffe:4::/64"
|
||||
|
|
|
@ -1548,7 +1548,7 @@ class Session:
|
|||
entries = []
|
||||
for iface in control_net.get_ifaces():
|
||||
name = iface.node.name
|
||||
for ip in iface.all_ips():
|
||||
for ip in iface.ips():
|
||||
entries.append(f"{ip.ip} {name}")
|
||||
|
||||
logging.info("Adding %d /etc/hosts file entries.", len(entries))
|
||||
|
|
|
@ -7,7 +7,7 @@ import os
|
|||
import shutil
|
||||
import threading
|
||||
from threading import RLock
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Type, Union
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type, Union
|
||||
|
||||
import netaddr
|
||||
|
||||
|
@ -138,6 +138,13 @@ class NodeBase(abc.ABC):
|
|||
return self.position.get()
|
||||
|
||||
def get_iface(self, iface_id: int) -> CoreInterface:
|
||||
"""
|
||||
Retrieve interface based on id.
|
||||
|
||||
:param iface_id: id of interface to retrieve
|
||||
:return: interface
|
||||
:raises CoreError: when interface does not exist
|
||||
"""
|
||||
if iface_id not in self.ifaces:
|
||||
raise CoreError(f"node({self.name}) does not have interface({iface_id})")
|
||||
return self.ifaces[iface_id]
|
||||
|
@ -436,7 +443,6 @@ class CoreNode(CoreNodeBase):
|
|||
"""
|
||||
|
||||
apitype: NodeTypes = NodeTypes.DEFAULT
|
||||
valid_address_types: Set[str] = {"inet", "inet6", "inet6link"}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -750,40 +756,39 @@ class CoreNode(CoreNodeBase):
|
|||
if self.up:
|
||||
self.node_net_client.device_mac(iface.name, mac)
|
||||
|
||||
def addaddr(self, iface_id: int, addr: str) -> None:
|
||||
def add_ip(self, iface_id: int, ip: str) -> None:
|
||||
"""
|
||||
Add interface address.
|
||||
Add an ip address to an interface in the format "10.0.0.1/24".
|
||||
|
||||
:param iface_id: id of interface to add address to
|
||||
:param addr: address to add to interface
|
||||
:return: nothing
|
||||
"""
|
||||
addr = utils.validate_ip(addr)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.addaddr(addr)
|
||||
if self.up:
|
||||
# ipv4 check
|
||||
broadcast = None
|
||||
if netaddr.valid_ipv4(addr):
|
||||
broadcast = "+"
|
||||
self.node_net_client.create_address(iface.name, addr, broadcast)
|
||||
|
||||
def deladdr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Delete address from an interface.
|
||||
|
||||
:param iface_id: id of interface to delete address from
|
||||
:param addr: address to delete from interface
|
||||
:param ip: address to add to interface
|
||||
:return: nothing
|
||||
:raises CoreError: when ip address provided is invalid
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
iface = self.get_iface(iface_id)
|
||||
try:
|
||||
iface.deladdr(addr)
|
||||
except ValueError:
|
||||
logging.exception("trying to delete unknown address: %s", addr)
|
||||
iface.add_ip(ip)
|
||||
if self.up:
|
||||
self.node_net_client.delete_address(iface.name, addr)
|
||||
# ipv4 check
|
||||
broadcast = None
|
||||
if netaddr.valid_ipv4(ip):
|
||||
broadcast = "+"
|
||||
self.node_net_client.create_address(iface.name, ip, broadcast)
|
||||
|
||||
def remove_ip(self, iface_id: int, ip: str) -> None:
|
||||
"""
|
||||
Remove an ip address from an interface in the format "10.0.0.1/24".
|
||||
|
||||
:param iface_id: id of interface to delete address from
|
||||
:param ip: ip address to remove from interface
|
||||
:return: nothing
|
||||
:raises CoreError: when ip address provided is invalid
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.remove_ip(ip)
|
||||
if self.up:
|
||||
self.node_net_client.delete_address(iface.name, ip)
|
||||
|
||||
def ifup(self, iface_id: int) -> None:
|
||||
"""
|
||||
|
@ -819,14 +824,14 @@ class CoreNode(CoreNodeBase):
|
|||
iface = self.get_iface(iface_id)
|
||||
iface.set_mac(iface_data.mac)
|
||||
for address in addresses:
|
||||
iface.addaddr(address)
|
||||
iface.add_ip(address)
|
||||
else:
|
||||
iface_id = self.newveth(iface_data.id, iface_data.name)
|
||||
self.attachnet(iface_id, net)
|
||||
if iface_data.mac:
|
||||
self.set_mac(iface_id, iface_data.mac)
|
||||
for address in addresses:
|
||||
self.addaddr(iface_id, address)
|
||||
self.add_ip(iface_id, address)
|
||||
self.ifup(iface_id)
|
||||
iface = self.get_iface(iface_id)
|
||||
return iface
|
||||
|
|
|
@ -134,46 +134,64 @@ class CoreInterface:
|
|||
if self.net is not None:
|
||||
self.net.detach(self)
|
||||
|
||||
def addaddr(self, address: str) -> None:
|
||||
def add_ip(self, ip: str) -> None:
|
||||
"""
|
||||
Add ip address in the format "10.0.0.1/24".
|
||||
|
||||
:param address: address to add
|
||||
:param ip: ip address to add
|
||||
:return: nothing
|
||||
:raises CoreError: when ip address provided is invalid
|
||||
"""
|
||||
try:
|
||||
ip = netaddr.IPNetwork(address)
|
||||
value = str(ip.ip)
|
||||
if netaddr.valid_ipv4(value):
|
||||
ip = netaddr.IPNetwork(ip)
|
||||
address = str(ip.ip)
|
||||
if netaddr.valid_ipv4(address):
|
||||
self.ip4s.append(ip)
|
||||
else:
|
||||
self.ip6s.append(ip)
|
||||
except netaddr.AddrFormatError:
|
||||
raise CoreError(f"adding invalid address {address}")
|
||||
raise CoreError(f"adding invalid address {ip}")
|
||||
|
||||
def deladdr(self, addr: str) -> None:
|
||||
def remove_ip(self, ip: str) -> None:
|
||||
"""
|
||||
Delete address.
|
||||
Remove ip address in the format "10.0.0.1/24".
|
||||
|
||||
:param addr: address to delete
|
||||
:param ip: ip address to delete
|
||||
:return: nothing
|
||||
:raises CoreError: when ip address provided is invalid
|
||||
"""
|
||||
if netaddr.valid_ipv4(addr):
|
||||
ip4 = netaddr.IPNetwork(addr)
|
||||
self.ip4s.remove(ip4)
|
||||
elif netaddr.valid_ipv6(addr):
|
||||
ip6 = netaddr.IPNetwork(addr)
|
||||
self.ip6s.remove(ip6)
|
||||
else:
|
||||
raise CoreError(f"deleting invalid address {addr}")
|
||||
try:
|
||||
ip = netaddr.IPNetwork(ip)
|
||||
address = str(ip.ip)
|
||||
if netaddr.valid_ipv4(address):
|
||||
self.ip4s.remove(ip)
|
||||
else:
|
||||
self.ip6s.remove(ip)
|
||||
except (netaddr.AddrFormatError, ValueError):
|
||||
raise CoreError(f"deleting invalid address {ip}")
|
||||
|
||||
def get_ip4(self) -> Optional[netaddr.IPNetwork]:
|
||||
"""
|
||||
Looks for the first ip4 address.
|
||||
|
||||
:return: ip4 address, None otherwise
|
||||
"""
|
||||
return next(iter(self.ip4s), None)
|
||||
|
||||
def get_ip6(self) -> Optional[netaddr.IPNetwork]:
|
||||
"""
|
||||
Looks for the first ip6 address.
|
||||
|
||||
:return: ip6 address, None otherwise
|
||||
"""
|
||||
return next(iter(self.ip6s), None)
|
||||
|
||||
def all_ips(self) -> List[netaddr.IPNetwork]:
|
||||
def ips(self) -> List[netaddr.IPNetwork]:
|
||||
"""
|
||||
Retrieve a list of all ip4 and ip6 addresses combined.
|
||||
|
||||
:return: ip4 and ip6 addresses
|
||||
"""
|
||||
return self.ip4s + self.ip6s
|
||||
|
||||
def set_mac(self, mac: str) -> None:
|
||||
|
@ -518,7 +536,7 @@ class TunTap(CoreInterface):
|
|||
:return: nothing
|
||||
"""
|
||||
self.waitfordevicenode()
|
||||
for ip in self.all_ips():
|
||||
for ip in self.ips():
|
||||
self.node.node_net_client.create_address(self.name, str(ip))
|
||||
|
||||
|
||||
|
|
|
@ -575,18 +575,17 @@ class CoreNetwork(CoreNetworkBase):
|
|||
return iface
|
||||
return None
|
||||
|
||||
def addrconfig(self, addrlist: List[str]) -> None:
|
||||
def add_ips(self, ips: List[str]) -> None:
|
||||
"""
|
||||
Set addresses on the bridge.
|
||||
Add ip addresses on the bridge in the format "10.0.0.1/24".
|
||||
|
||||
:param addrlist: address list
|
||||
:param ips: ip address to add
|
||||
:return: nothing
|
||||
"""
|
||||
if not self.up:
|
||||
return
|
||||
|
||||
for addr in addrlist:
|
||||
self.net_client.create_address(self.brname, str(addr))
|
||||
for ip in ips:
|
||||
self.net_client.create_address(self.brname, ip)
|
||||
|
||||
|
||||
class GreTapBridge(CoreNetwork):
|
||||
|
@ -663,22 +662,22 @@ class GreTapBridge(CoreNetwork):
|
|||
self.gretap = None
|
||||
super().shutdown()
|
||||
|
||||
def addrconfig(self, addrlist: List[str]) -> None:
|
||||
def add_ips(self, ips: List[str]) -> None:
|
||||
"""
|
||||
Set the remote tunnel endpoint. This is a one-time method for
|
||||
creating the GreTap device, which requires the remoteip at startup.
|
||||
The 1st address in the provided list is remoteip, 2nd optionally
|
||||
specifies localip.
|
||||
|
||||
:param addrlist: address list
|
||||
:param ips: address list
|
||||
:return: nothing
|
||||
"""
|
||||
if self.gretap:
|
||||
raise ValueError(f"gretap already exists for {self.name}")
|
||||
remoteip = addrlist[0].split("/")[0]
|
||||
remoteip = ips[0].split("/")[0]
|
||||
localip = None
|
||||
if len(addrlist) > 1:
|
||||
localip = addrlist[1].split("/")[0]
|
||||
if len(ips) > 1:
|
||||
localip = ips[1].split("/")[0]
|
||||
self.gretap = GreTap(
|
||||
session=self.session,
|
||||
remoteip=remoteip,
|
||||
|
@ -700,7 +699,7 @@ class GreTapBridge(CoreNetwork):
|
|||
self.grekey = key
|
||||
addresses = iface_data.get_addresses()
|
||||
if addresses:
|
||||
self.addrconfig(addresses)
|
||||
self.add_ips(addresses)
|
||||
|
||||
|
||||
class CtrlNet(CoreNetwork):
|
||||
|
|
|
@ -75,43 +75,43 @@ class PhysicalNode(CoreNodeBase):
|
|||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
mac = utils.validate_mac(mac)
|
||||
iface = self.ifaces[iface_id]
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.set_mac(mac)
|
||||
if self.up:
|
||||
self.net_client.device_mac(iface.name, mac)
|
||||
|
||||
def addaddr(self, iface_id: int, addr: str) -> None:
|
||||
def add_ip(self, iface_id: int, ip: str) -> None:
|
||||
"""
|
||||
Add an address to an interface.
|
||||
Add an ip address to an interface in the format "10.0.0.1/24".
|
||||
|
||||
:param iface_id: index of interface to add address to
|
||||
:param addr: address to add
|
||||
:param iface_id: id of interface to add address to
|
||||
:param ip: address to add to interface
|
||||
:return: nothing
|
||||
:raises CoreError: when ip address provided is invalid
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
addr = utils.validate_ip(addr)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.add_ip(ip)
|
||||
if self.up:
|
||||
self.net_client.create_address(iface.name, addr)
|
||||
iface.addaddr(addr)
|
||||
self.net_client.create_address(iface.name, ip)
|
||||
|
||||
def deladdr(self, iface_id: int, addr: str) -> None:
|
||||
def remove_ip(self, iface_id: int, ip: str) -> None:
|
||||
"""
|
||||
Delete an address from an interface.
|
||||
Remove an ip address from an interface in the format "10.0.0.1/24".
|
||||
|
||||
:param iface_id: index of interface to delete
|
||||
:param addr: address to delete
|
||||
:param iface_id: id of interface to delete address from
|
||||
:param ip: ip address to remove from interface
|
||||
:return: nothing
|
||||
:raises CoreError: when ip address provided is invalid
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
iface = self.ifaces[iface_id]
|
||||
try:
|
||||
iface.deladdr(addr)
|
||||
except ValueError:
|
||||
logging.exception("trying to delete unknown address: %s", addr)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.remove_ip(ip)
|
||||
if self.up:
|
||||
self.net_client.delete_address(iface.name, addr)
|
||||
self.net_client.delete_address(iface.name, ip)
|
||||
|
||||
def adopt_iface(
|
||||
self, iface: CoreInterface, iface_id: int, mac: str, addrlist: List[str]
|
||||
self, iface: CoreInterface, iface_id: int, mac: str, ips: List[str]
|
||||
) -> None:
|
||||
"""
|
||||
When a link message is received linking this node to another part of
|
||||
|
@ -128,8 +128,8 @@ class PhysicalNode(CoreNodeBase):
|
|||
iface.localname = iface.name
|
||||
if mac:
|
||||
self.set_mac(iface_id, mac)
|
||||
for addr in addrlist:
|
||||
self.addaddr(iface_id, addr)
|
||||
for ip in ips:
|
||||
self.add_ip(iface_id, ip)
|
||||
if self.up:
|
||||
self.net_client.device_up(iface.localname)
|
||||
|
||||
|
@ -317,7 +317,7 @@ class Rj45Node(CoreNodeBase):
|
|||
if net is not None:
|
||||
self.iface.attachnet(net)
|
||||
for addr in iface_data.get_addresses():
|
||||
self.addaddr(addr)
|
||||
self.add_ip(addr)
|
||||
return self.iface
|
||||
|
||||
def delete_iface(self, iface_id: int) -> None:
|
||||
|
@ -348,30 +348,31 @@ class Rj45Node(CoreNodeBase):
|
|||
raise CoreError(f"node({self.name}) does not have interface({iface.name})")
|
||||
return self.iface_id
|
||||
|
||||
def addaddr(self, addr: str) -> None:
|
||||
def add_ip(self, ip: str) -> None:
|
||||
"""
|
||||
Add address to to network interface.
|
||||
Add an ip address to an interface in the format "10.0.0.1/24".
|
||||
|
||||
:param addr: address to add
|
||||
:param ip: address to add to interface
|
||||
:return: nothing
|
||||
:raises CoreCommandError: when there is a command exception
|
||||
:raises CoreError: when ip address provided is invalid
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
addr = utils.validate_ip(addr)
|
||||
self.iface.add_ip(ip)
|
||||
if self.up:
|
||||
self.net_client.create_address(self.name, addr)
|
||||
self.iface.addaddr(addr)
|
||||
self.net_client.create_address(self.name, ip)
|
||||
|
||||
def deladdr(self, addr: str) -> None:
|
||||
def remove_ip(self, ip: str) -> None:
|
||||
"""
|
||||
Delete address from network interface.
|
||||
Remove an ip address from an interface in the format "10.0.0.1/24".
|
||||
|
||||
:param addr: address to delete
|
||||
:param ip: ip address to remove from interface
|
||||
:return: nothing
|
||||
:raises CoreCommandError: when there is a command exception
|
||||
:raises CoreError: when ip address provided is invalid
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
self.iface.remove_ip(ip)
|
||||
if self.up:
|
||||
self.net_client.delete_address(self.name, addr)
|
||||
self.iface.deladdr(addr)
|
||||
self.net_client.delete_address(self.name, ip)
|
||||
|
||||
def savestate(self) -> None:
|
||||
"""
|
||||
|
|
|
@ -67,7 +67,7 @@ class FRRZebra(CoreService):
|
|||
# include control interfaces in addressing but not routing daemons
|
||||
if hasattr(iface, "control") and iface.control is True:
|
||||
cfg += " "
|
||||
cfg += "\n ".join(map(cls.addrstr, iface.all_ips()))
|
||||
cfg += "\n ".join(map(cls.addrstr, iface.ips()))
|
||||
cfg += "\n"
|
||||
continue
|
||||
cfgv4 = ""
|
||||
|
|
|
@ -64,7 +64,7 @@ class Zebra(CoreService):
|
|||
# include control interfaces in addressing but not routing daemons
|
||||
if getattr(iface, "control", False):
|
||||
cfg += " "
|
||||
cfg += "\n ".join(map(cls.addrstr, iface.all_ips()))
|
||||
cfg += "\n ".join(map(cls.addrstr, iface.ips()))
|
||||
cfg += "\n"
|
||||
continue
|
||||
cfgv4 = ""
|
||||
|
|
|
@ -74,7 +74,7 @@ class DefaultRouteService(UtilService):
|
|||
ifaces = node.get_ifaces()
|
||||
if ifaces:
|
||||
iface = ifaces[0]
|
||||
for ip in iface.all_ips():
|
||||
for ip in iface.ips():
|
||||
net = ip.cidr
|
||||
if net.size > 1:
|
||||
router = net[1]
|
||||
|
@ -118,7 +118,7 @@ class StaticRouteService(UtilService):
|
|||
cfg += "# NOTE: this service must be customized to be of any use\n"
|
||||
cfg += "# Below are samples that you can uncomment and edit.\n#\n"
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "\n".join(map(cls.routestr, iface.all_ips()))
|
||||
cfg += "\n".join(map(cls.routestr, iface.ips()))
|
||||
cfg += "\n"
|
||||
return cfg
|
||||
|
||||
|
@ -241,7 +241,7 @@ max-lease-time 7200;
|
|||
ddns-update-style none;
|
||||
"""
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "\n".join(map(cls.subnetentry, iface.all_ips()))
|
||||
cfg += "\n".join(map(cls.subnetentry, iface.ips()))
|
||||
cfg += "\n"
|
||||
return cfg
|
||||
|
||||
|
@ -555,10 +555,7 @@ export LANG
|
|||
% node.name
|
||||
)
|
||||
for iface in node.get_ifaces(control=False):
|
||||
body += "<li>%s - %s</li>\n" % (
|
||||
iface.name,
|
||||
[str(x) for x in iface.all_ips()],
|
||||
)
|
||||
body += "<li>%s - %s</li>\n" % (iface.name, [str(x) for x in iface.ips()])
|
||||
return "<html><body>%s</body></html>" % body
|
||||
|
||||
|
||||
|
@ -626,7 +623,7 @@ class RadvdService(UtilService):
|
|||
"""
|
||||
cfg = "# auto-generated by RADVD service (utility.py)\n"
|
||||
for iface in node.get_ifaces(control=False):
|
||||
prefixes = list(map(cls.subnetentry, iface.all_ips()))
|
||||
prefixes = list(map(cls.subnetentry, iface.ips()))
|
||||
if len(prefixes) < 1:
|
||||
continue
|
||||
cfg += (
|
||||
|
|
|
@ -40,7 +40,7 @@ class XorpRtrmgr(CoreService):
|
|||
for iface in node.get_ifaces():
|
||||
cfg += " interface %s {\n" % iface.name
|
||||
cfg += "\tvif %s {\n" % iface.name
|
||||
cfg += "".join(map(cls.addrstr, iface.all_ips()))
|
||||
cfg += "".join(map(cls.addrstr, iface.ips()))
|
||||
cfg += cls.lladdrstr(iface)
|
||||
cfg += "\t}\n"
|
||||
cfg += " }\n"
|
||||
|
|
|
@ -164,7 +164,7 @@ class CoreXmlDeployment:
|
|||
if emane_element is not None:
|
||||
parent_element = emane_element
|
||||
|
||||
for ip in iface.all_ips():
|
||||
for ip in iface.ips():
|
||||
address = str(ip.ip)
|
||||
address_type = get_address_type(address)
|
||||
add_address(parent_element, address_type, address, iface.name)
|
||||
|
|
|
@ -75,31 +75,31 @@ class TestNodes:
|
|||
with pytest.raises(CoreError):
|
||||
node.set_mac(iface.node_id, mac)
|
||||
|
||||
def test_node_addaddr(self, session: Session):
|
||||
def test_node_add_ip(self, session: Session):
|
||||
# given
|
||||
node = session.add_node(CoreNode)
|
||||
switch = session.add_node(SwitchNode)
|
||||
iface_data = InterfaceData()
|
||||
iface = node.new_iface(switch, iface_data)
|
||||
addr = "192.168.0.1/24"
|
||||
ip = "192.168.0.1/24"
|
||||
|
||||
# when
|
||||
node.addaddr(iface.node_id, addr)
|
||||
node.add_ip(iface.node_id, ip)
|
||||
|
||||
# then
|
||||
assert str(iface.get_ip4()) == addr
|
||||
assert str(iface.get_ip4()) == ip
|
||||
|
||||
def test_node_addaddr_exception(self, session):
|
||||
def test_node_add_ip_exception(self, session):
|
||||
# given
|
||||
node = session.add_node(CoreNode)
|
||||
switch = session.add_node(SwitchNode)
|
||||
iface_data = InterfaceData()
|
||||
iface = node.new_iface(switch, iface_data)
|
||||
addr = "256.168.0.1/24"
|
||||
ip = "256.168.0.1/24"
|
||||
|
||||
# when
|
||||
with pytest.raises(CoreError):
|
||||
node.addaddr(iface.node_id, addr)
|
||||
node.add_ip(iface.node_id, ip)
|
||||
|
||||
@pytest.mark.parametrize("net_type", NET_TYPES)
|
||||
def test_net(self, session, net_type):
|
||||
|
|
Loading…
Reference in a new issue