Merge "Add existing_network context"
This commit is contained in:
commit
75308e6392
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)
|
cidr = generate_cidr(start_cidr=self.start_cidr)
|
||||||
return 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):
|
def create_network(self, tenant_id, **kwargs):
|
||||||
"""Create network.
|
"""Create network.
|
||||||
|
|
||||||
@ -123,18 +138,14 @@ class NovaNetworkWrapper(NetworkWrapper):
|
|||||||
label = utils.generate_random_name("rally_net_")
|
label = utils.generate_random_name("rally_net_")
|
||||||
network = self.client.networks.create(
|
network = self.client.networks.create(
|
||||||
tenant_id=tenant_id, cidr=cidr, label=label)
|
tenant_id=tenant_id, cidr=cidr, label=label)
|
||||||
return {"id": network.id,
|
return self._marshal_network_object(network)
|
||||||
"cidr": network.cidr,
|
|
||||||
"name": network.label,
|
|
||||||
"status": "ACTIVE",
|
|
||||||
"external": False,
|
|
||||||
"tenant_id": tenant_id}
|
|
||||||
|
|
||||||
def delete_network(self, network):
|
def delete_network(self, network):
|
||||||
return self.client.networks.delete(network["id"])
|
return self.client.networks.delete(network["id"])
|
||||||
|
|
||||||
def list_networks(self):
|
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):
|
def create_floating_ip(self, ext_network=None, **kwargs):
|
||||||
"""Allocate a floating ip from the given nova-network pool
|
"""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):
|
class Net(object):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
if "tenant_id" in kwargs:
|
||||||
|
kwargs["project_id"] = kwargs.pop("tenant_id")
|
||||||
self.__dict__.update(kwargs)
|
self.__dict__.update(kwargs)
|
||||||
|
|
||||||
def get_wrapper(self, *skip_cidrs, **kwargs):
|
def get_wrapper(self, *skip_cidrs, **kwargs):
|
||||||
@ -88,9 +90,18 @@ class NovaNetworkWrapperTestCase(test.TestCase):
|
|||||||
|
|
||||||
def test_list_networks(self):
|
def test_list_networks(self):
|
||||||
service = self.get_wrapper()
|
service = self.get_wrapper()
|
||||||
service.client.networks.list.return_value = "foo_list"
|
|
||||||
service.client.networks.list.reset_mock()
|
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()
|
service.client.networks.list.assert_called_once_with()
|
||||||
|
|
||||||
def test__get_floating_ip(self):
|
def test__get_floating_ip(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user