00ef4b0867
As discussed at the Epoxy PTG meeting, run an automated upgrade tool to make code python 3.9+ compliant. This patch is for pylint. Result of running: $ pyupgrade --py39-plus $(git ls-files | grep ".py$") Fixed PEP8 errors introduced by pyupgrade by running: $ autopep8 --select=E127,E128,E501 --max-line-length 79 -r \ --in-place neutron_vpnaas Also did manual updates as necessary to fix other errors and warnings after above commands. Inspired by Octavia and Nova [0]. [0] https://review.opendev.org/c/openstack/nova/+/896986 Change-Id: I610efe1a9f20a2a799c40bcf62b98e65e70f0982
649 lines
24 KiB
Python
649 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 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 OSError 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 OSError 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 = f"sudo ip netns exec {namespace} ip a"
|
|
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 = f"sudo rm -f {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))
|