summaryrefslogtreecommitdiffstats
path: root/ipapython
diff options
context:
space:
mode:
authorMartin Basti <mbasti@redhat.com>2017-06-14 14:47:23 +0200
committerDavid Kupka <dkupka@redhat.com>2017-06-20 11:29:41 +0200
commit0b69e44f16fbba6ab7ddef5a3e55bdabcfd6a8a6 (patch)
tree879db85d8efdb917ce2217e29cddce9064ee07ed /ipapython
parentcb48a49c80f4a11d2d16511e0f1366867320f153 (diff)
refactor CheckedIPAddress class
Make methods without side effects (setting mask) https://pagure.io/freeipa/issue/4317 Reviewed-By: David Kupka <dkupka@redhat.com>
Diffstat (limited to 'ipapython')
-rw-r--r--ipapython/ipautil.py29
1 files changed, 22 insertions, 7 deletions
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 647ee833a..2c020e3ec 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -62,6 +62,12 @@ PROTOCOL_NAMES = {
socket.SOCK_DGRAM: 'udp'
}
+InterfaceDetails = collections.namedtuple(
+ 'InterfaceDetails', [
+ 'name', # interface name
+ 'ifnet' # network details of interface
+ ])
+
class UnsafeIPAddress(netaddr.IPAddress):
"""Any valid IP address with or without netmask."""
@@ -161,9 +167,12 @@ class CheckedIPAddress(UnsafeIPAddress):
raise ValueError("cannot use multicast IP address {}".format(addr))
if match_local:
- if not self.get_matching_interface():
+ intf_details = self.get_matching_interface()
+ if not intf_details:
raise ValueError('no network interface matches the IP address '
'and netmask {}'.format(addr))
+ else:
+ self.set_ip_net(intf_details.ifnet)
if self._net is None:
if self.version == 4:
@@ -193,7 +202,8 @@ class CheckedIPAddress(UnsafeIPAddress):
def get_matching_interface(self):
"""Find matching local interface for address
- :return: Interface name or None if no interface has this address
+ :return: InterfaceDetails named tuple or None if no interface has
+ this address
"""
if self.version == 4:
family = netifaces.AF_INET
@@ -204,7 +214,6 @@ class CheckedIPAddress(UnsafeIPAddress):
"Unsupported address family ({})".format(self.version)
)
- iface = None
for interface in netifaces.interfaces():
for ifdata in netifaces.ifaddresses(interface).get(family, []):
@@ -218,11 +227,17 @@ class CheckedIPAddress(UnsafeIPAddress):
))
if ifnet.ip == self:
- iface = interface
- self._net = ifnet
- break
+ return InterfaceDetails(interface, ifnet)
- return iface
+ def set_ip_net(self, ifnet):
+ """Set IP Network details for this address. IPNetwork is valid only
+ locally, so this should be set only for local IP addresses
+
+ :param ifnet: netaddr.IPNetwork object with information about IP
+ network where particula address belongs locally
+ """
+ assert isinstance(ifnet, netaddr.IPNetwork)
+ self._net = ifnet
def valid_ip(addr):