![Sanjay Chari](/assets/img/avatar_default.png)
This patch makes the following changes. 1. Provider network dynamic workloads perform operations only on the provider networks created by dynamic workloads and not rally context external networks. 2. Locks have been incorporated into the provider networks dynamic workloads code in order to prevent race conditions. Closes-Bug: #1993527 Change-Id: If891b83517aa442e3594e84ec70e95d44a8d8fd4
178 lines
8.4 KiB
Python
178 lines
8.4 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import random
|
|
import os
|
|
import subprocess
|
|
|
|
from rally_openstack.task.scenarios.neutron import utils as neutron_utils
|
|
import dynamic_utils
|
|
from rally.task import atomic
|
|
|
|
from neutronclient.common.exceptions import NetworkNotFoundClient
|
|
|
|
class DynamicProviderNetworkBase(dynamic_utils.NovaUtils,
|
|
neutron_utils.NeutronScenario, dynamic_utils.LockUtils):
|
|
|
|
@atomic.action_timer("neutron.create_network")
|
|
def _create_provider_network(self, provider_phys_net):
|
|
"""Create neutron provider network.
|
|
:param provider_phys_net: provider physical network
|
|
:returns: neutron network dict
|
|
"""
|
|
project_id = self.context["tenant"]["id"]
|
|
body = {
|
|
"name": self.generate_random_name(),
|
|
"tenant_id": project_id,
|
|
"provider:network_type": "vlan",
|
|
"provider:physical_network": provider_phys_net,
|
|
"description": "dynwklds_provider_net"
|
|
}
|
|
# provider network can be created by admin client only
|
|
return self.admin_clients("neutron").create_network({"network": body})
|
|
|
|
@atomic.action_timer("neutron.show_network")
|
|
def _show_provider_network(self, provider_network):
|
|
"""Fetches information of a certain provider network.
|
|
:param provider_network: provider network object
|
|
"""
|
|
try:
|
|
return self.admin_clients("neutron").show_network(provider_network['network']['id'])
|
|
except NetworkNotFoundClient:
|
|
return None
|
|
|
|
@atomic.action_timer("neutron.delete_network")
|
|
def _delete_provider_network(self, provider_network):
|
|
"""Delete neutron provider network.
|
|
:param provider_network: provider network object
|
|
"""
|
|
|
|
return self.admin_clients("neutron").delete_network(provider_network['network']['id'])
|
|
|
|
def ping_server(self, server, iface_name, iface_mac, network, subnet):
|
|
"""Ping server created on provider network
|
|
:param server: server object
|
|
:param iface_name: interface name
|
|
:param iface_mac: interface MAC
|
|
:param network: provider network object
|
|
:param subnet: subnet object
|
|
"""
|
|
|
|
internal_network = list(server.networks)[0]
|
|
server_ip = server.addresses[internal_network][0]["addr"]
|
|
server_mac = server.addresses[internal_network][0]["OS-EXT-IPS-MAC:mac_addr"]
|
|
gateway = subnet['subnet']['gateway_ip']
|
|
vlan = network['network']['provider:segmentation_id']
|
|
dir_path = os.path.dirname(os.path.realpath(__file__))
|
|
file_path = os.path.join(dir_path, "scapy_icmp.py")
|
|
cmd = ["sudo", file_path, server_ip, server_mac, gateway, iface_mac, iface_name, str(vlan)]
|
|
proc = subprocess.Popen(cmd)
|
|
proc.wait()
|
|
if proc.returncode == 0:
|
|
self.log_info("Ping to {} is successful".format(server_ip))
|
|
else:
|
|
self.log_info("Ping to {} has failed".format(server_ip))
|
|
|
|
def provider_netcreate_nova_boot_ping(self, image, flavor, provider_phys_net, iface_name,
|
|
iface_mac, num_vms_provider_net, router_create_args=None,
|
|
network_create_args=None,
|
|
subnet_create_args=None,
|
|
**kwargs):
|
|
"""Create provider network, Boot and Ping VM
|
|
:param image: image ID or image name
|
|
:param flavor: flavor ID or flavor name
|
|
:param provider_phys_net: provider physical network
|
|
:param iface_name: interface name
|
|
:param iface_mac: interface MAC
|
|
:param num_vms_provider_net: int, number of vm's to create
|
|
:param router_create_args: dict, arguments for router creation
|
|
:param network_create_args: dict, arguments for network creation
|
|
:param subnet_create_args: dict, arguments for subnet creation
|
|
:param kwargs: dict, Keyword arguments to function
|
|
"""
|
|
|
|
provider_network = self._create_provider_network(provider_phys_net)
|
|
self.acquire_lock(provider_network['network']['id'])
|
|
subnet = self._create_subnet(provider_network, subnet_create_args or {})
|
|
kwargs["nics"] = [{'net-id': provider_network['network']['id']}]
|
|
tag = "provider_network:"+str(provider_network['network']['id'])
|
|
for _ in range(num_vms_provider_net):
|
|
server = self._boot_server_with_tag(image, flavor, tag, **kwargs)
|
|
self.log_info(" Server {} created on provider network {}".format(
|
|
server, provider_network))
|
|
self.ping_server(server, iface_name, iface_mac, provider_network, subnet)
|
|
self.release_lock(provider_network['network']['id'])
|
|
|
|
def pick_random_provider_net(self, provider_phys_net, **kwargs):
|
|
"""Picks random provider network that exists
|
|
:param provider_phys_net: provider physical network
|
|
:param kwargs: dict, Keyword arguments to function
|
|
"""
|
|
|
|
kwargs["provider:physical_network"] = provider_phys_net
|
|
kwargs["description"] = "dynwklds_provider_net"
|
|
nets = self._list_networks(**kwargs)
|
|
return self._show_provider_network({'network': random.choice(nets)})
|
|
|
|
def provider_net_nova_boot_ping(self, provider_phys_net, iface_name,
|
|
iface_mac, image, flavor, **kwargs):
|
|
"""Boot a VM on a random provider network that exists and Ping
|
|
:param provider_phys_net: provider physical network
|
|
:param iface_name: interface name
|
|
:param iface_mac: interface MAC
|
|
:param image: image ID or image name
|
|
:param flavor: flavor ID or flavor name
|
|
:param kwargs: dict, Keyword arguments to function
|
|
"""
|
|
|
|
random_network = self.pick_random_provider_net(provider_phys_net)
|
|
if random_network is None:
|
|
self.log_info("Network has already been deleted, cannot boot VMs on it")
|
|
return
|
|
if(not random_network['network']['subnets'] or
|
|
not self.acquire_lock(random_network['network']['id'])):
|
|
self.log_info("not booting new VMs on provider network {} as it is in-use".format(
|
|
random_network['network']['id']))
|
|
return
|
|
kwargs["nics"] = [{'net-id': random_network['network']['id']}]
|
|
tag = "provider_network:"+str(random_network['network']['id'])
|
|
server = self._boot_server_with_tag(image, flavor, tag, **kwargs)
|
|
subnet_id = random_network['network']['subnets'][0]
|
|
subnet = self.admin_clients("neutron").show_subnet(subnet_id)
|
|
self.ping_server(server, iface_name, iface_mac, random_network, subnet)
|
|
self.release_lock(random_network['network']['id'])
|
|
|
|
def provider_net_nova_delete(self, provider_phys_net, **kwargs):
|
|
"""Delete all the VM's on the provider network and then
|
|
the network.
|
|
:param provider_phys_net: provider physical network
|
|
:param kwargs: dict, Keyword arguments to function
|
|
"""
|
|
|
|
random_network = self.pick_random_provider_net(provider_phys_net)
|
|
if random_network is None:
|
|
self.log_info("Network has already been deleted")
|
|
return
|
|
if(not random_network['network']['subnets'] or
|
|
not self.acquire_lock(random_network['network']['id'])):
|
|
self.log_info("not deleting provider network {} as it is in-use".format(
|
|
random_network['network']['id']))
|
|
return
|
|
kwargs["nics"] = [{'net-id': random_network['network']['id']}]
|
|
tag = "provider_network:"+str(random_network['network']['id'])
|
|
servers = self._get_servers_by_tag(tag)
|
|
for server in servers:
|
|
self._delete_server(server)
|
|
self.log_info("Deleting provider network {}".format(random_network['network']['id']))
|
|
self._delete_provider_network(random_network)
|
|
self.release_lock(random_network['network']['id'])
|