Handle adding ip address when it already exists

Adding IP address on device is now done with pyroute2 lib.
This commit handle the case when pyroute2 function raise
exception when same IP address is already configured on
device.
In such case it will now raise exception which inherits from
RuntimeError what is consistent with eariler code when it
was done by running "ip addr" command to configue IP.

Change-Id: I89f22310782f2f0baf0ce6b20d2ab0e1d68654a0
Related-Bug: #1492714
This commit is contained in:
Sławek Kapłoński 2018-03-22 20:15:00 +01:00 committed by Slawek Kaplonski
parent 0982729f56
commit b17aad2384
2 changed files with 32 additions and 8 deletions

View File

@ -50,6 +50,19 @@ class NetworkInterfaceNotFound(RuntimeError):
pass
class IpAddressAlreadyExists(RuntimeError):
message = _("IP address %(ip)s already configured on %(device)s.")
def __init__(self, message=None, ip=None, device=None):
# NOTE(slaweq): 'message' can be passed as an optional argument
# because of how privsep daemon works. If exception is raised in
# function called by privsep daemon, it will then try to reraise it
# and will call it always with passing only message from originally
# raised exception.
message = message or self.message % {'ip': ip, 'device': device}
super(IpAddressAlreadyExists, self).__init__(message)
@privileged.default.entrypoint
def get_routing_table(ip_version, namespace=None):
"""Return a list of dictionaries, each representing a route.
@ -139,14 +152,19 @@ def _run_iproute_addr(command, device, namespace, **kwargs):
def add_ip_address(ip_version, ip, prefixlen, device, namespace, scope,
broadcast=None):
family = _IP_VERSION_FAMILY_MAP[ip_version]
_run_iproute_addr('add',
device,
namespace,
address=ip,
mask=prefixlen,
family=family,
broadcast=broadcast,
scope=_get_scope_name(scope))
try:
_run_iproute_addr('add',
device,
namespace,
address=ip,
mask=prefixlen,
family=family,
broadcast=broadcast,
scope=_get_scope_name(scope))
except NetlinkError as e:
if e.code == errno.EEXIST:
raise IpAddressAlreadyExists(ip=ip, device=device)
raise
@privileged.default.entrypoint

View File

@ -417,6 +417,12 @@ class IpLibTestCase(IpLibTestFramework):
device = self.manage_device(attr)
self._add_and_check_ips(device, ip_addresses)
# Now let's check if adding already existing IP address will raise
# RuntimeError
ip_address = ip_addresses[0]
self.assertRaises(RuntimeError,
device.addr.add, str(ip_address[0]), ip_address[1])
def test_delete_ip_address(self):
attr = self.generate_device_details()
cidr = attr.ip_cidrs[0]