Find an external network when no one is provided
Esternal network ID is stored in a Heat stack to keep the same network ID for later test case executions. Remove logic to found for looking for an external network from DevStack plugin. Change-Id: Ic7fe03324f4f328488988435530e127cedfab781
This commit is contained in:
parent
db68499e39
commit
0df9ce7868
@ -142,12 +142,8 @@ function configure_tobiko_neutron {
|
||||
# Write floating network
|
||||
local floating_network=${TOBIKO_NEUTRON_FLOATING_NETWORK}
|
||||
if [ "${floating_network}" != "" ]; then
|
||||
local floating_network=$(openstack network show -f value -c name "${floating_network}")
|
||||
else
|
||||
local networks=( $( openstack network list -f value -c Name --enable --external) )
|
||||
local floating_network=${networks[0]}
|
||||
iniset "${tobiko_conf_file}" neutron floating_network "${floating_network}"
|
||||
fi
|
||||
iniset "${tobiko_conf_file}" neutron floating_network "${floating_network}"
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,7 +81,7 @@ def filter_by_items(dictionaries, exclude=False, **items):
|
||||
|
||||
|
||||
class ObjectNotFound(_exception.TobikoException):
|
||||
"Object not found."
|
||||
"Object not found"
|
||||
|
||||
|
||||
class MultipleObjectsFound(_exception.TobikoException):
|
||||
|
@ -38,6 +38,10 @@ get_port = _client.get_port
|
||||
get_subnet = _client.get_subnet
|
||||
list_l3_agent_hosting_routers = _client.list_l3_agent_hosting_routers
|
||||
find_l3_agent_hosting_router = _client.find_l3_agent_hosting_router
|
||||
NoSuchNetwork = _client.NoSuchNetwork
|
||||
NoSuchPort = _client.NoSuchPort
|
||||
NoSuchRouter = _client.NoSuchRouter
|
||||
NoSuchSubnet = _client.NoSuchSubnet
|
||||
|
||||
new_ipv4_cidr = _cidr.new_ipv4_cidr
|
||||
new_ipv6_cidr = _cidr.new_ipv6_cidr
|
||||
|
@ -136,19 +136,32 @@ def get_floating_ip(floating_ip, client=None, **params):
|
||||
|
||||
|
||||
def get_network(network, client=None, **params):
|
||||
return neutron_client(client).show_network(network, **params)['network']
|
||||
try:
|
||||
return neutron_client(client).show_network(network,
|
||||
**params)['network']
|
||||
except neutronclient.exceptions.NotFound:
|
||||
raise NoSuchNetwork(id=network)
|
||||
|
||||
|
||||
def get_port(port, client=None, **params):
|
||||
return neutron_client(client).show_port(port, **params)['port']
|
||||
try:
|
||||
return neutron_client(client).show_port(port, **params)['port']
|
||||
except neutronclient.exceptions.NotFound:
|
||||
raise NoSuchPort(id=port)
|
||||
|
||||
|
||||
def get_router(router, client=None, **params):
|
||||
return neutron_client(client).show_router(router, **params)['router']
|
||||
try:
|
||||
return neutron_client(client).show_router(router, **params)['router']
|
||||
except neutronclient.exceptions.NotFound:
|
||||
raise NoSuchRouter(id=router)
|
||||
|
||||
|
||||
def get_subnet(subnet, client=None, **params):
|
||||
return neutron_client(client).show_subnet(subnet, **params)['subnet']
|
||||
try:
|
||||
return neutron_client(client).show_subnet(subnet, **params)['subnet']
|
||||
except neutronclient.exceptions.NotFound:
|
||||
raise NoSuchSubnet(id=subnet)
|
||||
|
||||
|
||||
def list_l3_agent_hosting_routers(router, client=None, **params):
|
||||
@ -170,3 +183,19 @@ def find_l3_agent_hosting_router(router, client=None, unique=False,
|
||||
return agents.first
|
||||
else:
|
||||
return default
|
||||
|
||||
|
||||
class NoSuchNetwork(tobiko.ObjectNotFound):
|
||||
message = "No such network found for {id!r}"
|
||||
|
||||
|
||||
class NoSuchPort(tobiko.ObjectNotFound):
|
||||
message = "No such port found for {id!r}"
|
||||
|
||||
|
||||
class NoSuchRouter(tobiko.ObjectNotFound):
|
||||
message = "No such router found for {id!r}"
|
||||
|
||||
|
||||
class NoSuchSubnet(tobiko.ObjectNotFound):
|
||||
message = "No such subnet found for {id!r}"
|
||||
|
@ -1,24 +0,0 @@
|
||||
# Copyright 2019 Red Hat
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import tobiko
|
||||
|
||||
|
||||
class NoSuchNetwork(tobiko.TobikoException):
|
||||
message = "No such network found for {network!r}"
|
||||
|
||||
|
||||
class MoreNetworksFound(tobiko.TobikoException):
|
||||
message = "More than one network found for {network!r}: {network_ids!s}"
|
@ -49,6 +49,10 @@ NetworkWithNetMtuWriteStackFixture = (
|
||||
_neutron.NetworkWithNetMtuWriteStackFixture)
|
||||
SecurityGroupsFixture = _neutron.SecurityGroupsFixture
|
||||
|
||||
get_floating_network = _neutron.get_floating_network
|
||||
has_floating_network = _neutron.has_floating_network
|
||||
skip_if_missing_floating_network = _neutron.skip_if_missing_floating_network
|
||||
|
||||
ServerStackFixture = _nova.ServerStackFixture
|
||||
KeyPairStackFixture = _nova.KeyPairStackFixture
|
||||
FlavorStackFixture = _nova.FlavorStackFixture
|
||||
|
@ -15,6 +15,8 @@
|
||||
# under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
|
||||
import netaddr
|
||||
from oslo_log import log
|
||||
|
||||
@ -25,10 +27,45 @@ from tobiko.openstack import neutron
|
||||
from tobiko.openstack.stacks import _hot
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class FloatingNetworkStackFixture(heat.HeatStackFixture):
|
||||
|
||||
template = _hot.heat_template_file('neutron/floating_network.yaml')
|
||||
|
||||
@property
|
||||
def external_name(self):
|
||||
return tobiko.tobiko_config().neutron.floating_network
|
||||
|
||||
_external_network = None
|
||||
|
||||
@property
|
||||
def external_network(self):
|
||||
network = self._external_network
|
||||
if network is None:
|
||||
self._external_network = network = find_external_network(
|
||||
name=self.external_name) or {}
|
||||
return network
|
||||
|
||||
@property
|
||||
def external_id(self):
|
||||
network = self.external_network
|
||||
return network and network['id'] or None
|
||||
|
||||
@property
|
||||
def has_external_id(self):
|
||||
return bool(self.external_id)
|
||||
|
||||
@property
|
||||
def network_details(self):
|
||||
return neutron.get_network(self.network_id)
|
||||
|
||||
|
||||
@neutron.skip_if_missing_networking_extensions('port-security')
|
||||
class NetworkStackFixture(heat.HeatStackFixture):
|
||||
"""Heat stack for creating internal network with a router to external"""
|
||||
@ -68,10 +105,18 @@ class NetworkStackFixture(heat.HeatStackFixture):
|
||||
"""Extra network creation parameters"""
|
||||
return {}
|
||||
|
||||
floating_network_stack = tobiko.required_setup_fixture(
|
||||
FloatingNetworkStackFixture)
|
||||
|
||||
@property
|
||||
def floating_network(self):
|
||||
"""Network ID where the Neutron floating IPs are created"""
|
||||
return self.floating_network_stack.network_id
|
||||
|
||||
@property
|
||||
def gateway_network(self):
|
||||
"""Floating IP network where the Neutron floating IPs are created"""
|
||||
return CONF.tobiko.neutron.floating_network
|
||||
"""Network ID where gateway routes packages to"""
|
||||
return self.floating_network
|
||||
|
||||
ha = False
|
||||
|
||||
@ -200,3 +245,48 @@ class SecurityGroupsFixture(heat.HeatStackFixture):
|
||||
"""
|
||||
#: Heat template file
|
||||
template = _hot.heat_template_file('neutron/security_groups.yaml')
|
||||
|
||||
|
||||
def find_external_network(name=None):
|
||||
network = None
|
||||
if name:
|
||||
try:
|
||||
network = neutron.get_network(name)
|
||||
except neutron.NoSuchNetwork:
|
||||
LOG.debug('No such network with ID %r', name)
|
||||
|
||||
if not network:
|
||||
params = {'router:external': True, "status": "ACTIVE"}
|
||||
if name:
|
||||
params['name'] = name
|
||||
try:
|
||||
network = neutron.find_network(**params)
|
||||
except tobiko.ObjectNotFound:
|
||||
LOG.exception('No such network (%s):',
|
||||
json.dumps(params, sort_keys=True))
|
||||
if name:
|
||||
message = ('No such external network with name or ID '
|
||||
'{!r}').format(name)
|
||||
raise ValueError(message)
|
||||
|
||||
if network:
|
||||
LOG.debug('Found external network %r:\n%s',
|
||||
network['name'], json.dumps(network, indent=4,
|
||||
sort_keys=True))
|
||||
return network
|
||||
|
||||
|
||||
def get_floating_network_id():
|
||||
return tobiko.setup_fixture(FloatingNetworkStackFixture).network_id
|
||||
|
||||
|
||||
def get_floating_network():
|
||||
return tobiko.setup_fixture(FloatingNetworkStackFixture).network_details
|
||||
|
||||
|
||||
def has_floating_network():
|
||||
return tobiko.setup_fixture(FloatingNetworkStackFixture).has_network
|
||||
|
||||
|
||||
skip_if_missing_floating_network = tobiko.skip_unless(
|
||||
'Floating network not found', has_floating_network)
|
||||
|
@ -129,12 +129,13 @@ class ServerStackFixture(heat.HeatStackFixture):
|
||||
def network(self):
|
||||
return self.network_stack.network_id
|
||||
|
||||
#: Floating IP network where the Neutron floating IP is created
|
||||
floating_network = CONF.tobiko.neutron.floating_network
|
||||
#: Floating IP network where the Neutron floating IP are created
|
||||
@property
|
||||
def floating_network(self):
|
||||
return self.network_stack.floating_network
|
||||
|
||||
@property
|
||||
def has_floating_ip(self):
|
||||
"""Whenever to allocate floating IP for the server"""
|
||||
return bool(self.floating_network)
|
||||
|
||||
@property
|
||||
|
40
tobiko/openstack/stacks/neutron/floating_network.yaml
Normal file
40
tobiko/openstack/stacks/neutron/floating_network.yaml
Normal file
@ -0,0 +1,40 @@
|
||||
heat_template_version: newton
|
||||
|
||||
|
||||
description: |
|
||||
Creates an network with a subnet and a gateway router to an external network
|
||||
if given
|
||||
|
||||
|
||||
parameters:
|
||||
external_id:
|
||||
description: Default value to be assigned to network ports
|
||||
type: string
|
||||
default: '<no-external-id>'
|
||||
|
||||
has_external_id:
|
||||
description: Extra network creation parameters
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
|
||||
conditions:
|
||||
has_network:
|
||||
get_param: has_external_id
|
||||
|
||||
|
||||
resources:
|
||||
network:
|
||||
type: OS::Neutron::Net
|
||||
external_id: {get_param: external_id}
|
||||
condition: has_network
|
||||
|
||||
|
||||
outputs:
|
||||
network_id:
|
||||
description: Network ID
|
||||
value: {get_resource: network}
|
||||
|
||||
has_network:
|
||||
description: Whenever has a floating network
|
||||
value: {get_param: has_external_id}
|
@ -75,9 +75,7 @@ parameters:
|
||||
gateway_network:
|
||||
description: Optional gateway network to route packages to
|
||||
type: string
|
||||
default:
|
||||
constraints:
|
||||
- custom_constraint: neutron.network
|
||||
default: '<no-gateway-network>'
|
||||
|
||||
gateway_value_specs:
|
||||
description: Extra gateway router creation parameters
|
||||
|
@ -96,3 +96,17 @@ class L3HaNetworkTestCase(NetworkTestCase):
|
||||
|
||||
#: Stack of resources with a network with a gateway router
|
||||
stack = tobiko.required_setup_fixture(stacks.L3haNetworkStackFixture)
|
||||
|
||||
|
||||
class FloatingNetworkStackTest(testtools.TestCase):
|
||||
|
||||
@stacks.skip_if_missing_floating_network
|
||||
def test_get_floating_network(self):
|
||||
network = stacks.get_floating_network()
|
||||
self.assertTrue(network['id'])
|
||||
self.assertIs(True, network['router:external'])
|
||||
self.assertEqual('ACTIVE', network['status'])
|
||||
|
||||
@stacks.skip_if_missing_floating_network
|
||||
def test_has_floating_network(self):
|
||||
self.assertIs(True, stacks.has_floating_network())
|
||||
|
Loading…
x
Reference in New Issue
Block a user