Handle AddrFormatError when CIDR can't be found

The network space for the cluster space or the public space may have
addresses in a different subnet than the one that is currently assigned
to the unit. In this case, the attempt to look up the netmask results in
a value of None, which in turn causes charmhelpers to raise an
AddrFormatError when attempting to determine the CIDR.

Handle this case within the interface and return None for the respective
CIDR. This may cause some issues where the public or cluster CIDRs are
not resolvable, however the charm interface already expects to provide
None if the CIDR cannot be determined.

A better, however more invasive, change would be to change out the calls
in the ceph-mon charm to use the network_get calls rather than
network_get_primary_address. Per the documentation for the network
primitives, it appears that the cidr can still be empty and is likely to
still lead to the inability to resolve the CIDR locally.

This change will primarily focus on handling the inability to resolve a
CIDR locally, postponing the network_get transformation this late in the
cycle.

Closes-Bug: #1898299
Change-Id: If1538eb645577653cada770211fd445b76284fd3
This commit is contained in:
Billy Olsen 2021-04-01 10:43:31 -07:00
parent 61c94148d9
commit 1bb6e20b34
2 changed files with 26 additions and 2 deletions

View File

@ -17,6 +17,8 @@ import json
import socket
import uuid
from netaddr.core import AddrFormatError
# the reactive framework unfortunately does not grok `import as` in conjunction
# with decorators on class instance methods, so we have to revert to `from ...`
# imports
@ -215,7 +217,13 @@ class CephRBDMirrorRequires(Endpoint):
"""
public_addr = self.all_joined_units.received['ceph-public-address']
if public_addr:
return ch_ip.resolve_network_cidr(public_addr)
try:
return ch_ip.resolve_network_cidr(public_addr)
except AddrFormatError:
# LP#1898299 in some cases the netmask will be None, which
# leads to an AddrFormatError. In this case, we should return
# None
return None
@property
def cluster_network(self):
@ -230,7 +238,13 @@ class CephRBDMirrorRequires(Endpoint):
"""
cluster_addr = self.all_joined_units.received['ceph-cluster-address']
if cluster_addr:
return ch_ip.resolve_network_cidr(cluster_addr)
try:
return ch_ip.resolve_network_cidr(cluster_addr)
except AddrFormatError:
# LP#1898299 in some cases the netmask will be None, which
# leads to an AddrFormatError. In this case, we should return
# None
return None
@property
def pools(self):

View File

@ -16,6 +16,8 @@ import json
import mock
import requires
from netaddr.core import AddrFormatError
import charms_openstack.test_utils as test_utils
@ -201,6 +203,10 @@ class TestCephRBDMirrorRequires(test_utils.PatchHelper):
'ceph-public-address')
self.resolve_network_cidr.assert_called_once_with('192.0.2.1')
# Test no netmask condition
self.resolve_network_cidr.side_effect = AddrFormatError()
self.assertEqual(self.requires_class.public_network, None)
def test_cluster_network(self):
self.patch_requires_class('_all_joined_units')
self._all_joined_units.received.__getitem__.return_value = '192.0.2.1'
@ -211,6 +217,10 @@ class TestCephRBDMirrorRequires(test_utils.PatchHelper):
'ceph-cluster-address')
self.resolve_network_cidr.assert_called_once_with('192.0.2.1')
# Test no netmask condition
self.resolve_network_cidr.side_effect = AddrFormatError()
self.assertEqual(self.requires_class.cluster_network, None)
def test_maybe_send_rq(self):
self.patch_requires_class('_relations')
relation = mock.MagicMock()