d8ba5b7a81
1. In reviews we usually check import grouping but it is boring. By using flake8-import-order plugin, we can avoid this. It enforces loose checking so it sounds good to use it. This flake8 plugin is already used in tempest. Note that flake8-import-order version is pinned to avoid unexpected breakage of pep8 job. Setup for unit tests of hacking rules is tweaked to disable flake8-import-order checks. This extension assumes an actual file exists and causes hacking rule unit tests. 2. This patch is also intend to clean up exceptions to avoid confusing for other developers and the maintenance-ability as well. Change-Id: I032892f08e073feb5b822d27d092f041b17d57e1
650 lines
24 KiB
Python
650 lines
24 KiB
Python
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
|
#
|
|
# 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 os
|
|
import socket
|
|
import stat
|
|
import time
|
|
|
|
import paramiko
|
|
from rally.common import logging
|
|
from rally.plugins.openstack.wrappers import network as network_wrapper
|
|
from rally.task import utils as task_utils
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
SUBNET_IP_VERSION = 4
|
|
START_CIDR = "10.2.0.0/24"
|
|
EXT_NET_CIDR = "172.16.1.0/24"
|
|
|
|
|
|
def execute_cmd_over_ssh(host, cmd, private_key):
|
|
"""Run the given command over ssh
|
|
|
|
Using paramiko package, it creates a connection to the given host;
|
|
executes the required command on it and returns the output.
|
|
:param host: Dictionary of ip, username and password
|
|
:param cmd: Command to be run over ssh
|
|
:param private_key: path to private key file
|
|
:return: Output of the executed command
|
|
"""
|
|
LOG.debug('EXECUTE COMMAND <%s> OVER SSH', cmd)
|
|
client = paramiko.SSHClient()
|
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
k = paramiko.RSAKey.from_private_key_file(private_key)
|
|
|
|
try:
|
|
|
|
client.connect(host["ip"], username=host["username"], pkey=k)
|
|
except paramiko.BadHostKeyException as e:
|
|
raise Exception(
|
|
"BADHOSTKEY EXCEPTION WHEN CONNECTING TO %s", host["ip"], e)
|
|
except paramiko.AuthenticationException as e:
|
|
raise Exception(
|
|
"AUTHENTICATION EXCEPTION WHEN CONNECTING TO %s", host["ip"], e)
|
|
except paramiko.SSHException as e:
|
|
raise Exception("SSH EXCEPTION WHEN CONNECTING TO %s", host["ip"], e)
|
|
except socket.error as e:
|
|
raise Exception("SOCKET ERROR WHEN CONNECTING TO %s", host["ip"], e)
|
|
LOG.debug("CONNECTED TO HOST <%s>", host["ip"])
|
|
try:
|
|
stdin, stdout, stderr = client.exec_command(cmd)
|
|
return stdout.read().splitlines()
|
|
except paramiko.SSHException as e:
|
|
raise Exception("SSHEXCEPTION WHEN CONNECTING TO %s", host["ip"], e)
|
|
finally:
|
|
client.close()
|
|
|
|
|
|
def create_tenant(keystone_client, tenant_suffix):
|
|
"""Creates keystone tenant with a random name.
|
|
|
|
:param keystone_client: keystone client
|
|
:param tenant_suffix: suffix name for the tenant
|
|
:returns: uuid of the new tenant
|
|
"""
|
|
tenant_name = "rally_tenant_" + tenant_suffix
|
|
LOG.debug("CREATING NEW TENANT %s", tenant_name)
|
|
return keystone_client.tenants.create(tenant_name).id
|
|
|
|
|
|
def create_network(neutron_client, neutron_admin_client, network_suffix,
|
|
tenant_id=None, DVR_flag=True, ext_net_name=None):
|
|
"""Create neutron network, subnet, router
|
|
|
|
:param neutron_client: neutron client
|
|
:param neutron_admin_client: neutron client with admin credentials
|
|
:param network_suffix: str, suffix name of the new network
|
|
:param tenant_id: uuid of the tenant
|
|
:param DVR_flag: True - creates a DVR router
|
|
False - creates a non DVR router
|
|
:param ext_net_name: external network that is to be used
|
|
:return: router, subnet, network, subnet_cidr
|
|
"""
|
|
subnet_cidr = network_wrapper.generate_cidr(start_cidr=START_CIDR)
|
|
|
|
def _create_network(neutron_client, network_suffix, is_external=False):
|
|
"""Creates neutron network"""
|
|
|
|
network_name = "rally_network_" + network_suffix
|
|
network_args = {"name": network_name,
|
|
"router:external": is_external
|
|
}
|
|
if tenant_id:
|
|
network_args["tenant_id"] = tenant_id
|
|
LOG.debug("ADDING NEW NETWORK %s", network_name)
|
|
return neutron_client.create_network({"network": network_args})
|
|
|
|
def _create_subnet(neutron_client, rally_network, network_suffix, cidr):
|
|
"""Create neutron subnet"""
|
|
|
|
network_id = rally_network["network"]["id"]
|
|
subnet_name = "rally_subnet_" + network_suffix
|
|
subnet_args = {"name": subnet_name,
|
|
"cidr": cidr,
|
|
"network_id": network_id,
|
|
"ip_version": SUBNET_IP_VERSION
|
|
}
|
|
if tenant_id:
|
|
subnet_args["tenant_id"] = tenant_id
|
|
LOG.debug("ADDING SUBNET %s", subnet_name)
|
|
return neutron_client.create_subnet({"subnet": subnet_args})
|
|
|
|
def _create_router(neutron_client, ext_network_id, rally_subnet, dvr_flag):
|
|
"""Create router, set the external gateway and add router interface
|
|
|
|
:param neutron_client: neutron_client
|
|
:param ext_network_id: uuid of the external network
|
|
:param rally_subnet: subnet to add router interface
|
|
:param dvr_flag: True - creates a DVR router
|
|
False - creates a non DVR router
|
|
:return: router
|
|
"""
|
|
router_name = "rally_router_" + network_suffix
|
|
gw_info = {"network_id": ext_network_id}
|
|
router_args = {"name": router_name,
|
|
"external_gateway_info": gw_info
|
|
}
|
|
if not dvr_flag:
|
|
router_args["distributed"] = dvr_flag
|
|
if tenant_id:
|
|
router_args["tenant_id"] = 'tenant_id'
|
|
LOG.debug("ADDING ROUTER %s", router_name)
|
|
rally_router = neutron_client.create_router({"router": router_args})
|
|
|
|
LOG.debug("[%s]: ADDING ROUTER INTERFACE")
|
|
neutron_client.add_interface_router(
|
|
rally_router['router']["id"],
|
|
{"subnet_id": rally_subnet["subnet"]["id"]})
|
|
return rally_router
|
|
|
|
def _get_external_network_id(ext_net_name):
|
|
"""Fetch the network id for the given external network, if it exists.
|
|
Else fetch the first external network present.
|
|
"""
|
|
|
|
ext_nets = neutron_client.list_networks(
|
|
**{'router:external': True})['networks']
|
|
|
|
ext_nets_searched = [n for n in ext_nets if n['name'] == ext_net_name]
|
|
if ext_nets_searched:
|
|
return ext_nets_searched[0]['id']
|
|
elif ext_nets:
|
|
return ext_nets[0]['id']
|
|
else:
|
|
return None
|
|
|
|
def _create_external_network():
|
|
"""Creat external network and subnet"""
|
|
|
|
ext_net = _create_network(neutron_admin_client, "public", True)
|
|
_create_subnet(neutron_admin_client, ext_net, "public", EXT_NET_CIDR)
|
|
return ext_net['network']['id']
|
|
|
|
ext_network_id = _get_external_network_id(ext_net_name)
|
|
if not ext_network_id:
|
|
ext_network_id = _create_external_network()
|
|
rally_network = _create_network(neutron_client, network_suffix)
|
|
rally_subnet = _create_subnet(neutron_client, rally_network,
|
|
network_suffix, subnet_cidr)
|
|
rally_router = _create_router(neutron_client, ext_network_id,
|
|
rally_subnet, DVR_flag)
|
|
return rally_router, rally_network, rally_subnet, subnet_cidr
|
|
|
|
|
|
def create_keypair(nova_client, keypair_suffix):
|
|
"""Create keypair
|
|
|
|
:param nova_client: nova_client
|
|
:param keypair_suffix: sufix name for the keypair
|
|
:return: keypair
|
|
"""
|
|
keypair_name = "rally_keypair_" + keypair_suffix
|
|
LOG.debug("CREATING A KEYPAIR %s", keypair_name)
|
|
keypair = nova_client.keypairs.create(keypair_name)
|
|
return keypair
|
|
|
|
|
|
def write_key_to_local_path(keypair, local_key_file):
|
|
"""Write the private key of the nova instance to a temp file
|
|
|
|
:param keypair: nova keypair
|
|
:param local_key_file: path to private key file
|
|
:return:
|
|
"""
|
|
|
|
with open(local_key_file, 'w') as f:
|
|
os.chmod(local_key_file, stat.S_IREAD | stat.S_IWRITE)
|
|
f.write(keypair.private_key)
|
|
|
|
|
|
def write_key_to_compute_node(keypair, local_path, remote_path, host,
|
|
private_key):
|
|
"""Write the private key of the nova instance to the compute node
|
|
|
|
First fetches the private key from the keypair and writes it to a
|
|
temporary file in the local machine. It then sftp's the file
|
|
to the compute host.
|
|
|
|
:param keypair: nova keypair
|
|
:param local_path: path to private key file of the nova instance in the
|
|
local machine
|
|
:param remote_path: path where the private key file has to be placed
|
|
in the remote machine
|
|
:param host: compute host credentials
|
|
:param private_key: path to your private key file
|
|
:return:
|
|
"""
|
|
|
|
LOG.debug("WRITING PRIVATE KEY TO COMPUTE NODE")
|
|
k = paramiko.RSAKey.from_private_key_file(private_key)
|
|
write_key_to_local_path(keypair, local_path)
|
|
try:
|
|
transport = paramiko.Transport(host['ip'], host['port'])
|
|
except paramiko.SSHException as e:
|
|
raise Exception(
|
|
"PARAMIKO TRANSPORT FAILED. CHECK IF THE HOST IP %s AND PORT %s "
|
|
"ARE CORRECT %s", host['ip'], host['port'], e)
|
|
try:
|
|
transport.connect(
|
|
username=host['username'], pkey=k)
|
|
except paramiko.BadHostKeyException as e:
|
|
transport.close()
|
|
raise Exception(
|
|
"BADHOSTKEY EXCEPTION WHEN CONNECTING TO %s", host["ip"], e)
|
|
except paramiko.AuthenticationException as e:
|
|
transport.close()
|
|
raise Exception("AUTHENTICATION EXCEPTION WHEN CONNECTING TO %s",
|
|
host["ip"], e)
|
|
except paramiko.SSHException as e:
|
|
transport.close()
|
|
raise Exception("SSH EXCEPTION WHEN CONNECTING TO %s", host["ip"], e)
|
|
LOG.debug("CONNECTED TO HOST <%s>", host["ip"])
|
|
|
|
try:
|
|
sftp_client = paramiko.SFTPClient.from_transport(transport)
|
|
sftp_client.put(local_path, remote_path)
|
|
except IOError as e:
|
|
raise Exception("FILE PATH DOESN'T EXIST", e)
|
|
finally:
|
|
transport.close()
|
|
|
|
|
|
def create_server(nova_client, keypair, **kwargs):
|
|
"""Create nova instance
|
|
|
|
:param nova_client: nova client
|
|
:param keypair: key-pair to allow ssh
|
|
:return: new nova instance
|
|
"""
|
|
# add sec-group
|
|
sec_group_name = "rally_secgroup_" + kwargs["sec_group_suffix"]
|
|
LOG.debug("ADDING NEW SECURITY GROUP %s", sec_group_name)
|
|
secgroup = nova_client.security_groups.create(sec_group_name,
|
|
sec_group_name)
|
|
# add security rules for SSH and ICMP
|
|
nova_client.security_group_rules.create(secgroup.id, from_port=22,
|
|
to_port=22, ip_protocol="tcp", cidr="0.0.0.0/0")
|
|
|
|
nova_client.security_group_rules.create(secgroup.id, from_port=-1,
|
|
to_port=-1, ip_protocol="icmp", cidr="0.0.0.0/0")
|
|
|
|
# boot new nova instance
|
|
server_name = "rally_server_" + (kwargs["server_suffix"])
|
|
LOG.debug("BOOTING NEW INSTANCE: %s", server_name)
|
|
LOG.debug("%s", kwargs["image"])
|
|
server = nova_client.servers.create(server_name,
|
|
image=kwargs["image"],
|
|
flavor=kwargs["flavor"],
|
|
key_name=keypair.name,
|
|
security_groups=[secgroup.id],
|
|
nics=kwargs["nics"])
|
|
return server
|
|
|
|
|
|
def assert_server_status(server, **kwargs):
|
|
"""Assert server status
|
|
|
|
:param server: nova server
|
|
"""
|
|
|
|
LOG.debug('WAITING FOR SERVER TO GO ACTIVE')
|
|
server = task_utils.wait_for(
|
|
server,
|
|
is_ready=task_utils.resource_is("ACTIVE"),
|
|
update_resource=task_utils.get_from_manager(),
|
|
timeout=kwargs["nova_server_boot_timeout"],
|
|
check_interval=5)
|
|
LOG.debug("SERVER STATUS: %s", server.status)
|
|
assert('ACTIVE' == server.status), ("THE INSTANCE IS NOT IN ACTIVE STATE")
|
|
|
|
|
|
def get_server_ip(nova_client, server_id, network_suffix):
|
|
"""Get the ip associated with the nova instance
|
|
|
|
:param nova_client: nova client
|
|
:param server_id: uuid of the nova instance whose ip is required
|
|
:param network_suffix: suffix name of the network
|
|
:return: ip address of the instance
|
|
"""
|
|
network_name = "rally_network_" + network_suffix
|
|
server_details = nova_client.servers.get(server_id)
|
|
server_ip = server_details.addresses[network_name][0]["addr"]
|
|
return server_ip
|
|
|
|
|
|
def add_floating_ip(nova_client, server):
|
|
"""Associates floating-ip to a server
|
|
|
|
:param nova_client: nova client
|
|
:param server: nova instance
|
|
:return: associated floating ip
|
|
"""
|
|
|
|
fip_list = nova_client.floating_ips.list()
|
|
for fip in fip_list:
|
|
if fip.instance_id is None:
|
|
floating_ip = fip
|
|
break
|
|
else:
|
|
LOG.debug("CREATING NEW FLOATING IP")
|
|
floating_ip = nova_client.floating_ips.create()
|
|
LOG.debug("ASSOCIATING FLOATING IP %s", floating_ip.ip)
|
|
nova_client.servers.add_floating_ip(server.id, floating_ip.ip)
|
|
return floating_ip
|
|
|
|
|
|
def get_namespace(host, private_key):
|
|
"""SSH into the host and get the namespaces
|
|
|
|
:param host : dictionary of controller/compute node credentials
|
|
{ip:x.x.x.x, username:xxx, password:xxx}
|
|
:param private_key: path to private key file
|
|
:return: namespaces
|
|
"""
|
|
LOG.debug("GET NAMESPACES")
|
|
cmd = "sudo ip netns"
|
|
namespaces = execute_cmd_over_ssh(host, cmd, private_key)
|
|
LOG.debug("NAMESPACES %s", namespaces)
|
|
return namespaces
|
|
|
|
|
|
def wait_for_namespace_creation(namespace_tag, router_id, hosts, private_key,
|
|
timeout=60):
|
|
"""Wait for the namespace creation
|
|
|
|
Get into each of the controllers/compute nodes and check which one contains
|
|
the snat/qrouter namespace corresponding to rally_router. Sleep for a sec
|
|
and repeat until either the namespace is found or the namespace_creation_
|
|
time exceeded.
|
|
:param namespace_tag: which namespace ("snat_" or "qrouter_")
|
|
:param router_id: uuid of the rally_router
|
|
:param hosts: controllers or compute hosts
|
|
:param private_key: path to private key file
|
|
:param timeout: namespace creation time
|
|
:return:
|
|
"""
|
|
start_time = time.time()
|
|
while True:
|
|
for host in hosts:
|
|
namespaces = get_namespace(host, private_key)
|
|
for line in namespaces:
|
|
if line == (namespace_tag + router_id):
|
|
namespace_tag = line
|
|
return namespace_tag, host
|
|
time.sleep(1)
|
|
if time.time() - start_time > timeout:
|
|
raise Exception("TIMEOUT WHILE WAITING FOR"
|
|
" NAMESPACES TO BE CREATED")
|
|
|
|
|
|
def ping(host, cmd, private_key):
|
|
"""Execute ping command over ssh"""
|
|
ping_result = execute_cmd_over_ssh(host, cmd, private_key)
|
|
if ping_result:
|
|
LOG.debug("PING RESULT %s", ping_result)
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def ping_router_gateway(namespace_controller_tuple, router_gw_ip, private_key):
|
|
"""Ping the ip address from network namespace
|
|
|
|
Get into controller's snat-namespaces and ping the peer router gateway ip.
|
|
:param namespace_controller_tuple: namespace, controller tuple. (It's the
|
|
controller that contains the namespace )
|
|
:param router_gw_ip: ip address to be pinged
|
|
:param private_key: path to private key file
|
|
:return: True if ping succeeds
|
|
False if ping fails
|
|
"""
|
|
namespace, controller = namespace_controller_tuple
|
|
LOG.debug("PING %s FROM THE NAMESPACE %s", router_gw_ip, namespace)
|
|
count = 4
|
|
cmd = "sudo ip netns exec {} ping -w {} -c {} {}".format(
|
|
namespace, 2 * count, count, router_gw_ip)
|
|
return ping(controller, cmd, private_key)
|
|
|
|
|
|
def get_interfaces(namespace_controller_tuple, private_key):
|
|
"""Get the interfaces
|
|
|
|
Get into the controller's snat namespace and list the interfaces.
|
|
:param namespace_controller_tuple: namespace, controller tuple(the
|
|
controller that contains the namespace).
|
|
:param private_key: path to private key file
|
|
:return: interfaces
|
|
"""
|
|
namespace, controller = namespace_controller_tuple
|
|
LOG.debug("GET THE INTERFACES BY USING 'ip a' FROM THE NAMESPACE %s",
|
|
namespace)
|
|
cmd = "sudo ip netns exec {} ip a".format(namespace)
|
|
interfaces = execute_cmd_over_ssh(controller, cmd, private_key)
|
|
LOG.debug("INTERFACES %s", interfaces)
|
|
return interfaces
|
|
|
|
|
|
def start_tcpdump(namespace_controller_tuple, interface, private_key):
|
|
"""Start the tcpdump at the given interface
|
|
|
|
Get into the controller's snat namespace and start a tcp dump at the
|
|
qg-interface.
|
|
:param namespace_controller_tuple: namespace, controller tuple. (It's the
|
|
controller that contains the namespace )
|
|
:param interface: interface in which tcpdump has to be run
|
|
:param private_key: path to private key file
|
|
:return: tcpdump output
|
|
"""
|
|
namespace, controller = namespace_controller_tuple
|
|
LOG.debug("START THE TCPDUMP USING 'tcpdump -i %s FROM THE NAMESPACE"
|
|
" %s", interface, namespace)
|
|
cmd = ("sudo ip netns exec {} timeout 15 tcpdump -n -i {}"
|
|
.format(namespace, interface))
|
|
tcpdump = execute_cmd_over_ssh(controller, cmd, private_key)
|
|
LOG.debug("TCPDUMP %s", tcpdump)
|
|
return tcpdump
|
|
|
|
|
|
def ssh_and_ping_server(local_server, peer_server, ns_compute_tuple, keyfile,
|
|
private_key):
|
|
"""SSH and ping the nova instance from the namespace
|
|
|
|
Get into the compute node's qrouter namespace and then ssh into the local
|
|
nova instance & ping the peer nova instance.
|
|
:param local_server: private ip of the server to ssh into
|
|
:param peer_server: private ip of the server to ping to
|
|
:param ns_compute_tuple: namespace, compute tuple. (It's the
|
|
compute node that contains the namespace )
|
|
:param keyfile: path to private key file of the nova instance
|
|
:param private_key: path to private key file
|
|
:return: True if ping succeeds
|
|
False if ping fails
|
|
"""
|
|
namespace, compute_host = ns_compute_tuple
|
|
LOG.debug("SSH INTO SERVER %s AND PING THE PEER SERVER %s FROM THE"
|
|
" NAMESPACE %s", local_server, peer_server, namespace)
|
|
host = "cirros@" + local_server
|
|
count = 20
|
|
cmd = ("sudo ip netns exec {} ssh -v -o StrictHostKeyChecking=no -o"
|
|
"HashKnownHosts=no -i {} {} ping -w {} -c {} {}"
|
|
.format(namespace, keyfile, host, 2 * count, count, peer_server))
|
|
return ping(compute_host, cmd, private_key)
|
|
|
|
|
|
def ssh_and_ping_server_with_fip(local_server, peer_server, keyfile,
|
|
private_key):
|
|
"""SSH into the local nova instance and ping the peer instance using fips
|
|
|
|
:param local_server: fip of the server to ssh into
|
|
:param peer_server: private ip of the server to ping to
|
|
:param keyfile: path to private key file of the nova instance
|
|
:param private_key: path to private key file
|
|
:return: True if ping succeeds
|
|
False if ping fails
|
|
"""
|
|
LOG.debug("SSH INTO LOCAL SERVER %s AND PING THE PEER SERVER %s",
|
|
local_server.ip, peer_server)
|
|
count = 20
|
|
local_host = {"ip": "127.0.0.1", "username": None}
|
|
host = "cirros@" + local_server.ip
|
|
cmd = ("ssh -v -o StrictHostKeyChecking=no -o"
|
|
"HashKnownHosts=no -i {} {} ping -w {} -c {} {}"
|
|
.format(keyfile, host, 2 * count, count, peer_server))
|
|
return ping(local_host, cmd, private_key)
|
|
|
|
|
|
def delete_servers(nova_client, servers):
|
|
"""Delete nova servers
|
|
|
|
It deletes the nova servers, associated security groups.
|
|
|
|
:param nova_client: nova client
|
|
:param servers: nova instances to be deleted
|
|
:return:
|
|
"""
|
|
for server in servers:
|
|
LOG.debug("DELETING NOVA INSTANCE: %s", server.id)
|
|
sec_group_id = server.security_groups[0]['name']
|
|
nova_client.servers.delete(server.id)
|
|
|
|
LOG.debug("WAITING FOR INSTANCE TO GET DELETED")
|
|
task_utils.wait_for_delete(
|
|
server, update_resource=task_utils.get_from_manager())
|
|
|
|
for secgroup in nova_client.security_groups.list():
|
|
if secgroup.id == sec_group_id:
|
|
LOG.debug("DELETING SEC_GROUP: %s", sec_group_id)
|
|
nova_client.security_groups.delete(secgroup.id)
|
|
|
|
|
|
def delete_floating_ips(nova_client, fips):
|
|
"""Delete floating ips
|
|
|
|
:param nova_client: nova client
|
|
:param fips: list of floating ips
|
|
:return:
|
|
"""
|
|
for fip in fips:
|
|
nova_client.floating_ips.delete(fip.id)
|
|
|
|
|
|
def delete_keypairs(nova_client, keypairs):
|
|
"""Delete key pairs
|
|
|
|
:param nova_client: nova client
|
|
:param keypairs: list of keypairs
|
|
:return
|
|
"""
|
|
for key_pair in keypairs:
|
|
LOG.debug("DELETING KEY_PAIR %s", key_pair.name)
|
|
nova_client.keypairs.delete(key_pair.id)
|
|
|
|
|
|
def delete_networks(neutron_client, neutron_admin_client,
|
|
routers, networks, subnets):
|
|
"""Delete neutron network, subnets amd routers
|
|
|
|
:param neutron_client: neutron client
|
|
:param neutron_admin_client: neutron_admin_client
|
|
:param routers: list of routers to be deleted
|
|
:param networks: list of networks to be deleted
|
|
:param subnets: list of subnets to be deleted
|
|
:return
|
|
"""
|
|
LOG.debug("DELETING RALLY ROUTER INTERFACES & GATEWAYS")
|
|
for router in routers:
|
|
neutron_client.remove_gateway_router(router['router']['id'])
|
|
router_name = router['router']['name']
|
|
subnet_name = ("rally_subnet_" + router_name[13:len(router_name)])
|
|
for subnet in subnets:
|
|
if subnet_name == subnet['subnet']['name']:
|
|
neutron_client.remove_interface_router(
|
|
router['router']['id'],
|
|
{"subnet_id": subnet['subnet']['id']})
|
|
|
|
LOG.debug("DELETING RALLY ROUTERS")
|
|
for router in routers:
|
|
neutron_client.delete_router(router['router']['id'])
|
|
|
|
LOG.debug("DELETING RALLY NETWORKS")
|
|
for network in networks:
|
|
if (network['network']['router:external'] and
|
|
network['network']['name'] == "rally_network_public"):
|
|
external_network = network
|
|
neutron_admin_client.delete_network(
|
|
external_network['network']["id"])
|
|
elif network['network']['router:external']:
|
|
pass
|
|
else:
|
|
neutron_client.delete_network(network['network']['id'])
|
|
|
|
|
|
def delete_tenants(keystone_client, tenant_ids):
|
|
"""Delete keystone tenant
|
|
|
|
:param keystone_client: keystone client
|
|
:param tenant_ids: list of tenants' uuids
|
|
:returns: delete keystone tenant instance
|
|
"""
|
|
LOG.debug('DELETE TENANTS')
|
|
for id in tenant_ids:
|
|
keystone_client.tenants.delete(id)
|
|
|
|
|
|
def delete_keyfiles(local_key_files, remote_key_files=None,
|
|
ns_compute_tuples=None, private_key=None):
|
|
"""Delete the SSH keyfiles from the compute and the local nodes
|
|
|
|
:param local_key_files: paths to ssh key files in local node
|
|
:param remote_key_files: paths to ssh key files in compute nodes
|
|
:param ns_compute_tuples: namespace, compute tuple. (It's the
|
|
compute node that contains the namespace )
|
|
:param private_key: path to private key file
|
|
:return:
|
|
"""
|
|
LOG.debug("DELETING RALLY KEY FILES FROM LOCAL MACHINE")
|
|
for key in local_key_files:
|
|
if os.path.exists(key):
|
|
os.remove(key)
|
|
|
|
if ns_compute_tuples:
|
|
LOG.debug("DELETING RALLY KEY FILES FROM COMPUTE HOSTS")
|
|
for key, ns_comp in zip(remote_key_files, ns_compute_tuples):
|
|
cmd = "sudo rm -f {}".format(key)
|
|
host = ns_comp[1]
|
|
execute_cmd_over_ssh(host, cmd, private_key)
|
|
|
|
|
|
def delete_hosts_from_knownhosts_file(hosts, ns_compute_tuples=None,
|
|
private_key=None):
|
|
"""Remove the hosts from the knownhosts file
|
|
|
|
:param hosts: host ips to be removed from /root/.ssh/knownhosts
|
|
:param ns_compute_tuples: namespace, compute tuple. (It's the
|
|
compute node that contains the namespace )
|
|
:param private_key: path to private key file
|
|
:return:
|
|
"""
|
|
if ns_compute_tuples:
|
|
LOG.debug("DELETES HOSTS FROM THE KNOWNHOSTS FILE")
|
|
for host, ns_comp in zip(hosts, ns_compute_tuples):
|
|
compute_host = ns_comp[1]
|
|
cmd = ("sudo ssh-keygen -f /root/.ssh/known_hosts -R"
|
|
" {}".format(host))
|
|
execute_cmd_over_ssh(compute_host, cmd, private_key)
|
|
else:
|
|
for host in hosts:
|
|
os.system("sudo ssh-keygen -f /root/.ssh/known_hosts -R"
|
|
" {}".format(host))
|