Add existing_network context
This context lets you use existing networks that have already been created instead of creating new networks with Rally. This is useful when, for instance, you are using Neutron with a dumb router that is not capable of creating new networks on the fly. Change-Id: I3718dba57145c3e64237dcb758cdcf3505e000dd
This commit is contained in:
parent
12b1abd86d
commit
7eb81c91ba
53
rally/plugins/openstack/context/existing_network.py
Normal file
53
rally/plugins/openstack/context/existing_network.py
Normal file
@ -0,0 +1,53 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 rally.common.i18n import _
|
||||
from rally.common import log as logging
|
||||
from rally.common import utils
|
||||
from rally import consts
|
||||
from rally import osclients
|
||||
from rally.plugins.openstack.wrappers import network as network_wrapper
|
||||
from rally.task import context
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@context.configure(name="existing_network", order=349)
|
||||
class ExistingNetwork(context.Context):
|
||||
"""This context supports using existing networks in Rally.
|
||||
|
||||
This context should be used on a deployment with existing users.
|
||||
"""
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
"type": "object",
|
||||
"$schema": consts.JSON_SCHEMA,
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
@utils.log_task_wrapper(LOG.info, _("Enter context: `existing_network`"))
|
||||
def setup(self):
|
||||
for user, tenant_id in utils.iterate_per_tenants(
|
||||
self.context.get("users", [])):
|
||||
net_wrapper = network_wrapper.wrap(
|
||||
osclients.Clients(user["endpoint"]),
|
||||
self.config)
|
||||
self.context["tenants"][tenant_id]["networks"] = (
|
||||
net_wrapper.list_networks())
|
||||
|
||||
@utils.log_task_wrapper(LOG.info, _("Exit context: `existing_network`"))
|
||||
def cleanup(self):
|
||||
"""Networks were not created by Rally, so nothing to do."""
|
@ -112,6 +112,21 @@ class NovaNetworkWrapper(NetworkWrapper):
|
||||
cidr = generate_cidr(start_cidr=self.start_cidr)
|
||||
return cidr
|
||||
|
||||
def _marshal_network_object(self, net_obj):
|
||||
"""Convert a Network object to a dict.
|
||||
|
||||
This helps keep return values from the NovaNetworkWrapper
|
||||
compatible with those from NeutronWrapper.
|
||||
|
||||
:param net_obj: The Network object to convert to a dict
|
||||
"""
|
||||
return {"id": net_obj.id,
|
||||
"cidr": net_obj.cidr,
|
||||
"name": net_obj.label,
|
||||
"status": "ACTIVE",
|
||||
"external": False,
|
||||
"tenant_id": net_obj.project_id}
|
||||
|
||||
def create_network(self, tenant_id, **kwargs):
|
||||
"""Create network.
|
||||
|
||||
@ -123,18 +138,14 @@ class NovaNetworkWrapper(NetworkWrapper):
|
||||
label = utils.generate_random_name("rally_net_")
|
||||
network = self.client.networks.create(
|
||||
tenant_id=tenant_id, cidr=cidr, label=label)
|
||||
return {"id": network.id,
|
||||
"cidr": network.cidr,
|
||||
"name": network.label,
|
||||
"status": "ACTIVE",
|
||||
"external": False,
|
||||
"tenant_id": tenant_id}
|
||||
return self._marshal_network_object(network)
|
||||
|
||||
def delete_network(self, network):
|
||||
return self.client.networks.delete(network["id"])
|
||||
|
||||
def list_networks(self):
|
||||
return self.client.networks.list()
|
||||
return [self._marshal_network_object(n)
|
||||
for n in self.client.networks.list()]
|
||||
|
||||
def create_floating_ip(self, ext_network=None, **kwargs):
|
||||
"""Allocate a floating ip from the given nova-network pool
|
||||
|
@ -0,0 +1,81 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from rally.plugins.openstack.context import existing_network
|
||||
from tests.unit import test
|
||||
|
||||
CTX = "rally.plugins.openstack.context"
|
||||
|
||||
|
||||
class ExistingNetworkTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ExistingNetworkTestCase, self).setUp()
|
||||
|
||||
self.config = mock.MagicMock()
|
||||
self.context = {
|
||||
"task": mock.MagicMock(),
|
||||
"users": [
|
||||
{"id": 1,
|
||||
"tenant_id": "tenant1",
|
||||
"endpoint": mock.Mock()},
|
||||
{"id": 2,
|
||||
"tenant_id": "tenant2",
|
||||
"endpoint": mock.Mock()},
|
||||
],
|
||||
"tenants": {
|
||||
"tenant1": {},
|
||||
"tenant2": {},
|
||||
},
|
||||
"config": {
|
||||
"existing_network": self.config
|
||||
},
|
||||
}
|
||||
|
||||
@mock.patch("rally.osclients.Clients")
|
||||
@mock.patch("rally.plugins.openstack.wrappers.network.wrap")
|
||||
def test_setup(self, mock_network_wrap, mock_clients):
|
||||
networks = [mock.Mock(), mock.Mock(), mock.Mock()]
|
||||
net_wrappers = {
|
||||
"tenant1": mock.Mock(
|
||||
**{"list_networks.return_value": networks[0:2]}),
|
||||
"tenant2": mock.Mock(
|
||||
**{"list_networks.return_value": networks[2:]})
|
||||
}
|
||||
mock_network_wrap.side_effect = [net_wrappers["tenant1"],
|
||||
net_wrappers["tenant2"]]
|
||||
|
||||
existing_network.ExistingNetwork(self.context).setup()
|
||||
|
||||
mock_clients.assert_has_calls([
|
||||
mock.call(u["endpoint"]) for u in self.context["users"]])
|
||||
mock_network_wrap.assert_has_calls([
|
||||
mock.call(mock_clients.return_value, self.config),
|
||||
mock.call(mock_clients.return_value, self.config)])
|
||||
for net_wrapper in net_wrappers.values():
|
||||
net_wrapper.list_networks.assert_called_once_with()
|
||||
|
||||
self.assertDictEqual(
|
||||
self.context["tenants"],
|
||||
{
|
||||
"tenant1": {"networks": networks[0:2]},
|
||||
"tenant2": {"networks": networks[2:]},
|
||||
}
|
||||
)
|
||||
|
||||
def test_cleanup(self):
|
||||
# NOTE(stpierre): Test that cleanup is not abstract
|
||||
existing_network.ExistingNetwork({"task": mock.MagicMock()}).cleanup()
|
@ -30,6 +30,8 @@ class NovaNetworkWrapperTestCase(test.TestCase):
|
||||
|
||||
class Net(object):
|
||||
def __init__(self, **kwargs):
|
||||
if "tenant_id" in kwargs:
|
||||
kwargs["project_id"] = kwargs.pop("tenant_id")
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def get_wrapper(self, *skip_cidrs, **kwargs):
|
||||
@ -88,9 +90,18 @@ class NovaNetworkWrapperTestCase(test.TestCase):
|
||||
|
||||
def test_list_networks(self):
|
||||
service = self.get_wrapper()
|
||||
service.client.networks.list.return_value = "foo_list"
|
||||
service.client.networks.list.reset_mock()
|
||||
self.assertEqual(service.list_networks(), "foo_list")
|
||||
service.client.networks.list.return_value = [
|
||||
self.Net(id="foo_id", project_id="foo_tenant", cidr="foo_cidr",
|
||||
label="foo_label"),
|
||||
self.Net(id="bar_id", project_id="bar_tenant", cidr="bar_cidr",
|
||||
label="bar_label")]
|
||||
expected = [
|
||||
{"id": "foo_id", "cidr": "foo_cidr", "name": "foo_label",
|
||||
"status": "ACTIVE", "external": False, "tenant_id": "foo_tenant"},
|
||||
{"id": "bar_id", "cidr": "bar_cidr", "name": "bar_label",
|
||||
"status": "ACTIVE", "external": False, "tenant_id": "bar_tenant"}]
|
||||
self.assertEqual(expected, service.list_networks())
|
||||
service.client.networks.list.assert_called_once_with()
|
||||
|
||||
def test__get_floating_ip(self):
|
||||
|
Loading…
Reference in New Issue
Block a user