Ensure that we resolve AAAA if prefer-ipv6 is True

We currently resolve A records regardless of whether
prefer-ipv6 is True or False. This patch ensures
that we request AAAA in the case where prefer-ipv6
is True.

Change-Id: I0749cd01e504fb4010addcd91bda3a1f32a03fab
Closes-Bug: 1729572
This commit is contained in:
Edward Hope-Morley 2017-11-02 12:38:41 +00:00
parent a92cfd6a8a
commit db18bc2f60
2 changed files with 39 additions and 16 deletions

View File

@ -48,6 +48,7 @@ from charmhelpers.contrib.network.ip import (
get_address_in_network,
get_ipv6_addr,
is_ip,
is_ipv6,
)
from charmhelpers.contrib.database.mysql import (
MySQLHelper,
@ -147,7 +148,7 @@ def setup_percona_repo():
subprocess.check_call(['apt-key', 'add', KEY])
def resolve_hostname_to_ip(hostname, ipv6=False):
def resolve_hostname_to_ip(hostname):
"""Resolve hostname to IP
@param hostname: hostname to be resolved
@ -160,18 +161,21 @@ def resolve_hostname_to_ip(hostname, ipv6=False):
fatal=True)
import dns.resolver
if is_ip(hostname):
if config('prefer-ipv6'):
if is_ipv6(hostname):
return hostname
query_type = 'AAAA'
elif is_ip(hostname):
return hostname
else:
if ipv6:
query_type = 'AAAA'
else:
query_type = 'A'
# This may throw an NXDOMAIN exception; in which case
# things are badly broken so just let it kill the hook
answers = dns.resolver.query(hostname, query_type)
if answers:
return answers[0].address
query_type = 'A'
# This may throw an NXDOMAIN exception; in which case
# things are badly broken so just let it kill the hook
answers = dns.resolver.query(hostname, query_type)
if answers:
return answers[0].address
def is_sufficient_peers():

View File

@ -485,14 +485,22 @@ class TestResolveHostnameToIP(CharmTestCase):
CharmTestCase.setUp(self, percona_utils,
self.TO_PATCH)
def test_resolve_hostname_to_ip_ips(self):
@mock.patch.object(percona_utils, 'is_ipv6')
@mock.patch.object(percona_utils, 'is_ip')
@mock.patch.object(percona_utils, 'config', lambda *args: None)
def test_resolve_hostname_to_ip_ips(self, mock_is_ip, mock_is_ipv6):
ipv6_address = '2a01:348:2f4:0:dba7:dc58:659b:941f'
ipv4_address = '10.10.10.2'
self.assertEqual(percona_utils.resolve_hostname_to_ip(ipv6_address),
ipv6_address)
self.assertTrue(mock_is_ip.called)
self.assertFalse(mock_is_ipv6.called)
self.assertEqual(percona_utils.resolve_hostname_to_ip(ipv4_address),
ipv4_address)
self.assertTrue(mock_is_ip.called)
self.assertFalse(mock_is_ipv6.called)
@mock.patch.object(percona_utils, 'config', lambda *args: None)
@mock.patch('dns.resolver.query')
def test_resolve_hostname_to_ip_hostname_a(self,
dns_query):
@ -505,19 +513,30 @@ class TestResolveHostnameToIP(CharmTestCase):
mock.call('myhostname', 'A'),
])
@mock.patch.object(percona_utils, 'is_ipv6')
@mock.patch.object(percona_utils, 'is_ip')
@mock.patch.object(percona_utils, 'config')
@mock.patch('dns.resolver.query')
def test_resolve_hostname_to_ip_hostname_aaaa(self,
dns_query):
def test_resolve_hostname_to_ip_hostname_aaaa(self, dns_query, mock_config,
mock_is_ip, mock_is_ipv6):
def fake_config(key):
return {'prefer-ipv6': True}.get(key)
mock_config.side_effect = fake_config
mock_answer = mock.MagicMock()
mock_is_ipv6.return_value = False
mock_answer.address = '2a01:348:2f4:0:dba7:dc58:659b:941f'
dns_query.return_value = [mock_answer]
self.assertEqual(percona_utils.resolve_hostname_to_ip('myhostname',
ipv6=True),
self.assertEqual(percona_utils.resolve_hostname_to_ip('myhostname'),
'2a01:348:2f4:0:dba7:dc58:659b:941f')
self.assertFalse(mock_is_ip.called)
self.assertTrue(mock_is_ipv6.called)
dns_query.assert_has_calls([
mock.call('myhostname', 'AAAA'),
])
@mock.patch.object(percona_utils, 'config', lambda *args: None)
@mock.patch('dns.resolver.query')
def test_resolve_hostname_to_ip_hostname_noanswer(self,
dns_query):