Extend network and existing_network contexts to save subnets

Change-Id: If820905dbe67563647ae95127800961b2e6e35af
This commit is contained in:
Andrey Kurilin
2020-04-21 23:20:47 +03:00
parent f13406795a
commit 465552f65c
6 changed files with 98 additions and 36 deletions

View File

@@ -42,6 +42,9 @@ Changed
* Bump min supported Rally framework version (rally>=3.0.0)
* Extend *network@openstack* context to save information about created subnets
and *existing_network@openstack* context with listing subnets.
Deprecated
~~~~~~~~~~

View File

@@ -198,7 +198,7 @@ class NeutronWrapper(NetworkWrapper):
start_cidr=self.start_cidr if ip_version == 4
else self.start_ipv6_cidr)
def create_network(self, tenant_id, **kwargs):
def _create_network_infrastructure(self, tenant_id, **kwargs):
"""Create network.
The following keyword arguments are accepted:
@@ -258,19 +258,48 @@ class NeutronWrapper(NetworkWrapper):
}
}
subnet = self.client.create_subnet(subnet_args)["subnet"]
subnets.append(subnet["id"])
subnets.append(subnet)
if router:
self.client.add_interface_router(router["id"],
{"subnet_id": subnet["id"]})
return {"id": network["id"],
return {
"network": {
"id": network["id"],
"name": network["name"],
"status": network["status"],
"subnets": subnets,
"subnets": [s["id"] for s in subnets],
"external": network.get("router:external", False),
"router_id": router and router["id"] or None,
"tenant_id": tenant_id}
"tenant_id": tenant_id
},
"subnets": subnets,
"router": router
}
def create_network(self, tenant_id, **kwargs):
"""Create network.
The following keyword arguments are accepted:
* add_router: Deprecated, please use router_create_args instead.
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
* dualstack: Whether subnets should be of both IPv4 and IPv6
* dns_nameservers: Nameservers for each subnet. Default:
8.8.8.8, 8.8.4.4
* network_create_args: Additional network creation arguments.
* router_create_args: Additional router creation arguments.
:param tenant_id: str, tenant ID
:param kwargs: Additional options, left open-ended for compatbilitiy.
See above for recognized keyword args.
:returns: dict, network data
"""
return self._create_network_infrastructure(
tenant_id, **kwargs)["network"]
def delete_v1_pool(self, pool_id):
"""Delete LB Pool (v1)

View File

@@ -16,7 +16,6 @@ from rally.common import validation
from rally_openstack.common import consts
from rally_openstack.common import osclients
from rally_openstack.common.wrappers import network as network_wrapper
from rally_openstack.task import context
@@ -36,11 +35,14 @@ class ExistingNetwork(context.OpenStackContext):
def setup(self):
for user, tenant_id in self._iterate_per_tenants():
net_wrapper = network_wrapper.wrap(
osclients.Clients(user["credential"]), self,
config=self.config)
clients = osclients.Clients(user["credential"])
self.context["tenants"][tenant_id]["networks"] = (
net_wrapper.list_networks())
clients.neutron().list_networks()["networks"]
)
self.context["tenants"][tenant_id]["subnets"] = (
clients.neutron().list_subnets()["subnets"]
)
def cleanup(self):
"""Networks were not created by Rally, so nothing to do."""

View File

@@ -102,24 +102,31 @@ class Network(context.OpenStackContext):
# creating a connection in setup and cleanup separately.
net_wrapper = network_wrapper.wrap(
osclients.Clients(self.context["admin"]["credential"]),
self, config=self.config)
self,
config=self.config
)
kwargs = {}
if self.config["dns_nameservers"] is not None:
kwargs["dns_nameservers"] = self.config["dns_nameservers"]
for user, tenant_id in self._iterate_per_tenants():
self.context["tenants"][tenant_id]["networks"] = []
self.context["tenants"][tenant_id]["subnets"] = []
for i in range(self.config["networks_per_tenant"]):
# NOTE(amaretskiy): router_create_args and subnets_num take
# effect for Neutron only.
network_create_args = self.config["network_create_args"].copy()
network = net_wrapper.create_network(
net_infra = net_wrapper._create_network_infrastructure(
tenant_id,
dualstack=self.config["dualstack"],
subnets_num=self.config["subnets_per_network"],
network_create_args=network_create_args,
router_create_args=self.config["router"],
**kwargs)
self.context["tenants"][tenant_id]["networks"].append(network)
self.context["tenants"][tenant_id]["networks"].append(
net_infra["network"]
)
self.context["tenants"][tenant_id]["subnets"].extend(
net_infra["subnets"]
)
def cleanup(self):
net_wrapper = network_wrapper.wrap(

View File

@@ -31,10 +31,10 @@ class ExistingNetworkTestCase(test.TestCase):
"users": [
{"id": 1,
"tenant_id": "tenant1",
"credential": mock.Mock()},
"credential": mock.Mock(tenant_name="tenant_1")},
{"id": 2,
"tenant_id": "tenant2",
"credential": mock.Mock()},
"credential": mock.Mock(tenant_name="tenant_2")},
],
"tenants": {
"tenant1": {},
@@ -46,34 +46,51 @@ class ExistingNetworkTestCase(test.TestCase):
})
@mock.patch("rally_openstack.common.osclients.Clients")
@mock.patch("rally_openstack.common.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:]})
def test_setup(self, mock_clients):
clients = {
# key is tenant_name
"tenant_1": mock.MagicMock(),
"tenant_2": mock.MagicMock()
}
mock_network_wrap.side_effect = [net_wrappers["tenant1"],
net_wrappers["tenant2"]]
mock_clients.side_effect = lambda cred: clients[cred.tenant_name]
networks = {
# key is tenant_id
"tenant_1": [mock.Mock(), mock.Mock()],
"tenant_2": [mock.Mock()]
}
subnets = {
# key is tenant_id
"tenant_1": [mock.Mock()],
"tenant_2": [mock.Mock()]
}
neutron1 = clients["tenant_1"].neutron.return_value
neutron2 = clients["tenant_2"].neutron.return_value
neutron1.list_networks.return_value = {
"networks": networks["tenant_1"]}
neutron2.list_networks.return_value = {
"networks": networks["tenant_2"]}
neutron1.list_subnets.return_value = {"subnets": subnets["tenant_1"]}
neutron2.list_subnets.return_value = {"subnets": subnets["tenant_2"]}
context = existing_network.ExistingNetwork(self.context)
context.setup()
mock_clients.assert_has_calls([
mock.call(u["credential"]) for u in self.context["users"]])
mock_network_wrap.assert_has_calls([
mock.call(mock_clients.return_value, context, config=self.config),
mock.call(mock_clients.return_value, context, config=self.config)])
for net_wrapper in net_wrappers.values():
net_wrapper.list_networks.assert_called_once_with()
neutron1.list_networks.assert_called_once_with()
neutron1.list_subnets.assert_called_once_with()
neutron2.list_networks.assert_called_once_with()
neutron2.list_subnets.assert_called_once_with()
self.assertEqual(
self.context["tenants"],
{
"tenant1": {"networks": networks[0:2]},
"tenant2": {"networks": networks[2:]},
"tenant1": {"networks": networks["tenant_1"],
"subnets": subnets["tenant_1"]},
"tenant2": {"networks": networks["tenant_2"],
"subnets": subnets["tenant_2"]},
}
)

View File

@@ -68,8 +68,12 @@ class NetworkTestCase(test.TestCase):
@mock.patch(NET + "wrap")
@mock.patch("rally_openstack.common.osclients.Clients")
def test_setup(self, mock_clients, mock_wrap, **dns_kwargs):
mock_create = mock.Mock(side_effect=lambda t, **kw: t + "-net")
mock_wrap.return_value = mock.Mock(create_network=mock_create)
def create_net_infra(t_id, **kwargs):
return {"network": f"{t_id}-net", "subnets": []}
mock_create = mock.Mock(side_effect=create_net_infra)
mock_wrap.return_value = mock.Mock(
_create_network_infrastructure=mock_create)
nets_per_tenant = 2
net_context = network_context.Network(
self.get_context(networks_per_tenant=nets_per_tenant,