Use NeutronService helper instead of network wrapper

This change allows to use network context without admin user

Change-Id: Ia25148e08e33d80ea9d021d5e16f87153b902d94
This commit is contained in:
Andrey Kurilin 2020-04-28 15:12:31 +03:00
parent a0b3cc09d0
commit 4c207ae082
35 changed files with 1430 additions and 1850 deletions

View File

@ -58,6 +58,9 @@
- .zuul.d/zuul.yaml
- rally-jobs/neutron-trunk.yaml
- rally_openstack/common/osclients.py
- rally_openstack/common/services/network
- rally_openstack/task/cleanup/resources.py
- rally_openstack/task/contexts/network
- rally_openstack/task/scenarios/neutron/trunk.py
- rally_openstack/task/scenarios/neutron/network.py
- tests/ci/playbooks
@ -105,6 +108,9 @@
files:
- rally-jobs/neutron-trunk.yaml
- rally_openstack/common/osclients.py
- rally_openstack/common/services/network
- rally_openstack/task/cleanup/resources.py
- rally_openstack/task/contexts/network
- rally_openstack/task/scenarios/neutron/trunk.py
- rally_openstack/task/scenarios/neutron/network.py
- tests/ci/playbooks

View File

@ -26,9 +26,16 @@ Changed
image changed from /rally/xrally_opentstack to /rally/xrally_openstack
(there was a typo in work openstack)
* *network@openstack* context does not require admin credentials anymore and
work with regular users as well
Fixed
~~~~~
* Some neutron scenarios accepted *name* parameter for create or update actions
on various entities. The value of the parameter was always ignored, but
anyway it gave wrong assumption.
* [verification component] Make config parser case sensitivity in
TempestContext and TempestConfigfileManager.

View File

@ -78,8 +78,7 @@
workloads:
-
scenario:
NeutronNetworks.create_and_list_networks:
network_create_args:
NeutronNetworks.create_and_list_networks: {}
runner:
constant:
times: 2
@ -92,6 +91,8 @@
NeutronNetworks.create_and_list_subnets:
subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2
contexts:
network: {}
runner:
constant:
times: 2
@ -111,3 +112,25 @@
sla:
failure_rate:
max: 0
- title: Test VMTask scenario
workloads:
-
scenario:
VMTasks.dd_load_test:
flavor:
name: "m1.tiny"
image:
name: {{image_name}}
floating_network: "public"
force_delete: false
username: "cirros"
contexts:
network: {}
runner:
constant:
times: 2
concurrency: 2
sla:
failure_rate:
max: 0

View File

@ -89,8 +89,8 @@
NeutronNetworks.create_and_list_subnets:
-
args:
network_create_args:
subnet_create_args:
network_create_args: {}
subnet_create_args: {}
subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2
runner:
@ -113,8 +113,6 @@
NeutronNetworks.create_and_show_subnets:
-
args:
network_create_args:
subnet_create_args:
subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2
runner:
@ -316,11 +314,8 @@
NeutronNetworks.create_and_list_routers:
-
args:
network_create_args:
subnet_create_args:
subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2
router_create_args:
runner:
type: "constant"
times: {{smoke or 8}}
@ -362,8 +357,6 @@
NeutronNetworks.create_and_list_ports:
-
args:
network_create_args:
port_create_args:
ports_per_network: 4
runner:
type: "constant"
@ -403,8 +396,6 @@
NeutronNetworks.create_and_show_ports:
-
args:
network_create_args: {}
port_create_args: {}
ports_per_network: 2
runner:
type: "constant"
@ -429,7 +420,6 @@
network_create_args: {}
network_update_args:
admin_state_up: False
name: "_updated"
runner:
type: "constant"
times: {{smoke or 8}}
@ -454,7 +444,6 @@
subnets_per_network: 2
subnet_update_args:
enable_dhcp: False
name: "_subnet_updated"
runner:
type: "constant"
times: {{smoke or 8}}
@ -482,7 +471,6 @@
router_create_args: {}
router_update_args:
admin_state_up: False
name: "_router_updated"
runner:
type: "constant"
times: {{smoke or 4}}
@ -624,7 +612,6 @@
admin_state_up: False
device_id: "dummy_id"
device_owner: "dummy_owner"
name: "_port_updated"
runner:
type: "constant"
times: {{smoke or 10}}

View File

@ -1,859 +0,0 @@
---
{%- set cirros_image_url = "http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img" %}
{%- set keystone_version = keystone_version|default("v2.0") %}
{% if keystone_version == "v2.0" %}
SaharaNodeGroupTemplates.create_and_list_node_group_templates:
-
args:
hadoop_version: "{{sahara_hadoop_version}}"
flavor:
name: "m1.small"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
api_versions:
sahara:
service_type: {{sahara_service_type}}
sla:
failure_rate:
max: 0
SaharaNodeGroupTemplates.create_delete_node_group_templates:
-
args:
hadoop_version: "{{sahara_hadoop_version}}"
flavor:
name: "m1.small"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
api_versions:
sahara:
service_type: {{sahara_service_type}}
sla:
failure_rate:
max: 0
KeystoneBasic.create_and_list_tenants:
-
args: {}
runner:
type: "constant"
times: 1
concurrency: 1
sla:
failure_rate:
max: 0
KeystoneBasic.create_tenant:
-
args: {}
runner:
type: "constant"
times: 1
concurrency: 1
sla:
failure_rate:
max: 0
KeystoneBasic.create_tenant_with_users:
-
args:
users_per_tenant: 10
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
sla:
failure_rate:
max: 0
{% endif %}
KeystoneBasic.create_user:
-
args: {}
runner:
type: "constant"
times: 1
concurrency: 1
sla:
failure_rate:
max: 0
KeystoneBasic.create_delete_user:
-
args: {}
runner:
type: "constant"
times: 1
concurrency: 1
sla:
failure_rate:
max: 0
KeystoneBasic.create_and_list_users:
-
args: {}
runner:
type: "constant"
times: 1
concurrency: 1
sla:
failure_rate:
max: 0
HeatStacks.create_and_list_stack:
-
args:
template_path: "~/.rally/extra/default.yaml.template"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
HeatStacks.create_and_delete_stack:
-
args:
template_path: "~/.rally/extra/default.yaml.template"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
Authenticate.keystone:
-
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
Authenticate.validate_cinder:
-
args:
repetitions: 2
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
Authenticate.validate_glance:
-
args:
repetitions: 2
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
Authenticate.validate_heat:
-
args:
repetitions: 2
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
Authenticate.validate_nova:
-
args:
repetitions: 2
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
Quotas.cinder_update_and_delete:
-
args:
max_quota: 1024
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
Quotas.cinder_update:
-
args:
max_quota: 1024
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
Quotas.nova_update_and_delete:
-
args:
max_quota: 1024
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
Quotas.nova_update:
-
args:
max_quota: 1024
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
VMTasks.boot_runcommand_delete:
-
args:
flavor:
name: "m1.tiny"
image:
name: "TestVM|cirros.*uec"
floating_network: "{{external_net}}"
use_floating_ip: true
command:
script_file: "~/.rally/extra/instance_test.sh"
interpreter: "/bin/sh"
username: "cirros"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
network: {}
sla:
failure_rate:
max: 0
NovaServers.boot_and_delete_server:
-
args:
flavor:
name: "m1.tiny"
image:
name: "TestVM|cirros.*uec"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
-
args:
auto_assign_nic: true
flavor:
name: "m1.tiny"
image:
name: "TestVM|cirros.*uec"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
network:
start_cidr: "10.2.0.0/24"
networks_per_tenant: 2
sla:
failure_rate:
max: 0
NovaServers.boot_and_list_server:
-
args:
flavor:
name: "m1.tiny"
image:
name: "TestVM|cirros.*uec"
detailed: True
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
NovaServers.list_servers:
-
args:
detailed: True
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
servers:
flavor:
name: "m1.tiny"
image:
name: "TestVM|cirros.*uec"
servers_per_tenant: 1
sla:
failure_rate:
max: 0
NovaServers.boot_and_bounce_server:
-
args:
flavor:
name: "m1.tiny"
image:
name: "TestVM|cirros.*uec"
actions:
-
hard_reboot: 1
-
stop_start: 1
-
rescue_unrescue: 1
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
NovaServers.boot_server:
-
args:
flavor:
name: "^ram64$"
image:
name: "TestVM|cirros.*uec"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
flavors:
-
name: "ram64"
ram: 64
sla:
failure_rate:
max: 0
-
args:
flavor:
name: "m1.tiny"
image:
name: "TestVM|cirros.*uec"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_list_networks:
-
args:
network_create_args:
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_list_subnets:
-
args:
network_create_args:
subnet_create_args:
subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2
runner:
type: "constant"
times: 1
concurrency: 1
context:
network: {}
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
subnet: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_list_routers:
-
args:
network_create_args:
subnet_create_args:
subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2
router_create_args:
runner:
type: "constant"
times: 1
concurrency: 1
context:
network: {}
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
subnet: -1
router: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_list_ports:
-
args:
network_create_args:
port_create_args:
ports_per_network: 4
runner:
type: "constant"
times: 1
concurrency: 1
context:
network: {}
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
subnet: -1
router: -1
port: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_update_networks:
-
args:
network_create_args: {}
network_update_args:
admin_state_up: False
name: "_updated"
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_update_subnets:
-
args:
network_create_args: {}
subnet_create_args: {}
subnet_cidr_start: "1.4.0.0/16"
subnets_per_network: 2
subnet_update_args:
enable_dhcp: False
name: "_subnet_updated"
runner:
type: "constant"
times: 1
concurrency: 1
context:
network: {}
users:
tenants: 5
users_per_tenant: 5
quotas:
neutron:
network: -1
subnet: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_update_routers:
-
args:
network_create_args: {}
subnet_create_args: {}
subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2
router_create_args: {}
router_update_args:
admin_state_up: False
name: "_router_updated"
runner:
type: "constant"
times: 1
concurrency: 1
context:
network: {}
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
subnet: -1
router: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_update_ports:
-
args:
network_create_args: {}
port_create_args: {}
ports_per_network: 5
port_update_args:
admin_state_up: False
device_id: "dummy_id"
device_owner: "dummy_owner"
name: "_port_updated"
runner:
type: "constant"
times: 1
concurrency: 1
context:
network: {}
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
port: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_delete_networks:
-
args:
network_create_args: {}
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
subnet: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_delete_subnets:
-
args:
network_create_args: {}
subnet_create_args: {}
subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2
runner:
type: "constant"
times: 1
concurrency: 1
context:
network: {}
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
subnet: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_delete_ports:
-
args:
network_create_args: {}
port_create_args: {}
ports_per_network: 10
runner:
type: "constant"
times: 1
concurrency: 1
context:
network: {}
users:
tenants: 1
users_per_tenant: 1
quotas:
neutron:
network: -1
port: -1
sla:
failure_rate:
max: 0
CinderVolumes.create_and_upload_volume_to_image:
-
args:
size: 1
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
CinderVolumes.create_volume_backup:
-
args:
size: 1
do_delete: True
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
CinderVolumes.create_and_restore_volume_backup:
-
args:
size: 1
do_delete: True
runner:
type: "constant"
times: 1
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
CinderVolumes.create_and_list_volume_backups:
-
args:
size: 1
detailed: True
do_delete: True
runner:
type: "constant"
times: 2
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0
VMTasks.runcommand_heat:
-
args:
workload:
resource: ["rally.plugins.workload", "siege.py"]
username: "fedora"
template: /home/rally/.rally/extra/workload/wordpress_heat_template.yaml
files:
wp-instances.yaml: /home/rally/.rally/extra/workload/wp-instances.yaml
parameters:
wp_instances_count: 2
wp_instance_type: gig
instance_type: gig
wp_image: fedora
image: fedora
network_id: {{external_net_id}}
context:
users:
tenants: 1
users_per_tenant: 1
flavors:
- name: gig
ram: 1024
disk: 4
vcpus: 1
runner:
concurrency: 1
timeout: 3000
times: 1
type: constant
sla:
failure_rate:
max: 100
GlanceImages.create_and_update_image:
-
args:
image_location: "{{ cirros_image_url }}"
container_format: "bare"
disk_format: "qcow2"
runner:
type: "constant"
times: 4
concurrency: 2
context:
users:
tenants: 2
users_per_tenant: 2
api_versions:
glance:
version: 1
sla:
failure_rate:
max: 100

View File

@ -89,7 +89,7 @@ def configure(name, default_version=None, default_service_type=None,
variable is not specified, validation will assume that your client
doesn't allow to specify service type.
:param supported_versions: List of supported versions(If this variable is
not specified, `OSClients.validate_version` method will raise an
not specified, `OSClient.validate_version` method will raise an
exception that client doesn't support setting any versions. If this
logic is wrong for your client, you should override `validate_version`
in client object)

View File

@ -20,6 +20,7 @@ from rally import exceptions
from rally.task import atomic
from rally.task import service
from rally_openstack.common import consts
from rally_openstack.common.services.network import net_utils
@ -271,17 +272,27 @@ class NeutronService(service.Service):
resp = self.client.show_network(network_id, **body)
return resp["network"]
def find_network(self, network_id_or_name):
def find_network(self, network_id_or_name, external=_NONE):
"""Find network by identifier (id or name)
:param network_id_or_name: Network ID or name
:param external: check target network is external or not
"""
network = None
for net in self.list_networks():
if network_id_or_name in (net["name"], net["id"]):
return net
raise exceptions.GetResourceFailure(
resource="network",
err=f"no name or id matches {network_id_or_name}")
network = net
break
if network is None:
raise exceptions.GetResourceFailure(
resource="network",
err=f"no name or id matches {network_id_or_name}")
if external:
if not network.get("router:external", False):
raise exceptions.NotFoundException(
f"Network '{network['name']} (id={network['id']})' is not "
f"external.")
return network
@atomic.action_timer("neutron.update_network")
@_create_network_arg_adapter()
@ -579,7 +590,7 @@ class NeutronService(service.Service):
description=_NONE, discover_external_gw=False,
external_gateway_info=_NONE, distributed=_NONE, ha=_NONE,
availability_zone_hints=_NONE, service_type_id=_NONE,
flavor_id=_NONE):
flavor_id=_NONE, enable_snat=_NONE):
"""Create router.
:param project_id: The ID of the project that owns the resource. Only
@ -605,12 +616,21 @@ class NeutronService(service.Service):
:param service_type_id: The ID of the service type associated with
the router.
:param flavor_id: The ID of the flavor associated with the router.
:param enable_snat: Whether to include `enable_snat: True` to
external_gateway_info or not. By default, it is enabled if a user
is admin and "ext-gw-mode" extension presents
"""
if external_gateway_info is _NONE and discover_external_gw:
for external_network in self.list_networks(router_external=True):
external_gateway_info = {"network_id": external_network["id"]}
if self.supports_extension("ext-gw-mode", silent=True):
if enable_snat is _NONE:
permission = self._clients.credential.permission
is_admin = permission == consts.EndpointPermission.ADMIN
if (self.supports_extension("ext-gw-mode", silent=True)
and is_admin):
external_gateway_info["enable_snat"] = True
elif enable_snat:
external_gateway_info["enable_snat"] = True
break
@ -856,7 +876,8 @@ class NeutronService(service.Service):
self.client.delete_port(port["id"])
except neutron_exceptions.PortNotFoundClient:
# port is auto-removed
pass
return False
return True
@atomic.action_timer("neutron.list_ports")
def list_ports(self, network_id=_NONE, device_id=_NONE, device_owner=_NONE,
@ -918,12 +939,7 @@ class NeutronService(service.Service):
if isinstance(floating_network, dict):
net_id = floating_network["id"]
elif floating_network:
network = self.find_network(floating_network)
if not network.get("router:external", False):
raise exceptions.NotFoundException(
f"Network '{network['name']} (id={network['id']})' is not "
f"external.")
net_id = network["id"]
net_id = self.find_network(floating_network, external=True)["id"]
else:
ext_networks = self.list_networks(router_external=True)
if not ext_networks:

View File

@ -61,7 +61,7 @@ class NetworkWrapper(object, metaclass=abc.ABCMeta):
START_IPV6_CIDR = "dead:beaf::/64"
SERVICE_IMPL = None
def __init__(self, clients, owner, config=None, atomics=None):
def __init__(self, clients, owner, config=None):
"""Returns available network wrapper instance.
:param clients: rally.plugins.openstack.osclients.Clients instance
@ -74,6 +74,7 @@ class NetworkWrapper(object, metaclass=abc.ABCMeta):
recognized, 'start_cidr' and 'start_ipv6_cidr'.
:returns: NetworkWrapper subclass instance
"""
self.clients = clients
if hasattr(clients, self.SERVICE_IMPL):
self.client = getattr(clients, self.SERVICE_IMPL)()
else:
@ -123,6 +124,10 @@ class NeutronWrapper(NetworkWrapper):
def neutron(_self):
return self.client
@property
def credential(_self):
return self.clients.credential
self.neutron = neutron.NeutronService(
clients=_SingleClientWrapper(),
name_generator=self.owner.generate_random_name,

View File

@ -27,7 +27,7 @@ from rally_openstack.common import consts
from rally_openstack.common import credential
from rally_openstack.common import osclients
from rally_openstack.common.services.identity import identity
from rally_openstack.common.wrappers import network
from rally_openstack.common.services.network import neutron
from rally_openstack.task import context
@ -35,8 +35,8 @@ LOG = logging.getLogger(__name__)
CONF = cfg.CONF
RESOURCE_MANAGEMENT_WORKERS_DESCR = ("The number of concurrent threads to use "
"for serving users context.")
RESOURCE_MANAGEMENT_WORKERS_DESCR = (
"The number of concurrent threads to use for serving users context.")
PROJECT_DOMAIN_DESCR = "ID of domain in which projects will be created."
USER_DOMAIN_DESCR = "ID of domain in which users will be created."
@ -135,30 +135,6 @@ class UserGenerator(context.OpenStackContext):
for key, value in self.DEFAULT_FOR_NEW_USERS.items():
self.config.setdefault(key, value)
def _remove_default_security_group(self):
"""Delete default security group for tenants."""
clients = osclients.Clients(self.credential)
if consts.Service.NEUTRON not in clients.services().values():
return
use_sg, msg = network.wrap(clients, self).supports_extension(
"security-group")
if not use_sg:
LOG.debug("Security group context is disabled: %s" % msg)
return
for user, tenant_id in self._iterate_per_tenants():
with logging.ExceptionLogger(
LOG, "Unable to delete default security group"):
uclients = osclients.Clients(user["credential"])
security_groups = uclients.neutron()\
.list_security_groups(tenant_id=tenant_id)
default = [sg for sg in security_groups["security_groups"]
if sg["name"] == "default"]
if default:
clients.neutron().delete_security_group(default[0]["id"])
def _create_tenants(self, threads):
tenants = collections.deque()
@ -237,36 +213,6 @@ class UserGenerator(context.OpenStackContext):
broker.run(publish, consume, threads)
return list(users)
def _get_consumer_for_deletion(self, func_name):
def consume(cache, resource_id):
if "client" not in cache:
clients = osclients.Clients(self.credential)
cache["client"] = identity.Identity(clients)
getattr(cache["client"], func_name)(resource_id)
return consume
def _delete_tenants(self):
threads = self.config["resource_management_workers"]
def publish(queue):
for tenant_id in self.context["tenants"]:
queue.append(tenant_id)
broker.run(publish, self._get_consumer_for_deletion("delete_project"),
threads)
self.context["tenants"] = {}
def _delete_users(self):
threads = self.config["resource_management_workers"]
def publish(queue):
for user in self.context["users"]:
queue.append(user["id"])
broker.run(publish, self._get_consumer_for_deletion("delete_user"),
threads)
self.context["users"] = []
def create_users(self):
"""Create tenants and users, using the broker pattern."""
@ -331,6 +277,54 @@ class UserGenerator(context.OpenStackContext):
else:
self.create_users()
def _remove_default_security_group(self):
"""Delete default security group for tenants."""
admin_client = neutron.NeutronService(
clients=osclients.Clients(self.credential),
atomic_inst=self.atomic_actions()
)
if not admin_client.supports_extension("security-group", silent=True):
LOG.debug("Security group context is disabled.")
return
security_groups = admin_client.list_security_groups(name="default")
for security_group in security_groups:
if security_group["tenant_id"] not in self.context["tenants"]:
continue
admin_client.delete_security_group(security_group["id"])
def _get_consumer_for_deletion(self, func_name):
def consume(cache, resource_id):
if "client" not in cache:
clients = osclients.Clients(self.credential)
cache["client"] = identity.Identity(clients)
getattr(cache["client"], func_name)(resource_id)
return consume
def _delete_tenants(self):
threads = self.config["resource_management_workers"]
def publish(queue):
for tenant_id in self.context["tenants"]:
queue.append(tenant_id)
broker.run(publish, self._get_consumer_for_deletion("delete_project"),
threads)
self.context["tenants"] = {}
def _delete_users(self):
threads = self.config["resource_management_workers"]
def publish(queue):
for user in self.context["users"]:
queue.append(user["id"])
broker.run(publish, self._get_consumer_for_deletion("delete_user"),
threads)
self.context["users"] = []
def cleanup(self):
"""Delete tenants and users, using the broker pattern."""
if self.existing_users:

View File

@ -16,8 +16,8 @@
from rally.common import logging
from rally.common import validation
from rally_openstack.common import osclients
from rally_openstack.common.wrappers import network
from rally_openstack.common.services.network import neutron
from rally_openstack.task.cleanup import manager as resource_manager
from rally_openstack.task import context
@ -50,68 +50,33 @@ def _rule_to_key(rule):
"port_range_max",
"port_range_min",
"protocol",
"remote_ip_prefix",
"security_group_id"
"remote_ip_prefix"
]
return "_".join([_normalize_rule_value(x, rule.get(x))
for x in comparison_keys])
def _prepare_open_secgroup(credential, secgroup_name):
"""Generate secgroup allowing all tcp/udp/icmp access.
In order to run tests on instances it is necessary to have SSH access.
This function generates a secgroup which allows all tcp/udp/icmp access.
:param credential: clients credential
:param secgroup_name: security group name
:returns: dict with security group details
"""
neutron = osclients.Clients(credential).neutron()
security_groups = neutron.list_security_groups()["security_groups"]
rally_open = [sg for sg in security_groups if sg["name"] == secgroup_name]
if not rally_open:
descr = "Allow ssh access to VMs created by Rally"
rally_open = neutron.create_security_group(
{"security_group": {"name": secgroup_name,
"description": descr}})["security_group"]
else:
rally_open = rally_open[0]
rules_to_add = [
{
"protocol": "tcp",
"port_range_max": 65535,
"port_range_min": 1,
"remote_ip_prefix": "0.0.0.0/0",
"direction": "ingress",
"security_group_id": rally_open["id"]
},
{
"protocol": "udp",
"port_range_max": 65535,
"port_range_min": 1,
"remote_ip_prefix": "0.0.0.0/0",
"direction": "ingress",
"security_group_id": rally_open["id"]
},
{
"protocol": "icmp",
"remote_ip_prefix": "0.0.0.0/0",
"direction": "ingress",
"security_group_id": rally_open["id"]
}
]
existing_rules = set(
_rule_to_key(r) for r in rally_open.get("security_group_rules", []))
for new_rule in rules_to_add:
if _rule_to_key(new_rule) not in existing_rules:
neutron.create_security_group_rule(
{"security_group_rule": new_rule})
return rally_open
_RULES_TO_ADD = [
{
"protocol": "tcp",
"port_range_max": 65535,
"port_range_min": 1,
"remote_ip_prefix": "0.0.0.0/0",
"direction": "ingress"
},
{
"protocol": "udp",
"port_range_max": 65535,
"port_range_min": 1,
"remote_ip_prefix": "0.0.0.0/0",
"direction": "ingress"
},
{
"protocol": "icmp",
"remote_ip_prefix": "0.0.0.0/0",
"direction": "ingress"
}
]
@validation.add("required_platform", platform="openstack", users=True)
@ -120,27 +85,48 @@ class AllowSSH(context.OpenStackContext):
"""Sets up security groups for all users to access VM via SSH."""
def setup(self):
admin_or_user = (self.context.get("admin")
or self.context.get("users")[0])
client = neutron.NeutronService(
clients=self.context["users"][0]["credential"].clients(),
name_generator=self.generate_random_name,
atomic_inst=self.atomic_actions()
)
net_wrapper = network.wrap(
osclients.Clients(admin_or_user["credential"]),
self, config=self.config)
use_sg, msg = net_wrapper.supports_extension("security-group")
if not use_sg:
LOG.info("Security group context is disabled: %s" % msg)
if not client.supports_extension("security-group", silent=True):
LOG.info("Security group context is disabled.")
return
secgroup_name = self.generate_random_name()
secgroups_per_tenant = {}
for user, tenant_id in self._iterate_per_tenants():
client = neutron.NeutronService(
clients=user["credential"].clients(),
name_generator=self.generate_random_name,
atomic_inst=self.atomic_actions()
)
secgroup = client.create_security_group(
name=secgroup_name,
description="Allow ssh access to VMs created by Rally")
secgroups_per_tenant[tenant_id] = secgroup
existing_rules = set(
_rule_to_key(rule)
for rule in secgroup.get("security_group_rules", []))
for new_rule in _RULES_TO_ADD:
if _rule_to_key(new_rule) not in existing_rules:
secgroup.setdefault("security_group_rules", [])
secgroup["security_group_rules"].append(
client.create_security_group_rule(
security_group_id=secgroup["id"], **new_rule)
)
for user in self.context["users"]:
user["secgroup"] = _prepare_open_secgroup(user["credential"],
secgroup_name)
user["secgroup"] = secgroups_per_tenant[user["tenant_id"]]
def cleanup(self):
for user, tenant_id in self._iterate_per_tenants():
with logging.ExceptionLogger(
LOG,
"Unable to delete security group: %s."
% user["secgroup"]["name"]):
clients = osclients.Clients(user["credential"])
clients.neutron().delete_security_group(user["secgroup"]["id"])
resource_manager.cleanup(
names=["neutron.security_group"],
admin=self.context.get("admin"),
users=self.context["users"],
task_id=self.get_owner_id(),
superclass=self.__class__
)

View File

@ -17,17 +17,15 @@ from rally.common import logging
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.common.services.network import neutron
from rally_openstack.task.cleanup import manager as resource_manager
from rally_openstack.task import context
LOG = logging.getLogger(__name__)
# NOTE(andreykurilin): admin is used only by cleanup
@validation.add("required_platform", platform="openstack", admin=True,
users=True)
@validation.add("required_platform", platform="openstack", users=True)
@context.configure(name="network", platform="openstack", order=350)
class Network(context.OpenStackContext):
"""Create networking resources.
@ -67,7 +65,13 @@ class Network(context.OpenStackContext):
"type": "object",
"properties": {
"external": {
"type": "boolean"
"type": "boolean",
"description": "Create a new external router."
},
"enable_snat": {
"type": "boolean",
"description": "Whether to enable SNAT for a router "
"if there is following extension or not"
},
"external_gateway_info": {
"description": "The external gateway information .",
@ -90,7 +94,6 @@ class Network(context.OpenStackContext):
"networks_per_tenant": 1,
"subnets_per_network": 1,
"network_create_args": {},
"dns_nameservers": None,
"router": {"external": True},
"dualstack": False
}
@ -100,27 +103,47 @@ class Network(context.OpenStackContext):
# multithreading/multiprocessing, it is likely the
# sockets are left open. This problem is eliminated by
# creating a connection in setup and cleanup separately.
net_wrapper = network_wrapper.wrap(
osclients.Clients(self.context["admin"]["credential"]),
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"] = []
client = neutron.NeutronService(
user["credential"].clients(),
name_generator=self.generate_random_name,
atomic_inst=self.atomic_actions()
)
network_create_args = self.config["network_create_args"].copy()
subnet_create_args = {
"start_cidr": (self.config["start_cidr"]
if not self.config["dualstack"] else None)}
if "dns_nameservers" in self.config:
dns_nameservers = self.config["dns_nameservers"]
subnet_create_args["dns_nameservers"] = dns_nameservers
router_create_args = dict(self.config["router"] or {})
if not router_create_args:
# old behaviour - empty dict means no router create
router_create_args = None
elif "external" in router_create_args:
external = router_create_args.pop("external")
router_create_args["discover_external_gw"] = external
for i in range(self.config["networks_per_tenant"]):
network_create_args = self.config["network_create_args"].copy()
net_infra = net_wrapper._create_network_infrastructure(
tenant_id,
dualstack=self.config["dualstack"],
subnets_num=self.config["subnets_per_network"],
net_infra = client.create_network_topology(
network_create_args=network_create_args,
router_create_args=self.config["router"],
**kwargs)
subnet_create_args=subnet_create_args,
subnets_dualstack=self.config["dualstack"],
subnets_count=self.config["subnets_per_network"],
router_create_args=router_create_args)
if net_infra["routers"]:
router_id = net_infra["routers"][0]["id"]
else:
router_id = None
net_infra["network"]["router_id"] = router_id
self.context["tenants"][tenant_id]["networks"].append(
net_infra["network"]
)
@ -129,12 +152,13 @@ class Network(context.OpenStackContext):
)
def cleanup(self):
net_wrapper = network_wrapper.wrap(
osclients.Clients(self.context["admin"]["credential"]),
self, config=self.config)
for tenant_id, tenant_ctx in self.context["tenants"].items():
for network in tenant_ctx.get("networks", []):
with logging.ExceptionLogger(
LOG,
"Failed to delete network for tenant %s" % tenant_id):
net_wrapper.delete_network(network)
resource_manager.cleanup(
names=[
"neutron.subnet", "neutron.network", "neutron.router",
"neutron.port"
],
admin=self.context.get("admin"),
users=self.context.get("users", []),
task_id=self.get_owner_id(),
superclass=self.__class__
)

View File

@ -28,13 +28,16 @@ LOG = logging.getLogger(__name__)
"""Scenarios for Neutron."""
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("required_services",
services=[consts.Service.NEUTRON])
@validation.add("required_platform", platform="openstack", users=True)
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_list_networks",
platform="openstack")
class CreateAndListNetworks(utils.NeutronScenario):
class CreateAndListNetworks(utils.NeutronBaseScenario):
def run(self, network_create_args=None):
"""Create a network and then list all networks.
@ -49,17 +52,20 @@ class CreateAndListNetworks(utils.NeutronScenario):
:param network_create_args: dict, POST /v2.0/networks request options
"""
self._create_network(network_create_args or {})
self._list_networks()
self.neutron.create_network(**(network_create_args or {}))
self.neutron.list_networks()
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("required_services",
services=[consts.Service.NEUTRON])
@validation.add("required_platform", platform="openstack", users=True)
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_show_network",
platform="openstack")
class CreateAndShowNetwork(utils.NeutronScenario):
class CreateAndShowNetwork(utils.NeutronBaseScenario):
def run(self, network_create_args=None):
"""Create a network and show network details.
@ -68,17 +74,23 @@ class CreateAndShowNetwork(utils.NeutronScenario):
:param network_create_args: dict, POST /v2.0/networks request options
"""
network = self._create_network(network_create_args or {})
self._show_network(network)
network = self.neutron.create_network(**(network_create_args or {}))
self.neutron.get_network(network["id"])
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="network_update_args")
@validation.add("required_services",
services=[consts.Service.NEUTRON])
@validation.add("required_platform", platform="openstack", users=True)
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_update_networks",
platform="openstack")
class CreateAndUpdateNetworks(utils.NeutronScenario):
class CreateAndUpdateNetworks(utils.NeutronBaseScenario):
def run(self, network_update_args, network_create_args=None):
"""Create and update a network.
@ -88,16 +100,19 @@ class CreateAndUpdateNetworks(utils.NeutronScenario):
:param network_update_args: dict, PUT /v2.0/networks update request
:param network_create_args: dict, POST /v2.0/networks request options
"""
network = self._create_network(network_create_args or {})
self._update_network(network, network_update_args)
network = self.neutron.create_network(**(network_create_args or {}))
self.neutron.update_network(network["id"], **network_update_args)
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("required_services",
services=[consts.Service.NEUTRON])
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_delete_networks",
platform="openstack")
class CreateAndDeleteNetworks(utils.NeutronScenario):
class CreateAndDeleteNetworks(utils.NeutronBaseScenario):
def run(self, network_create_args=None):
"""Create and delete a network.
@ -106,10 +121,16 @@ class CreateAndDeleteNetworks(utils.NeutronScenario):
:param network_create_args: dict, POST /v2.0/networks request options
"""
network = self._create_network(network_create_args or {})
self._delete_network(network["network"])
network = self.neutron.create_network(**(network_create_args or {}))
self.neutron.delete_network(network["id"])
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="subnet_create_args")
@validation.add("number", param_name="subnets_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -118,7 +139,7 @@ class CreateAndDeleteNetworks(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_list_subnets",
platform="openstack")
class CreateAndListSubnets(utils.NeutronScenario):
class CreateAndListSubnets(utils.NeutronBaseScenario):
def run(self, network_create_args=None, subnet_create_args=None,
subnet_cidr_start=None, subnets_per_network=1):
@ -133,12 +154,23 @@ class CreateAndListSubnets(utils.NeutronScenario):
:param subnet_cidr_start: str, start value for subnets CIDR
:param subnets_per_network: int, number of subnets for one network
"""
network = self._create_network(network_create_args or {})
self._create_subnets(network, subnet_create_args, subnet_cidr_start,
subnets_per_network)
self._list_subnets()
network = self.neutron.create_network(**(network_create_args or {}))
for _ in range(subnets_per_network):
self.neutron.create_subnet(network["id"],
start_cidr=subnet_cidr_start,
**(subnet_create_args or {}))
self.neutron.list_subnets()
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="subnet_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="subnet_update_args")
@validation.add("number", param_name="subnets_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -147,7 +179,7 @@ class CreateAndListSubnets(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_update_subnets",
platform="openstack")
class CreateAndUpdateSubnets(utils.NeutronScenario):
class CreateAndUpdateSubnets(utils.NeutronBaseScenario):
def run(self, subnet_update_args, network_create_args=None,
subnet_create_args=None, subnet_cidr_start=None,
@ -165,14 +197,24 @@ class CreateAndUpdateSubnets(utils.NeutronScenario):
:param subnet_cidr_start: str, start value for subnets CIDR
:param subnets_per_network: int, number of subnets for one network
"""
network = self._create_network(network_create_args or {})
subnets = self._create_subnets(network, subnet_create_args,
subnet_cidr_start, subnets_per_network)
network = self.neutron.create_network(**(network_create_args or {}))
subnets = []
for _ in range(subnets_per_network):
subnets.append(
self.neutron.create_subnet(
network["id"], start_cidr=subnet_cidr_start,
**(subnet_create_args or {}))
)
for subnet in subnets:
self._update_subnet(subnet, subnet_update_args)
self.neutron.update_subnet(subnet["id"], **subnet_update_args)
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="subnet_create_args")
@validation.add("number", param_name="subnets_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -181,7 +223,7 @@ class CreateAndUpdateSubnets(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_show_subnets",
platform="openstack")
class CreateAndShowSubnets(utils.NeutronScenario):
class CreateAndShowSubnets(utils.NeutronBaseScenario):
def run(self, network_create_args=None,
subnet_create_args=None, subnet_cidr_start=None,
@ -198,14 +240,24 @@ class CreateAndShowSubnets(utils.NeutronScenario):
:param subnet_cidr_start: str, start value for subnets CIDR
:param subnets_per_network: int, number of subnets for one network
"""
network = self._get_or_create_network(network_create_args)
subnets = self._create_subnets(network, subnet_create_args,
subnet_cidr_start, subnets_per_network)
network = self._get_or_create_network(**(network_create_args or {}))
subnets = []
for _ in range(subnets_per_network):
subnets.append(
self.neutron.create_subnet(
network["id"], start_cidr=subnet_cidr_start,
**(subnet_create_args or {}))
)
for subnet in subnets:
self._show_subnet(subnet)
self.neutron.get_subnet(subnet["id"])
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="subnet_create_args")
@validation.add("number", param_name="subnets_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -213,7 +265,7 @@ class CreateAndShowSubnets(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_delete_subnets",
platform="openstack")
class CreateAndDeleteSubnets(utils.NeutronScenario):
class CreateAndDeleteSubnets(utils.NeutronBaseScenario):
def run(self, network_create_args=None, subnet_create_args=None,
subnet_cidr_start=None, subnets_per_network=1):
@ -228,14 +280,27 @@ class CreateAndDeleteSubnets(utils.NeutronScenario):
:param subnet_cidr_start: str, start value for subnets CIDR
:param subnets_per_network: int, number of subnets for one network
"""
network = self._get_or_create_network(network_create_args)
subnets = self._create_subnets(network, subnet_create_args,
subnet_cidr_start, subnets_per_network)
network = self._get_or_create_network(**(network_create_args or {}))
subnets = []
for _ in range(subnets_per_network):
subnets.append(
self.neutron.create_subnet(
network["id"], start_cidr=subnet_cidr_start,
**(subnet_create_args or {}))
)
for subnet in subnets:
self._delete_subnet(subnet)
self.neutron.delete_subnet(subnet["id"])
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="subnet_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="router_create_args")
@validation.add("number", param_name="subnets_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -244,7 +309,7 @@ class CreateAndDeleteSubnets(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_list_routers",
platform="openstack")
class CreateAndListRouters(utils.NeutronScenario):
class CreateAndListRouters(utils.NeutronBaseScenario):
def run(self, network_create_args=None, subnet_create_args=None,
subnet_cidr_start=None, subnets_per_network=1,
@ -261,12 +326,28 @@ class CreateAndListRouters(utils.NeutronScenario):
:param subnets_per_network: int, number of subnets for one network
:param router_create_args: dict, POST /v2.0/routers request options
"""
self._create_network_structure(network_create_args, subnet_create_args,
subnet_cidr_start, subnets_per_network,
router_create_args)
self._list_routers()
subnet_create_args = dict(subnet_create_args or {})
subnet_create_args["start_cidr"] = subnet_cidr_start
self.neutron.create_network_topology(
network_create_args=(network_create_args or {}),
router_create_args=(router_create_args or {}),
router_per_subnet=True,
subnet_create_args=subnet_create_args,
subnets_count=subnets_per_network
)
self.neutron.list_routers()
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="subnet_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="router_create_args")
@validation.add("number", param_name="subnets_per_network", minval=1,
integer_only=True)
@validation.add("required_services", services=[consts.Service.NEUTRON])
@ -274,7 +355,7 @@ class CreateAndListRouters(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_show_routers",
platform="openstack")
class CreateAndShowRouters(utils.NeutronScenario):
class CreateAndShowRouters(utils.NeutronBaseScenario):
def run(self, network_create_args=None, subnet_create_args=None,
subnet_cidr_start=None, subnets_per_network=1,
@ -291,14 +372,33 @@ class CreateAndShowRouters(utils.NeutronScenario):
:param subnets_per_network: int, number of subnets for each network
:param router_create_args: dict, POST /v2.0/routers request options
"""
network, subnets, routers = self._create_network_structure(
network_create_args, subnet_create_args, subnet_cidr_start,
subnets_per_network, router_create_args)
subnet_create_args = dict(subnet_create_args or {})
subnet_create_args["start_cidr"] = subnet_cidr_start
for router in routers:
self._show_router(router)
net_topo = self.neutron.create_network_topology(
network_create_args=(network_create_args or {}),
router_create_args=(router_create_args or {}),
router_per_subnet=True,
subnet_create_args=subnet_create_args,
subnets_count=subnets_per_network
)
for router in net_topo["routers"]:
self.neutron.get_router(router["id"])
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="subnet_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="router_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="router_update_args")
@validation.add("number", param_name="subnets_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -306,7 +406,7 @@ class CreateAndShowRouters(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_update_routers",
platform="openstack")
class CreateAndUpdateRouters(utils.NeutronScenario):
class CreateAndUpdateRouters(utils.NeutronBaseScenario):
def run(self, router_update_args, network_create_args=None,
subnet_create_args=None, subnet_cidr_start=None,
@ -324,14 +424,30 @@ class CreateAndUpdateRouters(utils.NeutronScenario):
:param subnets_per_network: int, number of subnets for one network
:param router_create_args: dict, POST /v2.0/routers request options
"""
network, subnets, routers = self._create_network_structure(
network_create_args, subnet_create_args, subnet_cidr_start,
subnets_per_network, router_create_args)
subnet_create_args = dict(subnet_create_args or {})
subnet_create_args["start_cidr"] = subnet_cidr_start
for router in routers:
self._update_router(router, router_update_args)
net_topo = self.neutron.create_network_topology(
network_create_args=(network_create_args or {}),
router_create_args=(router_create_args or {}),
router_per_subnet=True,
subnet_create_args=subnet_create_args,
subnets_count=subnets_per_network
)
for router in net_topo["routers"]:
self.neutron.update_router(router["id"], **router_update_args)
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="subnet_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="router_create_args")
@validation.add("number", param_name="subnets_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -339,7 +455,7 @@ class CreateAndUpdateRouters(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_delete_routers",
platform="openstack")
class CreateAndDeleteRouters(utils.NeutronScenario):
class CreateAndDeleteRouters(utils.NeutronBaseScenario):
def run(self, network_create_args=None, subnet_create_args=None,
subnet_cidr_start=None, subnets_per_network=1,
@ -356,24 +472,38 @@ class CreateAndDeleteRouters(utils.NeutronScenario):
:param subnets_per_network: int, number of subnets for one network
:param router_create_args: dict, POST /v2.0/routers request options
"""
network, subnets, routers = self._create_network_structure(
network_create_args, subnet_create_args, subnet_cidr_start,
subnets_per_network, router_create_args)
subnet_create_args = dict(subnet_create_args or {})
subnet_create_args["start_cidr"] = subnet_cidr_start
net_topo = self.neutron.create_network_topology(
network_create_args=(network_create_args or {}),
router_create_args=(router_create_args or {}),
router_per_subnet=True,
subnet_create_args=subnet_create_args,
subnets_count=subnets_per_network
)
for e in range(subnets_per_network):
router = routers[e]
subnet = subnets[e]
self._remove_interface_router(subnet["subnet"], router["router"])
self._delete_router(router)
router = net_topo["routers"][e]
subnet = net_topo["subnets"][e]
self.neutron.remove_interface_from_router(subnet_id=subnet["id"],
router_id=router["id"])
self.neutron.delete_router(router["id"])
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="router_create_args")
@validation.add("required_services",
services=[consts.Service.NEUTRON])
@validation.add("required_platform", platform="openstack", users=True)
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.set_and_clear_router_gateway",
platform="openstack")
class SetAndClearRouterGateway(utils.NeutronScenario):
class SetAndClearRouterGateway(utils.NeutronBaseScenario):
def run(self, enable_snat=True, network_create_args=None,
router_create_args=None):
@ -390,12 +520,21 @@ class SetAndClearRouterGateway(utils.NeutronScenario):
"""
network_create_args = network_create_args or {}
router_create_args = router_create_args or {}
ext_net = self._create_network(network_create_args)
router = self._create_router(router_create_args)
self._add_gateway_router(router, ext_net, enable_snat)
self._remove_gateway_router(router)
ext_net = self.neutron.create_network(**network_create_args)
router = self.neutron.create_router(**router_create_args)
self.neutron.add_gateway_to_router(router_id=router["id"],
network_id=ext_net["id"],
enable_snat=enable_snat)
self.neutron.remove_gateway_from_router(router["id"])
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="port_create_args")
@validation.add("number", param_name="ports_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -404,7 +543,7 @@ class SetAndClearRouterGateway(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_list_ports",
platform="openstack")
class CreateAndListPorts(utils.NeutronScenario):
class CreateAndListPorts(utils.NeutronBaseScenario):
def run(self, network_create_args=None,
port_create_args=None, ports_per_network=1):
@ -415,13 +554,22 @@ class CreateAndListPorts(utils.NeutronScenario):
:param port_create_args: dict, POST /v2.0/ports request options
:param ports_per_network: int, number of ports for one network
"""
network = self._get_or_create_network(network_create_args)
network = self._get_or_create_network(**(network_create_args or {}))
for i in range(ports_per_network):
self._create_port(network, port_create_args or {})
self.neutron.create_port(network["id"], **(port_create_args or {}))
self._list_ports()
self.neutron.list_ports()
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="port_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="port_update_args")
@validation.add("number", param_name="ports_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -430,7 +578,7 @@ class CreateAndListPorts(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_update_ports",
platform="openstack")
class CreateAndUpdatePorts(utils.NeutronScenario):
class CreateAndUpdatePorts(utils.NeutronBaseScenario):
def run(self, port_update_args, network_create_args=None,
port_create_args=None, ports_per_network=1):
@ -445,12 +593,19 @@ class CreateAndUpdatePorts(utils.NeutronScenario):
:param port_create_args: dict, POST /v2.0/ports request options
:param ports_per_network: int, number of ports for one network
"""
network = self._get_or_create_network(network_create_args)
network = self._get_or_create_network(**(network_create_args or {}))
for i in range(ports_per_network):
port = self._create_port(network, port_create_args)
self._update_port(port, port_update_args)
port = self.neutron.create_port(
network["id"], **(port_create_args or {}))
self.neutron.update_port(port["id"], **port_update_args)
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="port_create_args")
@validation.add("number", param_name="ports_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -459,7 +614,7 @@ class CreateAndUpdatePorts(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_show_ports",
platform="openstack")
class CreateAndShowPorts(utils.NeutronScenario):
class CreateAndShowPorts(utils.NeutronBaseScenario):
def run(self, network_create_args=None,
port_create_args=None, ports_per_network=1):
@ -473,21 +628,20 @@ class CreateAndShowPorts(utils.NeutronScenario):
:param port_create_args: dict, POST /v2.0/ports request options
:param ports_per_network: int, number of ports for one network
"""
network_create_args = network_create_args or {}
port_create_args = port_create_args or {}
network = self._get_or_create_network(network_create_args)
network = self._get_or_create_network(**(network_create_args or {}))
for i in range(ports_per_network):
port = self._create_port(network, port_create_args)
msg = "Port isn't created"
self.assertTrue(port, err_msg=msg)
port = self.neutron.create_port(
network["id"], **(port_create_args or {}))
port_info = self._show_port(port)
msg = "Created port and Showed port isn't equal"
self.assertEqual(port["port"]["id"], port_info["port"]["id"],
err_msg=msg)
self.neutron.get_port(port["id"])
@validation.add("restricted_parameters",
param_names="name",
subdict="network_create_args")
@validation.add("restricted_parameters",
param_names="name",
subdict="port_create_args")
@validation.add("number", param_name="ports_per_network", minval=1,
integer_only=True)
@validation.add("required_services",
@ -495,7 +649,7 @@ class CreateAndShowPorts(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_delete_ports",
platform="openstack")
class CreateAndDeletePorts(utils.NeutronScenario):
class CreateAndDeletePorts(utils.NeutronBaseScenario):
def run(self, network_create_args=None,
port_create_args=None, ports_per_network=1):
@ -509,10 +663,12 @@ class CreateAndDeletePorts(utils.NeutronScenario):
:param port_create_args: dict, POST /v2.0/ports request options
:param ports_per_network: int, number of ports for one network
"""
network = self._get_or_create_network(network_create_args)
network = self._get_or_create_network(**(network_create_args or {}))
for i in range(ports_per_network):
port = self._create_port(network, port_create_args)
self._delete_port(port)
port = self.neutron.create_port(
network["id"], **(port_create_args or {}))
self.neutron.delete_port(port["id"])
@validation.add("number", param_name="ports_per_network", minval=1,
@ -527,7 +683,7 @@ class CreateAndDeletePorts(utils.NeutronScenario):
"network@openstack": {}},
name="NeutronNetworks.create_and_bind_ports",
platform="openstack")
class CreateAndBindPorts(utils.NeutronScenario):
class CreateAndBindPorts(utils.NeutronBaseScenario):
def run(self, ports_per_network=1):
"""Bind a given number of ports.
@ -558,29 +714,17 @@ class CreateAndBindPorts(utils.NeutronScenario):
tenant_id = self.context["tenant"]["id"]
for network in self.context["tenants"][tenant_id]["networks"]:
wrapped_network = {"network": network}
self._create_subnet(
wrapped_network,
start_cidr="10.2.0.0/24",
subnet_create_args={},
)
self._create_subnet(
wrapped_network,
start_cidr="2001:db8:1:1::/64",
subnet_create_args={},
)
self.neutron.create_subnet(network_id=network["id"], ip_version=4)
self.neutron.create_subnet(network_id=network["id"], ip_version=6)
for i in range(ports_per_network):
port = self._create_port(wrapped_network, port_create_args={})
port = self.neutron.create_port(network_id=network["id"])
# port bind needs admin role
self._update_port(
port,
port_update_args={
"device_owner": "compute:nova",
"device_id": "ba805478-85ff-11e9-a2e4-2b8dea218fc8",
"binding:host_id": host_to_bind,
},
self.admin_neutron.update_port(
port_id=port["id"],
device_owner="compute:nova",
device_id="ba805478-85ff-11e9-a2e4-2b8dea218fc8",
**{"binding:host_id": host_to_bind},
)
@ -591,7 +735,7 @@ class CreateAndBindPorts(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_list_floating_ips",
platform="openstack")
class CreateAndListFloatingIps(utils.NeutronScenario):
class CreateAndListFloatingIps(utils.NeutronBaseScenario):
def run(self, floating_network=None, floating_ip_args=None):
"""Create and list floating IPs.
@ -603,8 +747,9 @@ class CreateAndListFloatingIps(utils.NeutronScenario):
:param floating_ip_args: dict, POST /floatingips request options
"""
floating_ip_args = floating_ip_args or {}
self._create_floatingip(floating_network, **floating_ip_args)
self._list_floating_ips()
self.neutron.create_floatingip(floating_network=floating_network,
**floating_ip_args)
self.neutron.list_floatingips()
@validation.add("required_services",
@ -614,7 +759,7 @@ class CreateAndListFloatingIps(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.create_and_delete_floating_ips",
platform="openstack")
class CreateAndDeleteFloatingIps(utils.NeutronScenario):
class CreateAndDeleteFloatingIps(utils.NeutronBaseScenario):
def run(self, floating_network=None, floating_ip_args=None):
"""Create and delete floating IPs.
@ -626,9 +771,9 @@ class CreateAndDeleteFloatingIps(utils.NeutronScenario):
:param floating_ip_args: dict, POST /floatingips request options
"""
floating_ip_args = floating_ip_args or {}
floating_ip = self._create_floatingip(floating_network,
**floating_ip_args)
self._delete_floating_ip(floating_ip["floatingip"])
floatingip = self.neutron.create_floatingip(
floating_network=floating_network, **floating_ip_args)
self.neutron.delete_floatingip(floatingip["id"])
@validation.add("required_services",
@ -639,7 +784,7 @@ class CreateAndDeleteFloatingIps(utils.NeutronScenario):
context={"cleanup@openstack": ["neutron"]},
name="NeutronNetworks.associate_and_dissociate_floating_ips",
platform="openstack")
class AssociateAndDissociateFloatingIps(utils.NeutronScenario):
class AssociateAndDissociateFloatingIps(utils.NeutronBaseScenario):
def run(self, floating_network=None):
"""Associate and dissociate floating IPs.
@ -658,40 +803,31 @@ class AssociateAndDissociateFloatingIps(utils.NeutronScenario):
:param floating_network: str, external network for floating IP creation
"""
floating_ip = self._create_floatingip(
floating_network)
floating_network = self.neutron.find_network(floating_network,
external=True)
floating_ip = self.neutron.create_floatingip(
floating_network=floating_network)
private_network = self._create_network(
network_create_args={})
subnet = self._create_subnet(
network=private_network,
subnet_create_args={})
port = self._create_port(
network=private_network,
port_create_args={})
private_network = self.neutron.create_network()
subnet = self.neutron.create_subnet(network_id=private_network["id"])
port = self.neutron.create_port(network_id=private_network["id"])
router = self._create_router(
router_create_args={})
floating_network_id = self._get_network_id(floating_network)
self._add_gateway_router(
router,
{"network": {"id": floating_network_id}})
self._add_interface_router(
subnet["subnet"],
router["router"])
router = self.neutron.create_router()
self.neutron.add_gateway_to_router(
router["id"], network_id=floating_network["id"])
self.neutron.add_interface_to_router(
subnet_id=subnet["id"], router_id=router["id"])
self._associate_floating_ip(
floatingip=floating_ip["floatingip"],
port=port["port"])
self._dissociate_floating_ip(
floatingip=floating_ip["floatingip"])
self.neutron.associate_floatingip(
floatingip_id=floating_ip["id"], port_id=port["id"])
self.neutron.dissociate_floatingip(floatingip_id=floating_ip["id"])
@validation.add("required_services",
services=[consts.Service.NEUTRON])
@validation.add("required_platform", platform="openstack", users=True)
@scenario.configure(name="NeutronNetworks.list_agents", platform="openstack")
class ListAgents(utils.NeutronScenario):
class ListAgents(utils.NeutronBaseScenario):
def run(self, agent_args=None):
"""List all neutron agents.
@ -702,7 +838,7 @@ class ListAgents(utils.NeutronScenario):
:param agent_args: dict, POST /v2.0/agents request options
"""
agent_args = agent_args or {}
self._list_agents(**agent_args)
self.neutron.list_agents(**agent_args)
@validation.add("required_services",
@ -712,7 +848,7 @@ class ListAgents(utils.NeutronScenario):
@scenario.configure(context={"cleanup@openstack": ["neutron"]},
name="NeutronSubnets.delete_subnets",
platform="openstack")
class DeleteSubnets(utils.NeutronScenario):
class DeleteSubnets(utils.NeutronBaseScenario):
def run(self):
"""Delete a subnet that belongs to each precreated network.
@ -733,4 +869,4 @@ class DeleteSubnets(utils.NeutronScenario):
for network in self.context["tenants"][tenant_id]["networks"]:
# delete one of subnets based on the user sequential number
subnet_id = network["subnets"][number]
self._delete_subnet({"subnet": {"id": subnet_id}})
self.neutron.delete_subnet(subnet_id)

View File

@ -42,6 +42,31 @@ class NeutronBaseScenario(scenario.OpenStackScenario):
name_generator=self.generate_random_name,
atomic_inst=self.atomic_actions()
)
if hasattr(self, "_admin_clients"):
self.admin_neutron = neutron.NeutronService(
clients=self._admin_clients,
name_generator=self.generate_random_name,
atomic_inst=self.atomic_actions()
)
def _get_or_create_network(self, **network_create_args):
"""Get a network from context, or create a new one.
This lets users either create networks with the 'network'
context, provide existing networks with the 'existing_network'
context, or let the scenario create a default network for
them.
"""
if "networks" in self.context["tenant"]:
networks = self.context["tenant"]["networks"]
net_idx = self.context["iteration"] % len(networks)
return networks[net_idx]
else:
LOG.warning("Running this scenario without either the "
"'network@openstack' or 'existing_network@openstack' "
"context is deprecated since Rally-OpenStack 2.0.0.")
return self.neutron.create_network(**network_create_args)
class NeutronScenario(NeutronBaseScenario):

View File

@ -20,7 +20,6 @@ from rally.task import types
from rally.task import validation
from rally_openstack.common import consts
from rally_openstack.common.wrappers import network as network_wrapper
from rally_openstack.task import scenario
from rally_openstack.task.scenarios.cinder import utils as cinder_utils
from rally_openstack.task.scenarios.neutron import utils as neutron_utils
@ -37,7 +36,7 @@ LOG = logging.getLogger(__name__)
flavor={"type": "nova_flavor"})
@validation.add("image_valid_on_flavor", flavor_param="flavor",
image_param="image")
@validation.add("required_services", services=(consts.Service.NOVA))
@validation.add("required_services", services=[consts.Service.NOVA])
@validation.add("required_platform", platform="openstack", users=True)
@scenario.configure(context={"cleanup@openstack": ["nova"]},
name="NovaServers.boot_and_list_server",
@ -926,9 +925,8 @@ class BootAndAssociateFloatingIp(utils.NovaScenario):
"""
create_floating_ip_args = create_floating_ip_args or {}
server = self._boot_server(image, flavor, **kwargs)
address = network_wrapper.wrap(self.clients, self).create_floating_ip(
tenant_id=server.tenant_id, **create_floating_ip_args)
self._associate_floating_ip(server, address["ip"])
floatingip = self.neutron.create_floatingip(**create_floating_ip_args)
self._associate_floating_ip(server, floatingip)
@types.convert(image={"type": "glance_image"},
@ -1114,10 +1112,9 @@ class BootServerAssociateAndDissociateFloatingIP(utils.NovaScenario):
create_floating_ip_args = create_floating_ip_args or {}
server = self._boot_server(image, flavor, **kwargs)
address = network_wrapper.wrap(self.clients, self).create_floating_ip(
tenant_id=server.tenant_id, **create_floating_ip_args)
self._associate_floating_ip(server, address["ip"])
self._dissociate_floating_ip(server, address["ip"])
floatingip = self.neutron.create_floatingip(**create_floating_ip_args)
self._associate_floating_ip(server, floatingip)
self._dissociate_floating_ip(server, floatingip)
@types.convert(image={"type": "glance_image"},

View File

@ -26,7 +26,6 @@ from rally.task import atomic
from rally.task import utils
from rally.utils import sshutils
from rally_openstack.common.wrappers import network as network_wrapper
from rally_openstack.task.scenarios.nova import utils as nova_utils
LOG = logging.getLogger(__name__)
@ -161,30 +160,23 @@ class VMScenario(nova_utils.NovaScenario):
"id": fip.get("id"),
"is_floating": use_floating_ip}
@atomic.action_timer("vm.attach_floating_ip")
def _attach_floating_ip(self, server, floating_network):
internal_network = list(server.networks)[0]
fixed_ip = server.addresses[internal_network][0]["addr"]
with atomic.ActionTimer(self, "neutron.create_floating_ip"):
fip = network_wrapper.wrap(self.clients, self).create_floating_ip(
ext_network=floating_network,
tenant_id=server.tenant_id, fixed_ip=fixed_ip)
floatingip = self.neutron.create_floatingip(
floating_network=floating_network)
self._associate_floating_ip(server, floatingip, fixed_address=fixed_ip)
self._associate_floating_ip(server, fip, fixed_address=fixed_ip)
return {"id": floatingip["id"],
"ip": floatingip["floating_ip_address"]}
return fip
@atomic.action_timer("vm.delete_floating_ip")
def _delete_floating_ip(self, server, fip):
with logging.ExceptionLogger(
LOG, "Unable to delete IP: %s" % fip["ip"]):
if self.check_ip_address(fip["ip"])(server):
self._dissociate_floating_ip(server, fip)
with atomic.ActionTimer(self, "neutron.delete_floating_ip"):
network_wrapper.wrap(self.clients,
self).delete_floating_ip(
fip["id"], wait=True)
self.neutron.delete_floatingip(fip["id"])
def _delete_server_with_fip(self, server, fip, force_delete=False):
if fip["is_floating"]:

View File

@ -28,7 +28,7 @@ from rally.verification import utils
from rally_openstack.common import consts
from rally_openstack.common import credential
from rally_openstack.common.services.image import image
from rally_openstack.common.wrappers import network
from rally_openstack.common.services.network import neutron
from rally_openstack.verification.tempest import config as conf
@ -287,25 +287,29 @@ class TempestContext(context.VerifierContext):
return flavor
def _create_network_resources(self):
neutron_wrapper = network.NeutronWrapper(self.clients, self)
client = neutron.NeutronService(
clients=self.clients,
name_generator=self.generate_random_name,
atomic_inst=self.atomic_actions()
)
tenant_id = self.clients.keystone.auth_ref.project_id
router_create_args = {}
router_create_args = {"project_id": tenant_id}
public_net = None
if self.conf.has_section("network"):
public_net = self.conf.get("network", "public_network_id")
if public_net:
ext_gw_mode_enabled = neutron_wrapper.ext_gw_mode_enabled
external_gateway_info = {
"network_id": public_net
}
if ext_gw_mode_enabled:
if client.supports_extension("ext-gw-mode", silent=True):
external_gateway_info["enable_snat"] = True
router_create_args["external_gateway_info"] = external_gateway_info
LOG.debug("Creating network resources: network, subnet, router.")
net = neutron_wrapper.create_network(
tenant_id, subnets_num=1, add_router=True,
net = client.create_network_topology(
subnets_count=1,
router_create_args=router_create_args,
network_create_args={"shared": True})
subnet_create_args={"project_id": tenant_id},
network_create_args={"shared": True, "project_id": tenant_id})
LOG.debug("Network resources have been successfully created!")
self._created_networks.append(net)
@ -343,11 +347,16 @@ class TempestContext(context.VerifierContext):
self._remove_opt_value_from_config("orchestration", flavor.id)
def _cleanup_network_resources(self):
neutron_wrapper = network.NeutronWrapper(self.clients, self)
for net in self._created_networks:
client = neutron.NeutronService(
clients=self.clients,
name_generator=self.generate_random_name,
atomic_inst=self.atomic_actions()
)
for topo in self._created_networks:
LOG.debug("Deleting network resources: router, subnet, network.")
neutron_wrapper.delete_network(net)
self._remove_opt_value_from_config("compute", net["name"])
client.delete_network_topology(topo)
self._remove_opt_value_from_config("compute",
topo["network"]["name"])
LOG.debug("Network resources have been deleted.")
def _remove_opt_value_from_config(self, section, opt_value):

View File

@ -3,10 +3,8 @@
{
"args": {
"network_update_args": {
"admin_state_up": false,
"name": "_updated"
},
"network_create_args": {}
"admin_state_up": false
}
},
"runner": {
"type": "constant",

View File

@ -2,10 +2,8 @@
NeutronNetworks.create_and_update_networks:
-
args:
network_create_args: {}
network_update_args:
admin_state_up: False
name: "_updated"
runner:
type: "constant"
times: 10

View File

@ -2,13 +2,10 @@
"NeutronNetworks.create_and_update_ports": [
{
"args": {
"network_create_args": {},
"port_create_args": {},
"port_update_args": {
"admin_state_up": false,
"device_id": "dummy_id",
"device_owner": "dummy_owner",
"name": "_port_updated"
"device_owner": "dummy_owner"
},
"ports_per_network": 5
},

View File

@ -2,14 +2,11 @@
NeutronNetworks.create_and_update_ports:
-
args:
network_create_args: {}
port_create_args: {}
ports_per_network: 5
port_update_args:
admin_state_up: False
device_id: "dummy_id"
device_owner: "dummy_owner"
name: "_port_updated"
runner:
type: "constant"
times: 10

View File

@ -2,14 +2,10 @@
"NeutronNetworks.create_and_update_routers": [
{
"args": {
"network_create_args": {},
"subnet_create_args": {},
"subnet_cidr_start": "1.1.0.0/30",
"subnets_per_network": 2,
"router_create_args": {},
"router_update_args": {
"admin_state_up": false,
"name": "_router_updated"
"admin_state_up": false
}
},
"runner": {

View File

@ -2,14 +2,10 @@
NeutronNetworks.create_and_update_routers:
-
args:
network_create_args: {}
subnet_create_args: {}
subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2
router_create_args: {}
router_update_args:
admin_state_up: False
name: "_router_updated"
runner:
type: "constant"
times: 10

View File

@ -3,11 +3,8 @@
{
"args": {
"subnet_update_args": {
"enable_dhcp": false,
"name": "_subnet_updated"
"enable_dhcp": false
},
"network_create_args": {},
"subnet_create_args": {},
"subnet_cidr_start": "1.4.0.0/16",
"subnets_per_network": 2
},

View File

@ -2,13 +2,10 @@
NeutronNetworks.create_and_update_subnets:
-
args:
network_create_args: {}
subnet_create_args: {}
subnet_cidr_start: "1.4.0.0/16"
subnets_per_network: 2
subnet_update_args:
enable_dhcp: False
name: "_subnet_updated"
runner:
type: "constant"
times: 10

View File

@ -151,7 +151,6 @@
network_create_args: {}
network_update_args:
admin_state_up: false
name: "_updated"
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
@ -172,7 +171,6 @@
admin_state_up: false
device_id: "dummy_id"
device_owner: "dummy_owner"
name: "_port_updated"
ports_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
@ -193,7 +191,6 @@
router_create_args: {}
router_update_args:
admin_state_up: false
name: "_router_updated"
subnet_cidr_start: "1.1.0.0/30"
subnet_create_args: {}
subnets_per_network: 1
@ -219,7 +216,6 @@
subnet_create_args: {}
subnet_update_args:
enable_dhcp: false
name: "_subnet_updated"
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}

View File

@ -15,7 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
ALLOWED_EXTRA_MISSING=4
ALLOWED_EXTRA_MISSING=10
show_diff () {
head -1 $1

View File

@ -38,9 +38,10 @@ class NeutronWrapperTestCase(test.TestCase):
super(NeutronWrapperTestCase, self).setUp()
self.owner = Owner()
self.owner.generate_random_name = mock.Mock()
self.wrapper = network.NeutronWrapper(mock.MagicMock(),
self.owner,
config={})
clients = mock.MagicMock()
clients.credential.permission = consts.EndpointPermission.ADMIN
self.wrapper = network.NeutronWrapper(
clients, self.owner, config={})
self._nc = self.wrapper.neutron.client
def test_SUBNET_IP_VERSION(self):

View File

@ -263,84 +263,60 @@ class UserGeneratorForNewUsersTestCase(test.ScenarioTestCase):
"task": {"uuid": "task_id", "deployment_uuid": "dep_uuid"}
})
@mock.patch("%s.network.wrap" % CTX)
def test__remove_default_security_group_not_needed(self, mock_wrap):
services = {"compute": consts.Service.NOVA}
self.osclients.Clients().services.return_value = services
user_generator = users.UserGenerator(self.context)
user_generator._remove_default_security_group()
self.assertFalse(mock_wrap.called)
def test__remove_default_security_group(self):
@mock.patch("%s.network.wrap" % CTX)
def test__remove_default_security_group_neutron_no_sg(self, mock_wrap):
net_wrapper = mock.Mock(SERVICE_IMPL=consts.Service.NEUTRON)
net_wrapper.supports_extension.return_value = (False, None)
mock_wrap.return_value = net_wrapper
user_generator = users.UserGenerator(self.context)
admin_clients = mock.Mock()
admin_clients.services.return_value = {
"compute": consts.Service.NOVA,
"neutron": consts.Service.NEUTRON}
user_clients = [mock.Mock(), mock.Mock()]
self.osclients.Clients.side_effect = [admin_clients] + user_clients
user_generator._remove_default_security_group()
mock_wrap.assert_called_once_with(admin_clients, user_generator)
net_wrapper.supports_extension.assert_called_once_with(
"security-group")
@mock.patch("%s.network" % CTX)
def test__remove_default_security_group(self, mock_network):
net_wrapper = mock.Mock(SERVICE_IMPL=consts.Service.NEUTRON)
net_wrapper.supports_extension.return_value = (True, None)
mock_network.wrap.return_value = net_wrapper
user_generator = users.UserGenerator(self.context)
admin_clients = mock.Mock()
admin_clients.services.return_value = {
"compute": consts.Service.NOVA,
"neutron": consts.Service.NEUTRON}
user1 = mock.Mock()
user1.neutron.return_value.list_security_groups.return_value = {
"security_groups": [{"id": "id-1", "name": "default"},
{"id": "id-2", "name": "not-default"}]}
user2 = mock.Mock()
user2.neutron.return_value.list_security_groups.return_value = {
"security_groups": [{"id": "id-3", "name": "default"},
{"id": "id-4", "name": "not-default"}]}
user_clients = [user1, user2]
self.osclients.Clients.side_effect = [admin_clients] + user_clients
user_generator._iterate_per_tenants = mock.MagicMock(
return_value=[
(mock.MagicMock(), "t1"),
(mock.MagicMock(), "t2")
]
self.context.update(
tenants={
"tenant-1": {},
"tenant-2": {}
}
)
user_generator._remove_default_security_group()
self.osclients.Clients.return_value = mock.Mock()
neutron = self.osclients.Clients.return_value.neutron.return_value
neutron.list_extensions.return_value = {
"extensions": [{"alias": "security-group"}]}
mock_network.wrap.assert_called_once_with(admin_clients,
user_generator)
neutron.list_security_groups.return_value = {
"security_groups": [
{"id": "id-1", "name": "default", "tenant_id": "tenant-1"},
{"id": "id-2", "name": "default", "tenant_id": "tenant-2"},
{"id": "id-3", "name": "default", "tenant_id": "tenant-3"}
]
}
user_generator._iterate_per_tenants.assert_called_once_with()
expected = [mock.call(user_generator.credential)] + [
mock.call(u["credential"])
for u, t in user_generator._iterate_per_tenants.return_value]
self.osclients.Clients.assert_has_calls(expected, any_order=True)
users.UserGenerator(self.context)._remove_default_security_group()
user_net = user1.neutron.return_value
user_net.list_security_groups.assert_called_once_with(tenant_id="t1")
user_net = user2.neutron.return_value
user_net.list_security_groups.assert_called_once_with(tenant_id="t2")
admin_neutron = admin_clients.neutron.return_value
neutron.list_security_groups.assert_called_once_with(name="default")
self.assertEqual(
[mock.call("id-1"), mock.call("id-3")],
admin_neutron.delete_security_group.call_args_list)
[mock.call("id-1"), mock.call("id-2")],
neutron.delete_security_group.call_args_list
)
def test__remove_default_security_group_no_sg(self):
self.context.update(
tenants={
"tenant-1": {},
"tenant-2": {}
}
)
self.osclients.Clients.return_value = mock.Mock()
neutron = self.osclients.Clients.return_value.neutron.return_value
neutron.list_extensions.return_value = {"extensions": []}
neutron.list_security_groups.return_value = {
"security_groups": [
{"id": "id-1", "name": "default", "tenant_id": "tenant-1"},
{"id": "id-2", "name": "default", "tenant_id": "tenant-2"},
{"id": "id-3", "name": "default", "tenant_id": "tenant-3"}
]
}
users.UserGenerator(self.context)._remove_default_security_group()
self.assertFalse(neutron.list_security_groups.called)
self.assertFalse(neutron.delete_security_group.called)
@mock.patch("%s.identity" % CTX)
def test__create_tenants(self, mock_identity):

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
from unittest import mock
from rally_openstack.task.contexts.network import allow_ssh
@ -26,87 +27,94 @@ class AllowSSHContextTestCase(test.TestCase):
def setUp(self):
super(AllowSSHContextTestCase, self).setUp()
self.users = 2
self.secgroup_name = "test-secgroup"
self.users_count = 3
self.ctx_with_secgroup = test.get_test_context()
self.ctx_with_secgroup.update({
"users": [
self.ctx = test.get_test_context()
self.ctx.update(
users=[
{
"tenant_id": "uuid1",
"credential": "credential",
"secgroup": {"id": "secgroup_id", "name": "secgroup"}
"tenant_id": f"uuid{i // 3}",
"credential": mock.MagicMock()
}
] * self.users,
"admin": {"tenant_id": "uuid2", "credential": "admin_credential"},
"tenants": {"uuid1": {"id": "uuid1", "name": "uuid1"}},
})
self.ctx_without_secgroup = test.get_test_context()
self.ctx_without_secgroup.update({
"users": [{"tenant_id": "uuid1",
"credential": "credential"},
{"tenant_id": "uuid1",
"credential": "credential"}],
"admin": {"tenant_id": "uuid2", "credential": "admin_credential"},
"tenants": {"uuid1": {"id": "uuid1", "name": "uuid1"}},
})
@mock.patch("%s.osclients.Clients" % CTX)
def test__prepare_open_secgroup_rules(self, mock_clients):
fake_neutron = mock_clients.return_value.neutron.return_value
fake_neutron.list_security_groups.return_value = {
"security_groups": [{"id": "id", "name": "foo",
"security_group_rules": []}]}
allow_ssh._prepare_open_secgroup("credential", self.secgroup_name)
allow_ssh._prepare_open_secgroup("credential", "foo")
@mock.patch("%s.osclients.Clients" % CTX)
@mock.patch("%s._prepare_open_secgroup" % CTX)
@mock.patch("rally_openstack.common.wrappers.network.wrap")
def test_secgroup_setup_cleanup_with_secgroup_supported(
self, mock_network_wrap, mock__prepare_open_secgroup,
mock_clients):
mock_network_wrapper = mock.MagicMock()
mock_network_wrapper.supports_extension.return_value = (True, "")
mock_network_wrap.return_value = mock_network_wrapper
mock__prepare_open_secgroup.return_value = {
"name": "secgroup",
"id": "secgroup_id"}
mock_clients.return_value = mock.MagicMock()
secgrp_ctx = allow_ssh.AllowSSH(self.ctx_with_secgroup)
secgrp_ctx.setup()
self.assertEqual(self.ctx_with_secgroup, secgrp_ctx.context)
secgrp_ctx.cleanup()
self.assertEqual(
[
mock.call("admin_credential"),
mock.call("credential"),
mock.call().neutron(),
mock.call().neutron().delete_security_group("secgroup_id")
for i in range(1, self.users_count + 1)
],
mock_clients.mock_calls)
admin={
"tenant_id": "uuid2",
"credential": mock.MagicMock()},
tenants={
"uuid1": {"id": "uuid1", "name": "uuid1"},
"uuid2": {"id": "uuid2", "name": "uuid1"}
}
)
mock_network_wrap.assert_called_once_with(
mock_clients.return_value, secgrp_ctx, config={})
def test_setup(self):
for i, user in enumerate(self.ctx["users"]):
clients = user["credential"].clients.return_value
nc = clients.neutron.return_value
nc.list_extensions.return_value = {
"extensions": [{"alias": "security-group"}]
}
nc.create_security_group.return_value = {
"security_group": {
"name": "xxx",
"id": f"security-group-{i}",
"security_group_rules": []
}
}
@mock.patch("%s.osclients.Clients" % CTX)
@mock.patch("rally_openstack.common.wrappers.network.wrap")
def test_secgroup_setup_with_secgroup_unsupported(
self, mock_network_wrap, mock_clients):
mock_network_wrapper = mock.MagicMock()
mock_network_wrapper.supports_extension.return_value = (
False, "Not supported")
mock_network_wrap.return_value = mock_network_wrapper
mock_clients.return_value = mock.MagicMock()
allow_ssh.AllowSSH(self.ctx).setup()
secgrp_ctx = allow_ssh.AllowSSH(dict(self.ctx_without_secgroup))
secgrp_ctx.setup()
self.assertEqual(self.ctx_without_secgroup, secgrp_ctx.context)
# admin user should not be used
self.assertFalse(self.ctx["admin"]["credential"].clients.called)
mock_clients.assert_called_once_with("admin_credential")
processed_tenants = {}
for i, user in enumerate(self.ctx["users"]):
clients = user["credential"].clients.return_value
nc = clients.neutron.return_value
if i == 0:
nc.list_extensions.assert_called_once_with()
else:
self.assertFalse(nc.list_extensions.called)
mock_network_wrap.assert_called_once_with(
mock_clients.return_value, secgrp_ctx, config={})
if user["tenant_id"] in processed_tenants:
self.assertFalse(nc.create_security_group.called)
self.assertFalse(nc.create_security_group_rule.called)
else:
nc.create_security_group.assert_called_once_with({
"security_group": {
"name": mock.ANY,
"description": mock.ANY
}
})
secgroup = nc.create_security_group.return_value
secgroup = secgroup["security_group"]
rules = copy.deepcopy(allow_ssh._RULES_TO_ADD)
for rule in rules:
rule["security_group_id"] = secgroup["id"]
self.assertEqual(
[mock.call({"security_group_rule": rule})
for rule in rules],
nc.create_security_group_rule.call_args_list
)
processed_tenants[user["tenant_id"]] = secgroup
self.assertEqual(processed_tenants[user["tenant_id"]]["id"],
user["secgroup"]["id"])
def test_setup_no_security_group_extension(self):
clients = self.ctx["users"][0]["credential"].clients.return_value
nc = clients.neutron.return_value
nc.list_extensions.return_value = {"extensions": []}
allow_ssh.AllowSSH(self.ctx).setup()
# admin user should not be used
self.assertFalse(self.ctx["admin"]["credential"].clients.called)
nc.list_extensions.assert_called_once_with()
for i, user in enumerate(self.ctx["users"]):
if i == 0:
continue
self.assertFalse(user["credential"].clients.called)

View File

@ -21,7 +21,7 @@ import netaddr
from rally_openstack.task.contexts.network import networks as network_context
from tests.unit import test
NET = "rally_openstack.common.wrappers.network."
PATH = "rally_openstack.task.contexts.network.networks"
@ddt.ddt
@ -30,26 +30,23 @@ class NetworkTestCase(test.TestCase):
return {"task": {"uuid": "foo_task"},
"admin": {"credential": "foo_admin"},
"config": {"network": kwargs},
"users": [{"id": "foo_user", "tenant_id": "foo_tenant"},
{"id": "bar_user", "tenant_id": "bar_tenant"}],
"users": [{"id": "foo_user", "tenant_id": "foo_tenant",
"credential": mock.MagicMock()},
{"id": "bar_user", "tenant_id": "bar_tenant",
"credential": mock.MagicMock()}],
"tenants": {"foo_tenant": {"networks": [{"id": "foo_net"}]},
"bar_tenant": {"networks": [{"id": "bar_net"}]}}}
def test_START_CIDR_DFLT(self):
def test_default_start_cidr_is_valid(self):
netaddr.IPNetwork(network_context.Network.DEFAULT_CONFIG["start_cidr"])
@mock.patch("rally_openstack.common.osclients.Clients")
@mock.patch(NET + "wrap", return_value="foo_service")
def test__init__default(self, mock_wrap, mock_clients):
def test__init__default(self):
context = network_context.Network(self.get_context())
self.assertEqual(1, context.config["networks_per_tenant"])
self.assertEqual(network_context.Network.DEFAULT_CONFIG["start_cidr"],
context.config["start_cidr"])
self.assertIsNone(context.config["dns_nameservers"])
@mock.patch("rally_openstack.common.osclients.Clients")
@mock.patch(NET + "wrap", return_value="foo_service")
def test__init__explicit(self, mock_wrap, mock_clients):
def test__init__explicit(self):
context = network_context.Network(
self.get_context(start_cidr="foo_cidr", networks_per_tenant=42,
network_create_args={"fakearg": "fake"},
@ -61,57 +58,120 @@ class NetworkTestCase(test.TestCase):
self.assertEqual(("1.2.3.4", "5.6.7.8"),
context.config["dns_nameservers"])
@ddt.data({},
{"dns_nameservers": []},
{"dns_nameservers": ["1.2.3.4", "5.6.7.8"]})
@ddt.unpack
@mock.patch(NET + "wrap")
@mock.patch("rally_openstack.common.osclients.Clients")
def test_setup(self, mock_clients, mock_wrap, **dns_kwargs):
def create_net_infra(t_id, **kwargs):
return {"network": f"{t_id}-net", "subnets": []}
def test_setup(self):
ctx = self.get_context(networks_per_tenant=1,
network_create_args={},
subnets_per_network=2,
dns_nameservers=None,
external=True)
user = ctx["users"][0]
nc = user["credential"].clients.return_value.neutron.return_value
network = {"id": "net-id", "name": "s-1"}
subnets = [
{"id": "subnet1-id", "name": "subnet1-name"},
{"id": "subnet2-id", "name": "subnet2-name"}
]
router = {"id": "router"}
nc.create_network.return_value = {"network": network.copy()}
nc.create_router.return_value = {"router": router.copy()}
nc.create_subnet.side_effect = [{"subnet": s} for s in 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,
network_create_args={"fakearg": "fake"},
**dns_kwargs))
net_context._iterate_per_tenants = mock.MagicMock(
return_value=[
("foo_user", "foo_tenant"),
("bar_user", "bar_tenant")]
network_context.Network(ctx).setup()
ctx_data = ctx["tenants"][ctx["users"][0]["tenant_id"]]
self.assertEqual(
[{
"id": network["id"],
"name": network["name"],
"router_id": router["id"],
"subnets": [s["id"] for s in subnets]
}],
ctx_data["networks"]
)
net_context.setup()
nc.create_network.assert_called_once_with(
{"network": {"name": mock.ANY}})
nc.create_router.assert_called_once_with(
{"router": {"name": mock.ANY}})
self.assertEqual(
[
mock.call({"subnet": {
"name": mock.ANY, "network_id": network["id"],
"dns_nameservers": mock.ANY,
"ip_version": 4,
"cidr": mock.ANY}})
for i in range(2)],
nc.create_subnet.call_args_list
)
self.assertEqual(
[
mock.call(router["id"], {"subnet_id": subnets[0]["id"]}),
mock.call(router["id"], {"subnet_id": subnets[1]["id"]})
],
nc.add_interface_router.call_args_list
)
if "dns_nameservers" in dns_kwargs:
dns_kwargs["dns_nameservers"] = tuple(
dns_kwargs["dns_nameservers"])
create_calls = [
mock.call(tenant, dualstack=False,
subnets_num=1, network_create_args={"fakearg": "fake"},
router_create_args={"external": True},
**dns_kwargs)
for user, tenant in net_context._iterate_per_tenants.return_value]
mock_create.assert_has_calls(create_calls)
def test_setup_without_router(self):
dns_nameservers = ["1.2.3.4", "5.6.7.8"]
ctx = self.get_context(networks_per_tenant=1,
network_create_args={},
subnets_per_network=2,
router=None,
dns_nameservers=dns_nameservers)
user = ctx["users"][0]
nc = user["credential"].clients.return_value.neutron.return_value
network = {"id": "net-id", "name": "s-1"}
subnets = [
{"id": "subnet1-id", "name": "subnet1-name"},
{"id": "subnet2-id", "name": "subnet2-name"}
]
router = {"id": "router"}
nc.create_network.return_value = {"network": network.copy()}
nc.create_router.return_value = {"router": router.copy()}
nc.create_subnet.side_effect = [{"subnet": s} for s in subnets]
net_context._iterate_per_tenants.assert_called_once_with()
expected_networks = ["bar_tenant-net",
"foo_tenant-net"] * nets_per_tenant
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))
network_context.Network(ctx).setup()
@mock.patch("rally_openstack.common.osclients.Clients")
@mock.patch(NET + "wrap")
def test_cleanup(self, mock_wrap, mock_clients):
net_context = network_context.Network(self.get_context())
net_context.cleanup()
mock_wrap().delete_network.assert_has_calls(
[mock.call({"id": "foo_net"}), mock.call({"id": "bar_net"})],
any_order=True)
ctx_data = ctx["tenants"][ctx["users"][0]["tenant_id"]]
self.assertEqual(
[{
"id": network["id"],
"name": network["name"],
"router_id": None,
"subnets": [s["id"] for s in subnets]
}],
ctx_data["networks"]
)
nc.create_network.assert_called_once_with(
{"network": {"name": mock.ANY}})
self.assertEqual(
[
mock.call({"subnet": {
"name": mock.ANY, "network_id": network["id"],
# rally.task.context.Context converts list to unchangeable
# collection - tuple
"dns_nameservers": tuple(dns_nameservers),
"ip_version": 4,
"cidr": mock.ANY}})
for i in range(2)],
nc.create_subnet.call_args_list
)
self.assertFalse(nc.create_router.called)
self.assertFalse(nc.add_interface_router.called)
@mock.patch("%s.resource_manager.cleanup" % PATH)
def test_cleanup(self, mock_cleanup):
ctx = self.get_context()
network_context.Network(ctx).cleanup()
mock_cleanup.assert_called_once_with(
names=["neutron.subnet", "neutron.network", "neutron.router",
"neutron.port"],
superclass=network_context.Network,
admin=ctx.get("admin"),
users=ctx.get("users", []),
task_id=ctx["task"]["uuid"]
)

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ import ddt
import netaddr
from rally import exceptions
from rally_openstack.common import consts
from rally_openstack.task.scenarios.neutron import utils
from tests.unit import test
@ -251,6 +252,7 @@ class NeutronScenarioTestCase(test.ScenarioTestCase):
"neutron.create_router")
def test_create_router_with_ext_gw(self):
self._clients.credential.permission = consts.EndpointPermission.ADMIN
net_id = "ext-net"
self._nc.list_networks.return_value = {
"networks": [{"id": net_id, "router:external": True}]

View File

@ -919,9 +919,15 @@ class NovaServersTestCase(test.ScenarioTestCase):
scenario._get_console_url_server.assert_called_once_with(
server, "novnc")
@mock.patch(NOVA_SERVERS_MODULE + ".network_wrapper.wrap")
def test_boot_and_associate_floating_ip(self, mock_wrap):
scenario = servers.BootAndAssociateFloatingIp(self.context)
def test_boot_and_associate_floating_ip(self):
clients = mock.MagicMock()
neutronclient = clients.neutron.return_value
floatingip = "floatingip"
neutronclient.create_floatingip.return_value = {
"floatingip": floatingip}
scenario = servers.BootAndAssociateFloatingIp(self.context,
clients=clients)
server = mock.Mock()
scenario._boot_server = mock.Mock(return_value=server)
scenario._associate_floating_ip = mock.Mock()
@ -932,16 +938,21 @@ class NovaServersTestCase(test.ScenarioTestCase):
scenario._boot_server.assert_called_once_with(image, flavor,
fakearg="fakearg")
net_wrap = mock_wrap.return_value
net_wrap.create_floating_ip.assert_called_once_with(
tenant_id=server.tenant_id)
neutronclient.create_floatingip.assert_called_once_with(
{"floatingip": mock.ANY}
)
scenario._associate_floating_ip.assert_called_once_with(
server, net_wrap.create_floating_ip.return_value["ip"])
server, floatingip)
def test_boot_server_associate_and_dissociate_floating_ip(self):
clients = mock.MagicMock()
neutronclient = clients.neutron.return_value
floatingip = "floatingip"
neutronclient.create_floatingip.return_value = {
"floatingip": floatingip}
@mock.patch(NOVA_SERVERS_MODULE + ".network_wrapper.wrap")
def test_boot_server_associate_and_dissociate_floating_ip(self, mock_wrap):
scenario = servers.BootServerAssociateAndDissociateFloatingIP(
self.context)
self.context, clients=clients)
server = mock.Mock()
scenario._boot_server = mock.Mock(return_value=server)
scenario._associate_floating_ip = mock.Mock()
@ -953,13 +964,13 @@ class NovaServersTestCase(test.ScenarioTestCase):
scenario._boot_server.assert_called_once_with(image, flavor,
fakearg="fakearg")
net_wrap = mock_wrap.return_value
net_wrap.create_floating_ip.assert_called_once_with(
tenant_id=server.tenant_id)
neutronclient.create_floatingip.assert_called_once_with(
{"floatingip": mock.ANY}
)
scenario._associate_floating_ip.assert_called_once_with(
server, net_wrap.create_floating_ip.return_value["ip"])
server, floatingip)
scenario._dissociate_floating_ip.assert_called_once_with(
server, net_wrap.create_floating_ip.return_value["ip"])
server, floatingip)
def test_boot_and_update_server(self):
scenario = servers.BootAndUpdateServer(self.context)

View File

@ -136,7 +136,7 @@ class VMScenarioTestCase(test.ScenarioTestCase):
addresses={"foo_net": [{"addr": "foo_ip"}]},
tenant_id="foo_tenant"
)
scenario = utils.VMScenario(self.context)
scenario = utils.VMScenario(self.context, clients=mock.MagicMock())
scenario._boot_server = mock.Mock(return_value=server)
scenario._delete_server = mock.Mock()
@ -203,28 +203,29 @@ class VMScenarioTestCase(test.ScenarioTestCase):
scenario._delete_floating_ip.assert_called_once_with(server, fip)
scenario._delete_server.assert_called_once_with(server, force=True)
@mock.patch(VMTASKS_UTILS + ".network_wrapper.wrap")
def test__attach_floating_ip(self, mock_wrap):
def test__attach_floating_ip(self):
scenario, server = self.get_scenario()
nc = scenario._clients.neutron.return_value
netwrap = mock_wrap.return_value
fip = {"id": "foo_id", "ip": "foo_ip"}
netwrap.create_floating_ip.return_value = fip
fip = {"id": "foo_id", "floating_ip_address": "foo_ip"}
nc.create_floatingip.return_value = {"floatingip": fip}
floating_network = {"id": "floating-network-id",
"name": "floating-network"}
scenario._attach_floating_ip(
server, floating_network="bar_network")
server, floating_network=floating_network)
mock_wrap.assert_called_once_with(scenario.clients, scenario)
netwrap.create_floating_ip.assert_called_once_with(
ext_network="bar_network",
tenant_id="foo_tenant", fixed_ip="foo_ip")
nc.create_floatingip.assert_called_once_with({
"floatingip": {"description": mock.ANY,
"floating_network_id": floating_network["id"]}
})
scenario._associate_floating_ip.assert_called_once_with(
server, fip, fixed_address="foo_ip")
server, fip, fixed_address=fip["floating_ip_address"])
@mock.patch(VMTASKS_UTILS + ".network_wrapper.wrap")
def test__delete_floating_ip(self, mock_wrap):
def test__delete_floating_ip(self):
scenario, server = self.get_scenario()
nc = scenario._clients.neutron.return_value
_check_addr = mock.Mock(return_value=True)
scenario.check_ip_address = mock.Mock(return_value=_check_addr)
@ -238,9 +239,7 @@ class VMScenarioTestCase(test.ScenarioTestCase):
_check_addr.assert_called_once_with(server)
scenario._dissociate_floating_ip.assert_called_once_with(
server, fip)
mock_wrap.assert_called_once_with(scenario.clients, scenario)
mock_wrap.return_value.delete_floating_ip.assert_called_once_with(
"foo_id", wait=True)
nc.delete_floatingip.assert_called_once_with("foo_id")
class HostTestCase(test.TestCase):

View File

@ -44,6 +44,7 @@ CRED = {
"project_domain_name": "admin"
}
NET_PATH = "rally_openstack.common.services.network"
PATH = "rally_openstack.verification.tempest.context"
@ -266,17 +267,17 @@ class TempestContextTestCase(test.TestCase):
client.create_subnet.side_effect = [{"subnet": {"id": "subid1"}}]
client.list_networks.return_value = {"networks": []}
network = self.context._create_network_resources()
self.assertEqual("nid1", network["id"])
self.assertEqual("nid1", self.context._created_networks[0]["id"])
self.assertEqual("rid1",
self.context._created_networks[0]["router_id"])
self.assertEqual("subid1",
self.context._created_networks[0]["subnets"][0])
net_topo = self.context._create_network_resources()
self.assertEqual("nid1", net_topo["network"]["id"])
self.assertEqual("rid1", net_topo["routers"][0]["id"])
self.assertEqual("subid1", net_topo["subnets"][0]["id"])
@mock.patch("%s.neutron.NeutronService.supports_extension" % PATH)
def test__create_network_resources_public_network_override(
self, mock_supports_extension):
mock_supports_extension.return_value = True
@mock.patch("rally_openstack.common.wrappers.network.NeutronWrapper.ext_gw_mode_enabled", # noqa E501
new_callable=mock.PropertyMock, return_value=True)
def test__create_network_resources_public_network_override(self, mock_ext_gw_mode_enabled): # noqa E501
client = self.context.clients.neutron()
conf = self.context.conf
@ -348,15 +349,16 @@ class TempestContextTestCase(test.TestCase):
self.assertEqual("", self.context.conf.get("orchestration",
"instance_type"))
@mock.patch("rally_openstack.common.wrappers."
"network.NeutronWrapper.delete_network")
def test__cleanup_network_resources(
self, mock_neutron_wrapper_delete_network):
self.context._created_networks = [{"name": "net-12345"}]
@mock.patch("%s.neutron.NeutronService.delete_network_topology" % PATH)
def test__cleanup_network_resources(self, mock_delete_network_topology):
self.context._created_networks = [{"network": {"name": "net-12345"}}]
self.context.conf.set("compute", "fixed_network_name", "net-12345")
self.context._cleanup_network_resources()
self.assertEqual(1, mock_neutron_wrapper_delete_network.call_count)
mock_delete_network_topology.assert_called_once_with(
self.context._created_networks[0]
)
self.assertEqual("", self.context.conf.get("compute",
"fixed_network_name"))