Support dual-stack neutron networks
It is totally possible for a neutron network to have a network with a globally routable IPv6 subnet and an RFC-1918 IPv4 subnet. In fact, the existing OSIC Cloud1 does this, and the original region of Dreamhost did this. The trouble is, it's not possible in a reasonable way to _infer_ this setup, so we rely on brand-new config functions in os-client-config to allow a user to express that a network is external for ipv4 or for ipv6. Depends-On: I40f5165d36060643943bcb91df14e5e34cd5e3fa Change-Id: I12c491ac31b950dde4c1ac55860043fd9d05ece8
This commit is contained in:
parent
18aa5d1e28
commit
6832f734d0
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- Added support for dual stack networks where the IPv4 subnet and the
|
||||
IPv6 subnet have opposite public/private qualities. It is now possible
|
||||
to add configuration to clouds.yaml that will indicate that a network
|
||||
is public for v6 and private for v4, which is otherwise very difficult
|
||||
to correctly infer while setting server attributes like private_v4,
|
||||
public_v4 and public_v6.
|
@ -4,7 +4,7 @@ munch
|
||||
decorator
|
||||
jsonpatch
|
||||
ipaddress
|
||||
os-client-config>=1.17.0,!=1.19.0
|
||||
os-client-config>=1.20.0
|
||||
requestsexceptions>=1.1.1
|
||||
six
|
||||
|
||||
|
@ -81,7 +81,7 @@ def get_server_private_ip(server, cloud=None):
|
||||
# Short circuit the ports/networks search below with a heavily cached
|
||||
# and possibly pre-configured network name
|
||||
if cloud:
|
||||
int_nets = cloud.get_internal_networks()
|
||||
int_nets = cloud.get_internal_ipv4_networks()
|
||||
for int_net in int_nets:
|
||||
int_ip = get_server_ip(server, key_name=int_net['name'])
|
||||
if int_ip is not None:
|
||||
@ -123,7 +123,7 @@ def get_server_external_ipv4(cloud, server):
|
||||
|
||||
# Short circuit the ports/networks search below with a heavily cached
|
||||
# and possibly pre-configured network name
|
||||
ext_nets = cloud.get_external_networks()
|
||||
ext_nets = cloud.get_external_ipv4_networks()
|
||||
for ext_net in ext_nets:
|
||||
ext_ip = get_server_ip(server, key_name=ext_net['name'])
|
||||
if ext_ip is not None:
|
||||
|
@ -147,8 +147,19 @@ class OpenStackCloud(object):
|
||||
self.secgroup_source = cloud_config.config['secgroup_source']
|
||||
self.force_ipv4 = cloud_config.force_ipv4
|
||||
|
||||
# The first two aren't useful to us anymore, but we still do them
|
||||
# because there are two methods that won't work without them
|
||||
self._external_network_names = cloud_config.get_external_networks()
|
||||
self._internal_network_names = cloud_config.get_internal_networks()
|
||||
|
||||
# Provide better error message for people with stale OCC
|
||||
if cloud_config.get_external_ipv4_networks is None:
|
||||
raise OpenStackCloudException(
|
||||
"shade requires at least version 1.20.0 of os-client-config")
|
||||
self._external_ipv4_names = cloud_config.get_external_ipv4_networks()
|
||||
self._internal_ipv4_names = cloud_config.get_internal_ipv4_networks()
|
||||
self._external_ipv6_names = cloud_config.get_external_ipv6_networks()
|
||||
self._internal_ipv6_names = cloud_config.get_internal_ipv6_networks()
|
||||
self._nat_destination = cloud_config.get_nat_destination()
|
||||
self._default_network = cloud_config.get_default_network()
|
||||
|
||||
@ -1596,6 +1607,10 @@ class OpenStackCloud(object):
|
||||
with self._networks_lock:
|
||||
self._external_networks = []
|
||||
self._internal_networks = []
|
||||
self._external_ipv4_networks = []
|
||||
self._internal_ipv4_networks = []
|
||||
self._external_ipv6_networks = []
|
||||
self._internal_ipv6_networks = []
|
||||
self._nat_destination_network = None
|
||||
self._default_network_network = None
|
||||
self._network_list_stamp = False
|
||||
@ -1603,6 +1618,10 @@ class OpenStackCloud(object):
|
||||
def _set_interesting_networks(self):
|
||||
external_networks = []
|
||||
internal_networks = []
|
||||
external_ipv4_networks = []
|
||||
internal_ipv4_networks = []
|
||||
external_ipv6_networks = []
|
||||
internal_ipv6_networks = []
|
||||
nat_destination = None
|
||||
default_network = None
|
||||
|
||||
@ -1623,7 +1642,7 @@ class OpenStackCloud(object):
|
||||
return
|
||||
|
||||
for network in all_networks:
|
||||
# External networks
|
||||
# Old External networks
|
||||
if (network['name'] in self._external_network_names
|
||||
or network['id'] in self._external_network_names):
|
||||
external_networks.append(network)
|
||||
@ -1634,7 +1653,7 @@ class OpenStackCloud(object):
|
||||
network['id'] not in self._internal_network_names):
|
||||
external_networks.append(network)
|
||||
|
||||
# Internal networks
|
||||
# Old Internal networks
|
||||
if (network['name'] in self._internal_network_names
|
||||
or network['id'] in self._internal_network_names):
|
||||
internal_networks.append(network)
|
||||
@ -1644,6 +1663,45 @@ class OpenStackCloud(object):
|
||||
network['id'] not in self._external_network_names):
|
||||
internal_networks.append(network)
|
||||
|
||||
# External IPv4 networks
|
||||
if (network['name'] in self._external_ipv4_names
|
||||
or network['id'] in self._external_ipv4_names):
|
||||
external_ipv4_networks.append(network)
|
||||
elif ((('router:external' in network
|
||||
and network['router:external']) or
|
||||
network.get('provider:physical_network')) and
|
||||
network['name'] not in self._internal_ipv4_names and
|
||||
network['id'] not in self._internal_ipv4_names):
|
||||
external_ipv4_networks.append(network)
|
||||
|
||||
# Internal networks
|
||||
if (network['name'] in self._internal_ipv4_names
|
||||
or network['id'] in self._internal_ipv4_names):
|
||||
internal_ipv4_networks.append(network)
|
||||
elif (not network.get('router:external', False) and
|
||||
not network.get('provider:physical_network') and
|
||||
network['name'] not in self._external_ipv4_names and
|
||||
network['id'] not in self._external_ipv4_names):
|
||||
internal_ipv4_networks.append(network)
|
||||
|
||||
# External networks
|
||||
if (network['name'] in self._external_ipv6_names
|
||||
or network['id'] in self._external_ipv6_names):
|
||||
external_ipv6_networks.append(network)
|
||||
elif (network.get('router:external') and
|
||||
network['name'] not in self._internal_ipv6_names and
|
||||
network['id'] not in self._internal_ipv6_names):
|
||||
external_ipv6_networks.append(network)
|
||||
|
||||
# Internal networks
|
||||
if (network['name'] in self._internal_ipv6_names
|
||||
or network['id'] in self._internal_ipv6_names):
|
||||
internal_ipv6_networks.append(network)
|
||||
elif (not network.get('router:external', False) and
|
||||
network['name'] not in self._external_ipv6_names and
|
||||
network['id'] not in self._external_ipv6_names):
|
||||
internal_ipv6_networks.append(network)
|
||||
|
||||
# NAT Destination
|
||||
if self._nat_destination in (
|
||||
network['name'], network['id']):
|
||||
@ -1707,6 +1765,34 @@ class OpenStackCloud(object):
|
||||
" access and those networks could not be found".format(
|
||||
network=net_name))
|
||||
|
||||
for net_name in self._external_ipv4_names:
|
||||
if net_name not in [net['name'] for net in external_ipv4_networks]:
|
||||
raise OpenStackCloudException(
|
||||
"Networks: {network} was provided for external IPv4"
|
||||
" access and those networks could not be found".format(
|
||||
network=net_name))
|
||||
|
||||
for net_name in self._internal_ipv4_names:
|
||||
if net_name not in [net['name'] for net in internal_ipv4_networks]:
|
||||
raise OpenStackCloudException(
|
||||
"Networks: {network} was provided for internal IPv4"
|
||||
" access and those networks could not be found".format(
|
||||
network=net_name))
|
||||
|
||||
for net_name in self._external_ipv6_names:
|
||||
if net_name not in [net['name'] for net in external_ipv6_networks]:
|
||||
raise OpenStackCloudException(
|
||||
"Networks: {network} was provided for external IPv6"
|
||||
" access and those networks could not be found".format(
|
||||
network=net_name))
|
||||
|
||||
for net_name in self._internal_ipv6_names:
|
||||
if net_name not in [net['name'] for net in internal_ipv6_networks]:
|
||||
raise OpenStackCloudException(
|
||||
"Networks: {network} was provided for internal IPv6"
|
||||
" access and those networks could not be found".format(
|
||||
network=net_name))
|
||||
|
||||
if self._nat_destination and not nat_destination:
|
||||
raise OpenStackCloudException(
|
||||
'Network {network} was configured to be the'
|
||||
@ -1723,6 +1809,10 @@ class OpenStackCloud(object):
|
||||
|
||||
self._external_networks = external_networks
|
||||
self._internal_networks = internal_networks
|
||||
self._external_ipv4_networks = external_ipv4_networks
|
||||
self._internal_ipv4_networks = internal_ipv4_networks
|
||||
self._external_ipv6_networks = external_ipv6_networks
|
||||
self._internal_ipv6_networks = internal_ipv6_networks
|
||||
self._nat_destination_network = nat_destination
|
||||
self._default_network_network = default_network
|
||||
|
||||
@ -1761,6 +1851,9 @@ class OpenStackCloud(object):
|
||||
def get_external_networks(self):
|
||||
"""Return the networks that are configured to route northbound.
|
||||
|
||||
This should be avoided in favor of the specific ipv4/ipv6 method,
|
||||
but is here for backwards compatibility.
|
||||
|
||||
:returns: A list of network ``munch.Munch`` if one is found
|
||||
"""
|
||||
self._find_interesting_networks()
|
||||
@ -1769,11 +1862,46 @@ class OpenStackCloud(object):
|
||||
def get_internal_networks(self):
|
||||
"""Return the networks that are configured to not route northbound.
|
||||
|
||||
This should be avoided in favor of the specific ipv4/ipv6 method,
|
||||
but is here for backwards compatibility.
|
||||
|
||||
:returns: A list of network ``munch.Munch`` if one is found
|
||||
"""
|
||||
self._find_interesting_networks()
|
||||
return self._internal_networks
|
||||
|
||||
def get_external_ipv4_networks(self):
|
||||
"""Return the networks that are configured to route northbound.
|
||||
|
||||
:returns: A list of network ``munch.Munch`` if one is found
|
||||
"""
|
||||
self._find_interesting_networks()
|
||||
return self._external_ipv4_networks
|
||||
|
||||
def get_internal_ipv4_networks(self):
|
||||
"""Return the networks that are configured to not route northbound.
|
||||
|
||||
:returns: A list of network ``munch.Munch`` if one is found
|
||||
"""
|
||||
self._find_interesting_networks()
|
||||
return self._internal_ipv4_networks
|
||||
|
||||
def get_external_ipv6_networks(self):
|
||||
"""Return the networks that are configured to route northbound.
|
||||
|
||||
:returns: A list of network ``munch.Munch`` if one is found
|
||||
"""
|
||||
self._find_interesting_networks()
|
||||
return self._external_ipv6_networks
|
||||
|
||||
def get_internal_ipv6_networks(self):
|
||||
"""Return the networks that are configured to not route northbound.
|
||||
|
||||
:returns: A list of network ``munch.Munch`` if one is found
|
||||
"""
|
||||
self._find_interesting_networks()
|
||||
return self._internal_ipv6_networks
|
||||
|
||||
def _has_floating_ips(self):
|
||||
if not self._floating_ip_source:
|
||||
return False
|
||||
@ -3393,7 +3521,7 @@ class OpenStackCloud(object):
|
||||
# Use given list to get first matching external network
|
||||
floating_network_id = None
|
||||
for net in network:
|
||||
for ext_net in self.get_external_networks():
|
||||
for ext_net in self.get_external_ipv4_networks():
|
||||
if net in (ext_net['name'], ext_net['id']):
|
||||
floating_network_id = ext_net['id']
|
||||
break
|
||||
@ -3406,8 +3534,8 @@ class OpenStackCloud(object):
|
||||
net=network)
|
||||
)
|
||||
else:
|
||||
# Get first existing external network
|
||||
networks = self.get_external_networks()
|
||||
# Get first existing external IPv4 network
|
||||
networks = self.get_external_ipv4_networks()
|
||||
if not networks:
|
||||
raise OpenStackCloudResourceNotFound(
|
||||
"unable to find an external network")
|
||||
@ -3549,7 +3677,7 @@ class OpenStackCloud(object):
|
||||
"unable to find network for floating ips with id "
|
||||
"{0}".format(network_name_or_id))
|
||||
else:
|
||||
networks = self.get_external_networks()
|
||||
networks = self.get_external_ipv4_networks()
|
||||
if not networks:
|
||||
raise OpenStackCloudResourceNotFound(
|
||||
"Unable to find an external network in this cloud"
|
||||
@ -4185,8 +4313,7 @@ class OpenStackCloud(object):
|
||||
return True
|
||||
|
||||
# No external IPv4 network - no FIPs
|
||||
# TODO(mordred) THIS IS get_external_ipv4_networks IN THE NEXT PATCH
|
||||
networks = self.get_external_networks()
|
||||
networks = self.get_external_ipv4_networks()
|
||||
if not networks:
|
||||
return False
|
||||
|
||||
|
@ -214,6 +214,9 @@ class TestFloatingIP(base.TestCase):
|
||||
|
||||
mock_nova_client.servers.get.return_value = server
|
||||
# TODO(mordred) REMOVE THIS MOCK WHEN THE NEXT PATCH LANDS
|
||||
# SERIOUSLY THIS TIME. NEXT PATCH - WHICH SHOULD ADD MOCKS FOR
|
||||
# list_ports AND list_networks AND list_subnets. BUT THAT WOULD
|
||||
# BE NOT ACTUALLY RELATED TO THIS PATCH. SO DO IT NEXT PATCH
|
||||
mock_needs_floating_ip.return_value = True
|
||||
|
||||
self.cloud.add_ips_to_server(server_dict)
|
||||
|
@ -303,7 +303,7 @@ class TestFloatingIP(base.TestCase):
|
||||
@patch.object(_utils, '_filter_list')
|
||||
@patch.object(OpenStackCloud, '_neutron_create_floating_ip')
|
||||
@patch.object(OpenStackCloud, '_neutron_list_floating_ips')
|
||||
@patch.object(OpenStackCloud, 'get_external_networks')
|
||||
@patch.object(OpenStackCloud, 'get_external_ipv4_networks')
|
||||
@patch.object(OpenStackCloud, 'keystone_session')
|
||||
def test__neutron_available_floating_ips(
|
||||
self,
|
||||
@ -340,7 +340,7 @@ class TestFloatingIP(base.TestCase):
|
||||
@patch.object(_utils, '_filter_list')
|
||||
@patch.object(OpenStackCloud, '_neutron_create_floating_ip')
|
||||
@patch.object(OpenStackCloud, '_neutron_list_floating_ips')
|
||||
@patch.object(OpenStackCloud, 'get_external_networks')
|
||||
@patch.object(OpenStackCloud, 'get_external_ipv4_networks')
|
||||
@patch.object(OpenStackCloud, 'keystone_session')
|
||||
def test__neutron_available_floating_ips_network(
|
||||
self,
|
||||
@ -375,7 +375,7 @@ class TestFloatingIP(base.TestCase):
|
||||
server=None
|
||||
)
|
||||
|
||||
@patch.object(OpenStackCloud, 'get_external_networks')
|
||||
@patch.object(OpenStackCloud, 'get_external_ipv4_networks')
|
||||
@patch.object(OpenStackCloud, 'keystone_session')
|
||||
def test__neutron_available_floating_ips_invalid_network(
|
||||
self,
|
||||
@ -621,7 +621,7 @@ class TestFloatingIP(base.TestCase):
|
||||
|
||||
@patch.object(OpenStackCloud, '_submit_create_fip')
|
||||
@patch.object(OpenStackCloud, '_nat_destination_port')
|
||||
@patch.object(OpenStackCloud, 'get_external_networks')
|
||||
@patch.object(OpenStackCloud, 'get_external_ipv4_networks')
|
||||
def test_create_floating_ip_no_port(
|
||||
self, mock_get_ext_nets, mock_nat_destination_port,
|
||||
mock_submit_create_fip):
|
||||
|
@ -61,6 +61,18 @@ class FakeCloud(object):
|
||||
def get_external_networks(self):
|
||||
return []
|
||||
|
||||
def get_internal_ipv4_networks(self):
|
||||
return []
|
||||
|
||||
def get_external_ipv4_networks(self):
|
||||
return []
|
||||
|
||||
def get_internal_ipv6_networks(self):
|
||||
return []
|
||||
|
||||
def get_external_ipv6_networks(self):
|
||||
return []
|
||||
|
||||
def list_server_security_groups(self, server):
|
||||
return []
|
||||
|
||||
@ -107,6 +119,116 @@ SUBNETS_WITH_NAT = [
|
||||
},
|
||||
]
|
||||
|
||||
OSIC_NETWORKS = [
|
||||
{
|
||||
u'admin_state_up': True,
|
||||
u'id': u'7004a83a-13d3-4dcd-8cf5-52af1ace4cae',
|
||||
u'mtu': 0,
|
||||
u'name': u'GATEWAY_NET',
|
||||
u'router:external': True,
|
||||
u'shared': True,
|
||||
u'status': u'ACTIVE',
|
||||
u'subnets': [u'cf785ee0-6cc9-4712-be3d-0bf6c86cf455'],
|
||||
u'tenant_id': u'7a1ca9f7cc4e4b13ac0ed2957f1e8c32'
|
||||
},
|
||||
{
|
||||
u'admin_state_up': True,
|
||||
u'id': u'405abfcc-77dc-49b2-a271-139619ac9b26',
|
||||
u'mtu': 0,
|
||||
u'name': u'openstackjenkins-network1',
|
||||
u'router:external': False,
|
||||
u'shared': False,
|
||||
u'status': u'ACTIVE',
|
||||
u'subnets': [u'a47910bc-f649-45db-98ec-e2421c413f4e'],
|
||||
u'tenant_id': u'7e9c4d5842b3451d94417bd0af03a0f4'
|
||||
},
|
||||
{
|
||||
u'admin_state_up': True,
|
||||
u'id': u'54753d2c-0a58-4928-9b32-084c59dd20a6',
|
||||
u'mtu': 0,
|
||||
u'name': u'GATEWAY_NET_V6',
|
||||
u'router:external': True,
|
||||
u'shared': True,
|
||||
u'status': u'ACTIVE',
|
||||
u'subnets': [u'9c21d704-a8b9-409a-b56d-501cb518d380',
|
||||
u'7cb0ce07-64c3-4a3d-92d3-6f11419b45b9'],
|
||||
u'tenant_id': u'7a1ca9f7cc4e4b13ac0ed2957f1e8c32'
|
||||
}
|
||||
]
|
||||
|
||||
OSIC_SUBNETS = [
|
||||
{
|
||||
u'allocation_pools': [{
|
||||
u'end': u'172.99.106.254',
|
||||
u'start': u'172.99.106.5'}],
|
||||
u'cidr': u'172.99.106.0/24',
|
||||
u'dns_nameservers': [u'69.20.0.164', u'69.20.0.196'],
|
||||
u'enable_dhcp': True,
|
||||
u'gateway_ip': u'172.99.106.1',
|
||||
u'host_routes': [],
|
||||
u'id': u'cf785ee0-6cc9-4712-be3d-0bf6c86cf455',
|
||||
u'ip_version': 4,
|
||||
u'ipv6_address_mode': None,
|
||||
u'ipv6_ra_mode': None,
|
||||
u'name': u'GATEWAY_NET',
|
||||
u'network_id': u'7004a83a-13d3-4dcd-8cf5-52af1ace4cae',
|
||||
u'subnetpool_id': None,
|
||||
u'tenant_id': u'7a1ca9f7cc4e4b13ac0ed2957f1e8c32'
|
||||
},
|
||||
{
|
||||
u'allocation_pools': [{
|
||||
u'end': u'10.0.1.254', u'start': u'10.0.1.2'}],
|
||||
u'cidr': u'10.0.1.0/24',
|
||||
u'dns_nameservers': [u'8.8.8.8', u'8.8.4.4'],
|
||||
u'enable_dhcp': True,
|
||||
u'gateway_ip': u'10.0.1.1',
|
||||
u'host_routes': [],
|
||||
u'id': u'a47910bc-f649-45db-98ec-e2421c413f4e',
|
||||
u'ip_version': 4,
|
||||
u'ipv6_address_mode': None,
|
||||
u'ipv6_ra_mode': None,
|
||||
u'name': u'openstackjenkins-subnet1',
|
||||
u'network_id': u'405abfcc-77dc-49b2-a271-139619ac9b26',
|
||||
u'subnetpool_id': None,
|
||||
u'tenant_id': u'7e9c4d5842b3451d94417bd0af03a0f4'
|
||||
},
|
||||
{
|
||||
u'allocation_pools': [{
|
||||
u'end': u'10.255.255.254', u'start': u'10.0.0.2'}],
|
||||
u'cidr': u'10.0.0.0/8',
|
||||
u'dns_nameservers': [u'8.8.8.8', u'8.8.4.4'],
|
||||
u'enable_dhcp': True,
|
||||
u'gateway_ip': u'10.0.0.1',
|
||||
u'host_routes': [],
|
||||
u'id': u'9c21d704-a8b9-409a-b56d-501cb518d380',
|
||||
u'ip_version': 4,
|
||||
u'ipv6_address_mode': None,
|
||||
u'ipv6_ra_mode': None,
|
||||
u'name': u'GATEWAY_SUBNET_V6V4',
|
||||
u'network_id': u'54753d2c-0a58-4928-9b32-084c59dd20a6',
|
||||
u'subnetpool_id': None,
|
||||
u'tenant_id': u'7a1ca9f7cc4e4b13ac0ed2957f1e8c32'
|
||||
},
|
||||
{
|
||||
u'allocation_pools': [{
|
||||
u'end': u'2001:4800:1ae1:18:ffff:ffff:ffff:ffff',
|
||||
u'start': u'2001:4800:1ae1:18::2'}],
|
||||
u'cidr': u'2001:4800:1ae1:18::/64',
|
||||
u'dns_nameservers': [u'2001:4860:4860::8888'],
|
||||
u'enable_dhcp': True,
|
||||
u'gateway_ip': u'2001:4800:1ae1:18::1',
|
||||
u'host_routes': [],
|
||||
u'id': u'7cb0ce07-64c3-4a3d-92d3-6f11419b45b9',
|
||||
u'ip_version': 6,
|
||||
u'ipv6_address_mode': u'dhcpv6-stateless',
|
||||
u'ipv6_ra_mode': None,
|
||||
u'name': u'GATEWAY_SUBNET_V6V6',
|
||||
u'network_id': u'54753d2c-0a58-4928-9b32-084c59dd20a6',
|
||||
u'subnetpool_id': None,
|
||||
u'tenant_id': u'7a1ca9f7cc4e4b13ac0ed2957f1e8c32'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class TestMeta(base.TestCase):
|
||||
def test_find_nova_addresses_key_name(self):
|
||||
@ -394,6 +516,61 @@ class TestMeta(base.TestCase):
|
||||
mock_list_networks.assert_not_called()
|
||||
mock_list_floating_ips.assert_not_called()
|
||||
|
||||
@mock.patch.object(shade.OpenStackCloud, 'list_floating_ips')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'list_subnets')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'list_server_security_groups')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'get_image_name')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'get_flavor_name')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'has_service')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'list_networks')
|
||||
def test_get_server_cloud_osic_split(
|
||||
self, mock_list_networks, mock_has_service,
|
||||
mock_get_flavor_name, mock_get_image_name,
|
||||
mock_list_server_security_groups,
|
||||
mock_list_subnets,
|
||||
mock_list_floating_ips):
|
||||
self.cloud._floating_ip_source = None
|
||||
self.cloud.force_ipv4 = False
|
||||
self.cloud._local_ipv6 = True
|
||||
self.cloud._external_ipv4_names = ['GATEWAY_NET']
|
||||
self.cloud._external_ipv6_names = ['GATEWAY_NET_V6']
|
||||
self.cloud._internal_ipv4_names = ['GATEWAY_NET_V6']
|
||||
self.cloud._internal_ipv6_names = []
|
||||
mock_get_image_name.return_value = 'cirros-0.3.4-x86_64-uec'
|
||||
mock_get_flavor_name.return_value = 'm1.tiny'
|
||||
mock_has_service.return_value = True
|
||||
mock_list_subnets.return_value = OSIC_SUBNETS
|
||||
mock_list_networks.return_value = OSIC_NETWORKS
|
||||
|
||||
srv = self.cloud.get_openstack_vars(meta.obj_to_dict(fakes.FakeServer(
|
||||
id='test-id', name='test-name', status='ACTIVE',
|
||||
flavor={u'id': u'1'},
|
||||
image={
|
||||
'name': u'cirros-0.3.4-x86_64-uec',
|
||||
u'id': u'f93d000b-7c29-4489-b375-3641a1758fe1'},
|
||||
addresses={
|
||||
'private': [{
|
||||
'addr': "10.223.160.141",
|
||||
'version': 4
|
||||
}],
|
||||
'public': [{
|
||||
'addr': "104.130.246.91",
|
||||
'version': 4
|
||||
}, {
|
||||
'addr': "2001:4800:7819:103:be76:4eff:fe05:8525",
|
||||
'version': 6
|
||||
}]
|
||||
}
|
||||
)))
|
||||
|
||||
self.assertEqual("10.223.160.141", srv['private_v4'])
|
||||
self.assertEqual("104.130.246.91", srv['public_v4'])
|
||||
self.assertEqual(
|
||||
"2001:4800:7819:103:be76:4eff:fe05:8525", srv['public_v6'])
|
||||
self.assertEqual(
|
||||
"2001:4800:7819:103:be76:4eff:fe05:8525", srv['interface_ip'])
|
||||
mock_list_floating_ips.assert_not_called()
|
||||
|
||||
@mock.patch.object(shade.OpenStackCloud, 'has_service')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'list_subnets')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'list_networks')
|
||||
|
Loading…
x
Reference in New Issue
Block a user