Make network context more configurable

This adds two new configuration keys to the 'network' context:

* subnets_per_network lets the user specify more than one subnet per
  network, which was previously hard-coded.
* network_create_args lets the user pass arbitrary arguments to the
  network create function. This obviously has the potential to be
  specific to the network implementation, but that is left to the end
  user.

Change-Id: Ibbd334a4321bcd26538f129aeff85e8ef2cbda5a
This commit is contained in:
Chris St. Pierre
2015-08-07 10:48:43 -05:00
parent c9822a499d
commit 61430ad23c
4 changed files with 69 additions and 24 deletions

View File

@@ -39,6 +39,14 @@ class Network(context.Context):
"networks_per_tenant": {
"type": "integer",
"minimum": 1
},
"subnets_per_network": {
"type": "integer",
"minimum": 1
},
"network_create_args": {
"type": "object",
"additionalProperties": True
}
},
"additionalProperties": False
@@ -46,7 +54,9 @@ class Network(context.Context):
DEFAULT_CONFIG = {
"start_cidr": "10.2.0.0/24",
"networks_per_tenant": 1
"networks_per_tenant": 1,
"subnets_per_network": 1,
"network_create_args": {}
}
@utils.log_task_wrapper(LOG.info, _("Enter context: `network`"))
@@ -64,10 +74,11 @@ class Network(context.Context):
for i in range(self.config["networks_per_tenant"]):
# NOTE(amaretskiy): add_router and subnets_num take effect
# for Neutron only.
# NOTE(amaretskiy): Do we need neutron subnets_num > 1 ?
network = net_wrapper.create_network(tenant_id,
add_router=True,
subnets_num=1)
network = net_wrapper.create_network(
tenant_id,
add_router=True,
subnets_num=self.config["subnets_per_network"],
network_create_args=self.config["network_create_args"])
self.context["tenants"][tenant_id]["networks"].append(network)
@utils.log_task_wrapper(LOG.info, _("Exit context: `network`"))

View File

@@ -131,13 +131,20 @@ class NovaNetworkWrapper(NetworkWrapper):
"""Create network.
:param tenant_id: str, tenant ID
:param **kwargs: for compatibility, not used here
:param **kwargs: Additional keyword arguments. Only
``network_create_args`` is honored; other
arguments are accepted for compatibility, but
are not used here. ``network_create_args``
can be used to provide additional arbitrary
network creation arguments.
:returns: dict, network data
"""
cidr = self._generate_cidr()
label = utils.generate_random_name("rally_net_")
network_create_args = kwargs.get("network_create_args", {})
network = self.client.networks.create(
project_id=tenant_id, cidr=cidr, label=label)
project_id=tenant_id, cidr=cidr, label=label,
**network_create_args)
return self._marshal_network_object(network)
def delete_network(self, network):
@@ -271,16 +278,25 @@ class NeutronWrapper(NetworkWrapper):
def create_network(self, tenant_id, **kwargs):
"""Create network.
The following keyword arguments are accepted:
* add_router: Create an external router and add an interface to each
subnet created. Default: False
* subnets_num: Number of subnets to create per network. Default: 0
* dns_nameservers: Nameservers for each subnet. Default:
8.8.8.8, 8.8.4.4
* network_create_args: Additional network creation arguments.
:param tenant_id: str, tenant ID
:param **kwargs: extra options
:param kwargs: Additional options, left open-ended for compatbilitiy.
See above for recognized keyword args.
:returns: dict, network data
"""
network_args = {
"network": {
"tenant_id": tenant_id,
"name": utils.generate_random_name("rally_net_")
}
}
network_args = {"network": kwargs.get("network_create_args", {})}
network_args["network"].update({
"tenant_id": tenant_id,
"name": utils.generate_random_name("rally_net_")
})
network = self.client.create_network(network_args)["network"]
router = None

View File

@@ -47,9 +47,12 @@ class NetworkTestCase(test.TestCase):
@mock.patch(NET + "wrap", return_value="foo_service")
def test__init__explicit(self, mock_wrap, mock_clients):
context = network_context.Network(
self.get_context(start_cidr="foo_cidr", networks_per_tenant=42))
self.get_context(start_cidr="foo_cidr", networks_per_tenant=42,
network_create_args={"fakearg": "fake"}))
self.assertEqual(context.config["networks_per_tenant"], 42)
self.assertEqual(context.config["start_cidr"], "foo_cidr")
self.assertDictEqual(context.config["network_create_args"],
{"fakearg": "fake"})
@mock.patch(NET + "wrap")
@mock.patch("rally.plugins.openstack.context.network.networks.utils")
@@ -59,20 +62,30 @@ class NetworkTestCase(test.TestCase):
("foo_user", "foo_tenant"),
("bar_user", "bar_tenant")]
mock_create = mock.Mock(side_effect=lambda t, **kw: t + "-net")
mock_utils.generate_random_name = mock.Mock()
mock_wrap.return_value = mock.Mock(create_network=mock_create)
nets_per_tenant = 2
net_context = network_context.Network(
self.get_context(networks_per_tenant=nets_per_tenant))
self.get_context(networks_per_tenant=nets_per_tenant,
network_create_args={"fakearg": "fake"}))
net_context.setup()
create_calls = [
mock.call(tenant, add_router=True,
subnets_num=1, network_create_args={"fakearg": "fake"})
for user, tenant in mock_utils.iterate_per_tenants.return_value]
mock_create.assert_has_calls(create_calls)
mock_utils.iterate_per_tenants.assert_called_once_with(
net_context.context["users"])
expected_networks = [["bar_tenant-net"] * nets_per_tenant,
["foo_tenant-net"] * nets_per_tenant]
expected_networks = ["bar_tenant-net",
"foo_tenant-net"] * nets_per_tenant
actual_networks = []
for tenant_id, tenant_ctx in (
sorted(net_context.context["tenants"].items())):
actual_networks.append(tenant_ctx["networks"])
self.assertEqual(expected_networks, actual_networks)
for tenant_id, tenant_ctx in net_context.context["tenants"].items():
actual_networks.extend(tenant_ctx["networks"])
self.assertSequenceEqual(sorted(expected_networks),
sorted(actual_networks))
@mock.patch("rally.osclients.Clients")
@mock.patch(NET + "wrap")

View File

@@ -69,7 +69,9 @@ class NovaNetworkWrapperTestCase(test.TestCase):
service.client.networks.create.side_effect = (
lambda **kwargs: self.Net(id="foo_id", **kwargs))
service._generate_cidr = mock.Mock(return_value="foo_cidr")
net = service.create_network("foo_tenant", bar="spam")
net = service.create_network("foo_tenant",
network_create_args={"fakearg": "fake"},
bar="spam")
self.assertEqual(net, {"id": "foo_id",
"name": "foo_name",
"cidr": "foo_cidr",
@@ -79,7 +81,8 @@ class NovaNetworkWrapperTestCase(test.TestCase):
mock_generate_random_name.assert_called_once_with("rally_net_")
service._generate_cidr.assert_called_once_with()
service.client.networks.create.assert_called_once_with(
project_id="foo_tenant", cidr="foo_cidr", label="foo_name")
project_id="foo_tenant", cidr="foo_cidr", label="foo_name",
fakearg="fake")
def test_delete_network(self):
service = self.get_wrapper()
@@ -279,7 +282,9 @@ class NeutronWrapperTestCase(test.TestCase):
"network": {"id": "foo_id",
"name": "foo_name",
"status": "foo_status"}}
net = service.create_network("foo_tenant", subnets_num=subnets_num)
service.client.create_network.assert_called_once_with({
"network": {"tenant_id": "foo_tenant", "name": "foo_name"}})
self.assertEqual(net, {"id": "foo_id",