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 - .zuul.d/zuul.yaml
- rally-jobs/neutron-trunk.yaml - rally-jobs/neutron-trunk.yaml
- rally_openstack/common/osclients.py - 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/trunk.py
- rally_openstack/task/scenarios/neutron/network.py - rally_openstack/task/scenarios/neutron/network.py
- tests/ci/playbooks - tests/ci/playbooks
@ -105,6 +108,9 @@
files: files:
- rally-jobs/neutron-trunk.yaml - rally-jobs/neutron-trunk.yaml
- rally_openstack/common/osclients.py - 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/trunk.py
- rally_openstack/task/scenarios/neutron/network.py - rally_openstack/task/scenarios/neutron/network.py
- tests/ci/playbooks - tests/ci/playbooks

View File

@ -26,9 +26,16 @@ Changed
image changed from /rally/xrally_opentstack to /rally/xrally_openstack image changed from /rally/xrally_opentstack to /rally/xrally_openstack
(there was a typo in work 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 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 * [verification component] Make config parser case sensitivity in
TempestContext and TempestConfigfileManager. TempestContext and TempestConfigfileManager.

View File

@ -78,8 +78,7 @@
workloads: workloads:
- -
scenario: scenario:
NeutronNetworks.create_and_list_networks: NeutronNetworks.create_and_list_networks: {}
network_create_args:
runner: runner:
constant: constant:
times: 2 times: 2
@ -92,6 +91,8 @@
NeutronNetworks.create_and_list_subnets: NeutronNetworks.create_and_list_subnets:
subnet_cidr_start: "1.1.0.0/30" subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2 subnets_per_network: 2
contexts:
network: {}
runner: runner:
constant: constant:
times: 2 times: 2
@ -111,3 +112,25 @@
sla: sla:
failure_rate: failure_rate:
max: 0 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: NeutronNetworks.create_and_list_subnets:
- -
args: args:
network_create_args: network_create_args: {}
subnet_create_args: subnet_create_args: {}
subnet_cidr_start: "1.1.0.0/30" subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2 subnets_per_network: 2
runner: runner:
@ -113,8 +113,6 @@
NeutronNetworks.create_and_show_subnets: NeutronNetworks.create_and_show_subnets:
- -
args: args:
network_create_args:
subnet_create_args:
subnet_cidr_start: "1.1.0.0/30" subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2 subnets_per_network: 2
runner: runner:
@ -316,11 +314,8 @@
NeutronNetworks.create_and_list_routers: NeutronNetworks.create_and_list_routers:
- -
args: args:
network_create_args:
subnet_create_args:
subnet_cidr_start: "1.1.0.0/30" subnet_cidr_start: "1.1.0.0/30"
subnets_per_network: 2 subnets_per_network: 2
router_create_args:
runner: runner:
type: "constant" type: "constant"
times: {{smoke or 8}} times: {{smoke or 8}}
@ -362,8 +357,6 @@
NeutronNetworks.create_and_list_ports: NeutronNetworks.create_and_list_ports:
- -
args: args:
network_create_args:
port_create_args:
ports_per_network: 4 ports_per_network: 4
runner: runner:
type: "constant" type: "constant"
@ -403,8 +396,6 @@
NeutronNetworks.create_and_show_ports: NeutronNetworks.create_and_show_ports:
- -
args: args:
network_create_args: {}
port_create_args: {}
ports_per_network: 2 ports_per_network: 2
runner: runner:
type: "constant" type: "constant"
@ -429,7 +420,6 @@
network_create_args: {} network_create_args: {}
network_update_args: network_update_args:
admin_state_up: False admin_state_up: False
name: "_updated"
runner: runner:
type: "constant" type: "constant"
times: {{smoke or 8}} times: {{smoke or 8}}
@ -454,7 +444,6 @@
subnets_per_network: 2 subnets_per_network: 2
subnet_update_args: subnet_update_args:
enable_dhcp: False enable_dhcp: False
name: "_subnet_updated"
runner: runner:
type: "constant" type: "constant"
times: {{smoke or 8}} times: {{smoke or 8}}
@ -482,7 +471,6 @@
router_create_args: {} router_create_args: {}
router_update_args: router_update_args:
admin_state_up: False admin_state_up: False
name: "_router_updated"
runner: runner:
type: "constant" type: "constant"
times: {{smoke or 4}} times: {{smoke or 4}}
@ -624,7 +612,6 @@
admin_state_up: False admin_state_up: False
device_id: "dummy_id" device_id: "dummy_id"
device_owner: "dummy_owner" device_owner: "dummy_owner"
name: "_port_updated"
runner: runner:
type: "constant" type: "constant"
times: {{smoke or 10}} 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 variable is not specified, validation will assume that your client
doesn't allow to specify service type. doesn't allow to specify service type.
:param supported_versions: List of supported versions(If this variable is :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 exception that client doesn't support setting any versions. If this
logic is wrong for your client, you should override `validate_version` logic is wrong for your client, you should override `validate_version`
in client object) in client object)

View File

@ -20,6 +20,7 @@ from rally import exceptions
from rally.task import atomic from rally.task import atomic
from rally.task import service from rally.task import service
from rally_openstack.common import consts
from rally_openstack.common.services.network import net_utils 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) resp = self.client.show_network(network_id, **body)
return resp["network"] 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) """Find network by identifier (id or name)
:param network_id_or_name: Network 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(): for net in self.list_networks():
if network_id_or_name in (net["name"], net["id"]): if network_id_or_name in (net["name"], net["id"]):
return net network = net
raise exceptions.GetResourceFailure( break
resource="network", if network is None:
err=f"no name or id matches {network_id_or_name}") 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") @atomic.action_timer("neutron.update_network")
@_create_network_arg_adapter() @_create_network_arg_adapter()
@ -579,7 +590,7 @@ class NeutronService(service.Service):
description=_NONE, discover_external_gw=False, description=_NONE, discover_external_gw=False,
external_gateway_info=_NONE, distributed=_NONE, ha=_NONE, external_gateway_info=_NONE, distributed=_NONE, ha=_NONE,
availability_zone_hints=_NONE, service_type_id=_NONE, availability_zone_hints=_NONE, service_type_id=_NONE,
flavor_id=_NONE): flavor_id=_NONE, enable_snat=_NONE):
"""Create router. """Create router.
:param project_id: The ID of the project that owns the resource. Only :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 :param service_type_id: The ID of the service type associated with
the router. the router.
:param flavor_id: The ID of the flavor 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: if external_gateway_info is _NONE and discover_external_gw:
for external_network in self.list_networks(router_external=True): for external_network in self.list_networks(router_external=True):
external_gateway_info = {"network_id": external_network["id"]} 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 external_gateway_info["enable_snat"] = True
break break
@ -856,7 +876,8 @@ class NeutronService(service.Service):
self.client.delete_port(port["id"]) self.client.delete_port(port["id"])
except neutron_exceptions.PortNotFoundClient: except neutron_exceptions.PortNotFoundClient:
# port is auto-removed # port is auto-removed
pass return False
return True
@atomic.action_timer("neutron.list_ports") @atomic.action_timer("neutron.list_ports")
def list_ports(self, network_id=_NONE, device_id=_NONE, device_owner=_NONE, 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): if isinstance(floating_network, dict):
net_id = floating_network["id"] net_id = floating_network["id"]
elif floating_network: elif floating_network:
network = self.find_network(floating_network) net_id = self.find_network(floating_network, external=True)["id"]
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"]
else: else:
ext_networks = self.list_networks(router_external=True) ext_networks = self.list_networks(router_external=True)
if not ext_networks: if not ext_networks:

View File

@ -61,7 +61,7 @@ class NetworkWrapper(object, metaclass=abc.ABCMeta):
START_IPV6_CIDR = "dead:beaf::/64" START_IPV6_CIDR = "dead:beaf::/64"
SERVICE_IMPL = None SERVICE_IMPL = None
def __init__(self, clients, owner, config=None, atomics=None): def __init__(self, clients, owner, config=None):
"""Returns available network wrapper instance. """Returns available network wrapper instance.
:param clients: rally.plugins.openstack.osclients.Clients 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'. recognized, 'start_cidr' and 'start_ipv6_cidr'.
:returns: NetworkWrapper subclass instance :returns: NetworkWrapper subclass instance
""" """
self.clients = clients
if hasattr(clients, self.SERVICE_IMPL): if hasattr(clients, self.SERVICE_IMPL):
self.client = getattr(clients, self.SERVICE_IMPL)() self.client = getattr(clients, self.SERVICE_IMPL)()
else: else:
@ -123,6 +124,10 @@ class NeutronWrapper(NetworkWrapper):
def neutron(_self): def neutron(_self):
return self.client return self.client
@property
def credential(_self):
return self.clients.credential
self.neutron = neutron.NeutronService( self.neutron = neutron.NeutronService(
clients=_SingleClientWrapper(), clients=_SingleClientWrapper(),
name_generator=self.owner.generate_random_name, 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 credential
from rally_openstack.common import osclients from rally_openstack.common import osclients
from rally_openstack.common.services.identity import identity 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 from rally_openstack.task import context
@ -35,8 +35,8 @@ LOG = logging.getLogger(__name__)
CONF = cfg.CONF CONF = cfg.CONF
RESOURCE_MANAGEMENT_WORKERS_DESCR = ("The number of concurrent threads to use " RESOURCE_MANAGEMENT_WORKERS_DESCR = (
"for serving users context.") "The number of concurrent threads to use for serving users context.")
PROJECT_DOMAIN_DESCR = "ID of domain in which projects will be created." PROJECT_DOMAIN_DESCR = "ID of domain in which projects will be created."
USER_DOMAIN_DESCR = "ID of domain in which users 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(): for key, value in self.DEFAULT_FOR_NEW_USERS.items():
self.config.setdefault(key, value) 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): def _create_tenants(self, threads):
tenants = collections.deque() tenants = collections.deque()
@ -237,36 +213,6 @@ class UserGenerator(context.OpenStackContext):
broker.run(publish, consume, threads) broker.run(publish, consume, threads)
return list(users) 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): def create_users(self):
"""Create tenants and users, using the broker pattern.""" """Create tenants and users, using the broker pattern."""
@ -331,6 +277,54 @@ class UserGenerator(context.OpenStackContext):
else: else:
self.create_users() 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): def cleanup(self):
"""Delete tenants and users, using the broker pattern.""" """Delete tenants and users, using the broker pattern."""
if self.existing_users: if self.existing_users:

View File

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

View File

@ -17,17 +17,15 @@ from rally.common import logging
from rally.common import validation from rally.common import validation
from rally_openstack.common import consts from rally_openstack.common import consts
from rally_openstack.common import osclients from rally_openstack.common.services.network import neutron
from rally_openstack.common.wrappers import network as network_wrapper from rally_openstack.task.cleanup import manager as resource_manager
from rally_openstack.task import context from rally_openstack.task import context
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
# NOTE(andreykurilin): admin is used only by cleanup @validation.add("required_platform", platform="openstack", users=True)
@validation.add("required_platform", platform="openstack", admin=True,
users=True)
@context.configure(name="network", platform="openstack", order=350) @context.configure(name="network", platform="openstack", order=350)
class Network(context.OpenStackContext): class Network(context.OpenStackContext):
"""Create networking resources. """Create networking resources.
@ -67,7 +65,13 @@ class Network(context.OpenStackContext):
"type": "object", "type": "object",
"properties": { "properties": {
"external": { "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": { "external_gateway_info": {
"description": "The external gateway information .", "description": "The external gateway information .",
@ -90,7 +94,6 @@ class Network(context.OpenStackContext):
"networks_per_tenant": 1, "networks_per_tenant": 1,
"subnets_per_network": 1, "subnets_per_network": 1,
"network_create_args": {}, "network_create_args": {},
"dns_nameservers": None,
"router": {"external": True}, "router": {"external": True},
"dualstack": False "dualstack": False
} }
@ -100,27 +103,47 @@ class Network(context.OpenStackContext):
# multithreading/multiprocessing, it is likely the # multithreading/multiprocessing, it is likely the
# sockets are left open. This problem is eliminated by # sockets are left open. This problem is eliminated by
# creating a connection in setup and cleanup separately. # 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(): for user, tenant_id in self._iterate_per_tenants():
self.context["tenants"][tenant_id]["networks"] = [] self.context["tenants"][tenant_id]["networks"] = []
self.context["tenants"][tenant_id]["subnets"] = [] 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"]): 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( net_infra = client.create_network_topology(
tenant_id,
dualstack=self.config["dualstack"],
subnets_num=self.config["subnets_per_network"],
network_create_args=network_create_args, network_create_args=network_create_args,
router_create_args=self.config["router"], subnet_create_args=subnet_create_args,
**kwargs) 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( self.context["tenants"][tenant_id]["networks"].append(
net_infra["network"] net_infra["network"]
) )
@ -129,12 +152,13 @@ class Network(context.OpenStackContext):
) )
def cleanup(self): def cleanup(self):
net_wrapper = network_wrapper.wrap( resource_manager.cleanup(
osclients.Clients(self.context["admin"]["credential"]), names=[
self, config=self.config) "neutron.subnet", "neutron.network", "neutron.router",
for tenant_id, tenant_ctx in self.context["tenants"].items(): "neutron.port"
for network in tenant_ctx.get("networks", []): ],
with logging.ExceptionLogger( admin=self.context.get("admin"),
LOG, users=self.context.get("users", []),
"Failed to delete network for tenant %s" % tenant_id): task_id=self.get_owner_id(),
net_wrapper.delete_network(network) superclass=self.__class__
)

View File

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

View File

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

View File

@ -26,7 +26,6 @@ from rally.task import atomic
from rally.task import utils from rally.task import utils
from rally.utils import sshutils 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 from rally_openstack.task.scenarios.nova import utils as nova_utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -161,30 +160,23 @@ class VMScenario(nova_utils.NovaScenario):
"id": fip.get("id"), "id": fip.get("id"),
"is_floating": use_floating_ip} "is_floating": use_floating_ip}
@atomic.action_timer("vm.attach_floating_ip")
def _attach_floating_ip(self, server, floating_network): def _attach_floating_ip(self, server, floating_network):
internal_network = list(server.networks)[0] internal_network = list(server.networks)[0]
fixed_ip = server.addresses[internal_network][0]["addr"] fixed_ip = server.addresses[internal_network][0]["addr"]
with atomic.ActionTimer(self, "neutron.create_floating_ip"): floatingip = self.neutron.create_floatingip(
fip = network_wrapper.wrap(self.clients, self).create_floating_ip( floating_network=floating_network)
ext_network=floating_network, self._associate_floating_ip(server, floatingip, fixed_address=fixed_ip)
tenant_id=server.tenant_id, fixed_ip=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): def _delete_floating_ip(self, server, fip):
with logging.ExceptionLogger( with logging.ExceptionLogger(
LOG, "Unable to delete IP: %s" % fip["ip"]): LOG, "Unable to delete IP: %s" % fip["ip"]):
if self.check_ip_address(fip["ip"])(server): if self.check_ip_address(fip["ip"])(server):
self._dissociate_floating_ip(server, fip) self._dissociate_floating_ip(server, fip)
with atomic.ActionTimer(self, "neutron.delete_floating_ip"): self.neutron.delete_floatingip(fip["id"])
network_wrapper.wrap(self.clients,
self).delete_floating_ip(
fip["id"], wait=True)
def _delete_server_with_fip(self, server, fip, force_delete=False): def _delete_server_with_fip(self, server, fip, force_delete=False):
if fip["is_floating"]: 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 consts
from rally_openstack.common import credential from rally_openstack.common import credential
from rally_openstack.common.services.image import image 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 from rally_openstack.verification.tempest import config as conf
@ -287,25 +287,29 @@ class TempestContext(context.VerifierContext):
return flavor return flavor
def _create_network_resources(self): 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 tenant_id = self.clients.keystone.auth_ref.project_id
router_create_args = {} router_create_args = {"project_id": tenant_id}
public_net = None public_net = None
if self.conf.has_section("network"): if self.conf.has_section("network"):
public_net = self.conf.get("network", "public_network_id") public_net = self.conf.get("network", "public_network_id")
if public_net: if public_net:
ext_gw_mode_enabled = neutron_wrapper.ext_gw_mode_enabled
external_gateway_info = { external_gateway_info = {
"network_id": public_net "network_id": public_net
} }
if ext_gw_mode_enabled: if client.supports_extension("ext-gw-mode", silent=True):
external_gateway_info["enable_snat"] = True external_gateway_info["enable_snat"] = True
router_create_args["external_gateway_info"] = external_gateway_info router_create_args["external_gateway_info"] = external_gateway_info
LOG.debug("Creating network resources: network, subnet, router.") LOG.debug("Creating network resources: network, subnet, router.")
net = neutron_wrapper.create_network( net = client.create_network_topology(
tenant_id, subnets_num=1, add_router=True, subnets_count=1,
router_create_args=router_create_args, 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!") LOG.debug("Network resources have been successfully created!")
self._created_networks.append(net) self._created_networks.append(net)
@ -343,11 +347,16 @@ class TempestContext(context.VerifierContext):
self._remove_opt_value_from_config("orchestration", flavor.id) self._remove_opt_value_from_config("orchestration", flavor.id)
def _cleanup_network_resources(self): def _cleanup_network_resources(self):
neutron_wrapper = network.NeutronWrapper(self.clients, self) client = neutron.NeutronService(
for net in self._created_networks: 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.") LOG.debug("Deleting network resources: router, subnet, network.")
neutron_wrapper.delete_network(net) client.delete_network_topology(topo)
self._remove_opt_value_from_config("compute", net["name"]) self._remove_opt_value_from_config("compute",
topo["network"]["name"])
LOG.debug("Network resources have been deleted.") LOG.debug("Network resources have been deleted.")
def _remove_opt_value_from_config(self, section, opt_value): def _remove_opt_value_from_config(self, section, opt_value):

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -151,7 +151,6 @@
network_create_args: {} network_create_args: {}
network_update_args: network_update_args:
admin_state_up: false admin_state_up: false
name: "_updated"
context: context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %} {% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas: quotas:
@ -172,7 +171,6 @@
admin_state_up: false admin_state_up: false
device_id: "dummy_id" device_id: "dummy_id"
device_owner: "dummy_owner" device_owner: "dummy_owner"
name: "_port_updated"
ports_per_network: 1 ports_per_network: 1
context: context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %} {% call user_context(tenants_amount, users_amount, use_existing_users) %}
@ -193,7 +191,6 @@
router_create_args: {} router_create_args: {}
router_update_args: router_update_args:
admin_state_up: false admin_state_up: false
name: "_router_updated"
subnet_cidr_start: "1.1.0.0/30" subnet_cidr_start: "1.1.0.0/30"
subnet_create_args: {} subnet_create_args: {}
subnets_per_network: 1 subnets_per_network: 1
@ -219,7 +216,6 @@
subnet_create_args: {} subnet_create_args: {}
subnet_update_args: subnet_update_args:
enable_dhcp: false enable_dhcp: false
name: "_subnet_updated"
subnets_per_network: 1 subnets_per_network: 1
context: context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %} {% 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 # License for the specific language governing permissions and limitations
# under the License. # under the License.
ALLOWED_EXTRA_MISSING=4 ALLOWED_EXTRA_MISSING=10
show_diff () { show_diff () {
head -1 $1 head -1 $1

View File

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

View File

@ -263,84 +263,60 @@ class UserGeneratorForNewUsersTestCase(test.ScenarioTestCase):
"task": {"uuid": "task_id", "deployment_uuid": "dep_uuid"} "task": {"uuid": "task_id", "deployment_uuid": "dep_uuid"}
}) })
@mock.patch("%s.network.wrap" % CTX) def test__remove_default_security_group(self):
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)
@mock.patch("%s.network.wrap" % CTX) self.context.update(
def test__remove_default_security_group_neutron_no_sg(self, mock_wrap): tenants={
net_wrapper = mock.Mock(SERVICE_IMPL=consts.Service.NEUTRON) "tenant-1": {},
net_wrapper.supports_extension.return_value = (False, None) "tenant-2": {}
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")
]
) )
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, neutron.list_security_groups.return_value = {
user_generator) "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() users.UserGenerator(self.context)._remove_default_security_group()
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)
user_net = user1.neutron.return_value neutron.list_security_groups.assert_called_once_with(name="default")
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
self.assertEqual( self.assertEqual(
[mock.call("id-1"), mock.call("id-3")], [mock.call("id-1"), mock.call("id-2")],
admin_neutron.delete_security_group.call_args_list) 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) @mock.patch("%s.identity" % CTX)
def test__create_tenants(self, mock_identity): def test__create_tenants(self, mock_identity):

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import copy
from unittest import mock from unittest import mock
from rally_openstack.task.contexts.network import allow_ssh from rally_openstack.task.contexts.network import allow_ssh
@ -26,87 +27,94 @@ class AllowSSHContextTestCase(test.TestCase):
def setUp(self): def setUp(self):
super(AllowSSHContextTestCase, self).setUp() super(AllowSSHContextTestCase, self).setUp()
self.users = 2 self.users_count = 3
self.secgroup_name = "test-secgroup"
self.ctx_with_secgroup = test.get_test_context() self.ctx = test.get_test_context()
self.ctx_with_secgroup.update({ self.ctx.update(
"users": [ users=[
{ {
"tenant_id": "uuid1", "tenant_id": f"uuid{i // 3}",
"credential": "credential", "credential": mock.MagicMock()
"secgroup": {"id": "secgroup_id", "name": "secgroup"}
} }
] * self.users, for i in range(1, self.users_count + 1)
"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")
], ],
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( def test_setup(self):
mock_clients.return_value, secgrp_ctx, config={}) 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) allow_ssh.AllowSSH(self.ctx).setup()
@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()
secgrp_ctx = allow_ssh.AllowSSH(dict(self.ctx_without_secgroup)) # admin user should not be used
secgrp_ctx.setup() self.assertFalse(self.ctx["admin"]["credential"].clients.called)
self.assertEqual(self.ctx_without_secgroup, secgrp_ctx.context)
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( if user["tenant_id"] in processed_tenants:
mock_clients.return_value, secgrp_ctx, config={}) 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 rally_openstack.task.contexts.network import networks as network_context
from tests.unit import test from tests.unit import test
NET = "rally_openstack.common.wrappers.network." PATH = "rally_openstack.task.contexts.network.networks"
@ddt.ddt @ddt.ddt
@ -30,26 +30,23 @@ class NetworkTestCase(test.TestCase):
return {"task": {"uuid": "foo_task"}, return {"task": {"uuid": "foo_task"},
"admin": {"credential": "foo_admin"}, "admin": {"credential": "foo_admin"},
"config": {"network": kwargs}, "config": {"network": kwargs},
"users": [{"id": "foo_user", "tenant_id": "foo_tenant"}, "users": [{"id": "foo_user", "tenant_id": "foo_tenant",
{"id": "bar_user", "tenant_id": "bar_tenant"}], "credential": mock.MagicMock()},
{"id": "bar_user", "tenant_id": "bar_tenant",
"credential": mock.MagicMock()}],
"tenants": {"foo_tenant": {"networks": [{"id": "foo_net"}]}, "tenants": {"foo_tenant": {"networks": [{"id": "foo_net"}]},
"bar_tenant": {"networks": [{"id": "bar_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"]) netaddr.IPNetwork(network_context.Network.DEFAULT_CONFIG["start_cidr"])
@mock.patch("rally_openstack.common.osclients.Clients") def test__init__default(self):
@mock.patch(NET + "wrap", return_value="foo_service")
def test__init__default(self, mock_wrap, mock_clients):
context = network_context.Network(self.get_context()) context = network_context.Network(self.get_context())
self.assertEqual(1, context.config["networks_per_tenant"]) self.assertEqual(1, context.config["networks_per_tenant"])
self.assertEqual(network_context.Network.DEFAULT_CONFIG["start_cidr"], self.assertEqual(network_context.Network.DEFAULT_CONFIG["start_cidr"],
context.config["start_cidr"]) context.config["start_cidr"])
self.assertIsNone(context.config["dns_nameservers"])
@mock.patch("rally_openstack.common.osclients.Clients") def test__init__explicit(self):
@mock.patch(NET + "wrap", return_value="foo_service")
def test__init__explicit(self, mock_wrap, mock_clients):
context = network_context.Network( context = network_context.Network(
self.get_context(start_cidr="foo_cidr", networks_per_tenant=42, self.get_context(start_cidr="foo_cidr", networks_per_tenant=42,
network_create_args={"fakearg": "fake"}, network_create_args={"fakearg": "fake"},
@ -61,57 +58,120 @@ class NetworkTestCase(test.TestCase):
self.assertEqual(("1.2.3.4", "5.6.7.8"), self.assertEqual(("1.2.3.4", "5.6.7.8"),
context.config["dns_nameservers"]) context.config["dns_nameservers"])
@ddt.data({}, def test_setup(self):
{"dns_nameservers": []}, ctx = self.get_context(networks_per_tenant=1,
{"dns_nameservers": ["1.2.3.4", "5.6.7.8"]}) network_create_args={},
@ddt.unpack subnets_per_network=2,
@mock.patch(NET + "wrap") dns_nameservers=None,
@mock.patch("rally_openstack.common.osclients.Clients") external=True)
def test_setup(self, mock_clients, mock_wrap, **dns_kwargs): user = ctx["users"][0]
def create_net_infra(t_id, **kwargs): nc = user["credential"].clients.return_value.neutron.return_value
return {"network": f"{t_id}-net", "subnets": []} 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) network_context.Network(ctx).setup()
mock_wrap.return_value = mock.Mock(
_create_network_infrastructure=mock_create) ctx_data = ctx["tenants"][ctx["users"][0]["tenant_id"]]
nets_per_tenant = 2 self.assertEqual(
net_context = network_context.Network( [{
self.get_context(networks_per_tenant=nets_per_tenant, "id": network["id"],
network_create_args={"fakearg": "fake"}, "name": network["name"],
**dns_kwargs)) "router_id": router["id"],
net_context._iterate_per_tenants = mock.MagicMock( "subnets": [s["id"] for s in subnets]
return_value=[ }],
("foo_user", "foo_tenant"), ctx_data["networks"]
("bar_user", "bar_tenant")]
) )
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: def test_setup_without_router(self):
dns_kwargs["dns_nameservers"] = tuple( dns_nameservers = ["1.2.3.4", "5.6.7.8"]
dns_kwargs["dns_nameservers"]) ctx = self.get_context(networks_per_tenant=1,
create_calls = [ network_create_args={},
mock.call(tenant, dualstack=False, subnets_per_network=2,
subnets_num=1, network_create_args={"fakearg": "fake"}, router=None,
router_create_args={"external": True}, dns_nameservers=dns_nameservers)
**dns_kwargs) user = ctx["users"][0]
for user, tenant in net_context._iterate_per_tenants.return_value] nc = user["credential"].clients.return_value.neutron.return_value
mock_create.assert_has_calls(create_calls) 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() network_context.Network(ctx).setup()
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))
@mock.patch("rally_openstack.common.osclients.Clients") ctx_data = ctx["tenants"][ctx["users"][0]["tenant_id"]]
@mock.patch(NET + "wrap") self.assertEqual(
def test_cleanup(self, mock_wrap, mock_clients): [{
net_context = network_context.Network(self.get_context()) "id": network["id"],
net_context.cleanup() "name": network["name"],
mock_wrap().delete_network.assert_has_calls( "router_id": None,
[mock.call({"id": "foo_net"}), mock.call({"id": "bar_net"})], "subnets": [s["id"] for s in subnets]
any_order=True) }],
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 import netaddr
from rally import exceptions from rally import exceptions
from rally_openstack.common import consts
from rally_openstack.task.scenarios.neutron import utils from rally_openstack.task.scenarios.neutron import utils
from tests.unit import test from tests.unit import test
@ -251,6 +252,7 @@ class NeutronScenarioTestCase(test.ScenarioTestCase):
"neutron.create_router") "neutron.create_router")
def test_create_router_with_ext_gw(self): def test_create_router_with_ext_gw(self):
self._clients.credential.permission = consts.EndpointPermission.ADMIN
net_id = "ext-net" net_id = "ext-net"
self._nc.list_networks.return_value = { self._nc.list_networks.return_value = {
"networks": [{"id": net_id, "router:external": True}] "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( scenario._get_console_url_server.assert_called_once_with(
server, "novnc") server, "novnc")
@mock.patch(NOVA_SERVERS_MODULE + ".network_wrapper.wrap") def test_boot_and_associate_floating_ip(self):
def test_boot_and_associate_floating_ip(self, mock_wrap): clients = mock.MagicMock()
scenario = servers.BootAndAssociateFloatingIp(self.context) neutronclient = clients.neutron.return_value
floatingip = "floatingip"
neutronclient.create_floatingip.return_value = {
"floatingip": floatingip}
scenario = servers.BootAndAssociateFloatingIp(self.context,
clients=clients)
server = mock.Mock() server = mock.Mock()
scenario._boot_server = mock.Mock(return_value=server) scenario._boot_server = mock.Mock(return_value=server)
scenario._associate_floating_ip = mock.Mock() scenario._associate_floating_ip = mock.Mock()
@ -932,16 +938,21 @@ class NovaServersTestCase(test.ScenarioTestCase):
scenario._boot_server.assert_called_once_with(image, flavor, scenario._boot_server.assert_called_once_with(image, flavor,
fakearg="fakearg") fakearg="fakearg")
net_wrap = mock_wrap.return_value neutronclient.create_floatingip.assert_called_once_with(
net_wrap.create_floating_ip.assert_called_once_with( {"floatingip": mock.ANY}
tenant_id=server.tenant_id) )
scenario._associate_floating_ip.assert_called_once_with( 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( scenario = servers.BootServerAssociateAndDissociateFloatingIP(
self.context) self.context, clients=clients)
server = mock.Mock() server = mock.Mock()
scenario._boot_server = mock.Mock(return_value=server) scenario._boot_server = mock.Mock(return_value=server)
scenario._associate_floating_ip = mock.Mock() scenario._associate_floating_ip = mock.Mock()
@ -953,13 +964,13 @@ class NovaServersTestCase(test.ScenarioTestCase):
scenario._boot_server.assert_called_once_with(image, flavor, scenario._boot_server.assert_called_once_with(image, flavor,
fakearg="fakearg") fakearg="fakearg")
net_wrap = mock_wrap.return_value neutronclient.create_floatingip.assert_called_once_with(
net_wrap.create_floating_ip.assert_called_once_with( {"floatingip": mock.ANY}
tenant_id=server.tenant_id) )
scenario._associate_floating_ip.assert_called_once_with( 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( 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): def test_boot_and_update_server(self):
scenario = servers.BootAndUpdateServer(self.context) scenario = servers.BootAndUpdateServer(self.context)

View File

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

View File

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