Allow Ipv6 addresses for nova_metadata_host

Current logic didn't check if the nova_metadata_host is an IPv6 address
causing the proxy request to fail with an exception because the url is
not valid.

This patchs check if the nova_metadata_host is an IPv6 address and
create a valid url enclosing the IPv6 address with brackets

Closes-Bug: #1796593

Change-Id: Ibfebffcec2c8860237a1f151084de978a7863bd8
Signed-off-by: aojeagarcia <aojeagarcia@suse.com>
(cherry picked from commit 85588ad38e)
This commit is contained in:
aojeagarcia 2018-10-07 23:17:08 +02:00 committed by Antonio Ojea
parent 6e9c1d31ca
commit 2fba9f42b9
3 changed files with 42 additions and 2 deletions

View File

@ -32,6 +32,7 @@ from neutron.agent.linux import utils as agent_utils
from neutron.agent import rpc as agent_rpc
from neutron.common import cache_utils as cache
from neutron.common import constants as n_const
from neutron.common import ipv6_utils
from neutron.common import rpc as n_rpc
from neutron.common import topics
from neutron.conf.agent.metadata import config
@ -172,8 +173,10 @@ class MetadataProxyHandler(object):
'X-Instance-ID-Signature': self._sign_instance_id(instance_id)
}
nova_host_port = '%s:%s' % (self.conf.nova_metadata_host,
self.conf.nova_metadata_port)
nova_host_port = ipv6_utils.valid_ipv6_url(
self.conf.nova_metadata_host,
self.conf.nova_metadata_port)
url = urlparse.urlunsplit((
self.conf.nova_metadata_protocol,
nova_host_port,

View File

@ -75,3 +75,15 @@ def is_ipv6_pd_enabled(subnet):
constants.IPV6_PD_POOL_ID
"""
return subnet.get('subnetpool_id') == const.IPV6_PD_POOL_ID
def valid_ipv6_url(host, port):
"""Given a host and a port returns a valid URL
RFC2732 https://tools.ietf.org/html/rfc2732
square brackets always required in ipv6 URI.
"""
if netaddr.valid_ipv6(host):
uri = '[%s]:%s' % (host, port)
else:
uri = '%s:%s' % (host, port)
return uri

View File

@ -113,3 +113,28 @@ class TestIsEui64Address(base.BaseTestCase):
'fffe::0cad:12fe:fe44:5566',
'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
self._test_eui_64(ips, False)
class TestValidIpv6URL(base.BaseTestCase):
def test_valid_ipv6_url(self):
host = "::1"
port = 443
self.assertEqual("[::1]:443", ipv6_utils.valid_ipv6_url(host, port))
def test_invalid_ipv6_url(self):
host = "::1"
port = 443
self.assertNotEqual("::1:443", ipv6_utils.valid_ipv6_url(host, port))
def test_valid_ipv4_url(self):
host = "192.168.1.2"
port = 443
self.assertEqual("192.168.1.2:443",
ipv6_utils.valid_ipv6_url(host, port))
def test_valid_hostname_url(self):
host = "controller"
port = 443
self.assertEqual("controller:443",
ipv6_utils.valid_ipv6_url(host, port))