VPNaaS Scenario tests using Rally
Introducing VPNaaS scenario tests using Rally. This patch contains rally-jobs/plugins/vpn_utils.py file that holds a few utility functions that will be used by the actual test files. Change-Id: I01aa18be580211f1013a2203d69dc8bd2200c514
This commit is contained in:
parent
c574a40c59
commit
163332fd8c
0
rally-jobs/__init__.py
Normal file
0
rally-jobs/__init__.py
Normal file
0
rally-jobs/plugins/__init__.py
Normal file
0
rally-jobs/plugins/__init__.py
Normal file
773
rally-jobs/plugins/vpn_utils.py
Normal file
773
rally-jobs/plugins/vpn_utils.py
Normal file
@ -0,0 +1,773 @@
|
||||
# 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 concurrent.futures
|
||||
import exceptions
|
||||
import os
|
||||
from oslo_config import cfg
|
||||
import re
|
||||
import stat
|
||||
import time
|
||||
|
||||
|
||||
def noop(*args, **kwargs):
|
||||
pass
|
||||
cfg.CONF.register_cli_opts = noop
|
||||
|
||||
from neutron.agent.linux import ip_lib
|
||||
from neutron.agent.linux import utils as linux_utils
|
||||
from rally.common import log as logging
|
||||
from rally.plugins.openstack import scenario
|
||||
from rally.task import utils as task_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class VpnUtils(scenario.OpenStackScenario):
|
||||
"""Utility class for VPNaaS scenarios with basic atomic actions."""
|
||||
SUBNET_IP_VERSION = 4
|
||||
|
||||
def _create_network(self, neutron_client, network_suffix, cidr):
|
||||
"""Create neutron network
|
||||
|
||||
:param neutron_client: neutron client
|
||||
:param network_suffix: str, suffix name of the new network
|
||||
:param cidr: subnet cidr
|
||||
:return: router, subnet , network
|
||||
"""
|
||||
def create_network(neutron_client, network_suffix, isExternal=False):
|
||||
network_name = "rally_network_" + network_suffix
|
||||
network_args = {"name": network_name,
|
||||
"router:external": isExternal}
|
||||
|
||||
LOG.debug("ADDING NEW NETWORK: %s", network_name)
|
||||
rally_network = neutron_client.create_network(
|
||||
{"network": network_args})
|
||||
return rally_network
|
||||
|
||||
def create_subnet(neutron_client, rally_network, network_suffix, cidr):
|
||||
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": self.SUBNET_IP_VERSION}
|
||||
|
||||
LOG.debug("ADDING SUBNET: %s", subnet_name)
|
||||
rally_subnet = neutron_client.create_subnet(
|
||||
{"subnet": subnet_args})
|
||||
return rally_subnet
|
||||
|
||||
def create_router(private_subnet, public_network_id):
|
||||
router_name = "rally_router_" + network_suffix
|
||||
gw_info = {"network_id": public_network_id}
|
||||
router_args = {"name": router_name,
|
||||
"external_gateway_info": gw_info}
|
||||
|
||||
LOG.debug("ADDING ROUTER: %s", router_name)
|
||||
rally_router = neutron_client.create_router(
|
||||
{"router": router_args})
|
||||
|
||||
# create router interface - connect subnet to it
|
||||
LOG.debug("ADDING ROUTER INTERFACE")
|
||||
neutron_client.add_interface_router(
|
||||
rally_router['router']["id"],
|
||||
{"subnet_id": private_subnet["subnet"]["id"]})
|
||||
return rally_router
|
||||
|
||||
# check for external network and create one if not found
|
||||
def get_external_network():
|
||||
for network in neutron_client.list_networks()['networks']:
|
||||
if network['router:external']:
|
||||
public_network_id = network['id']
|
||||
LOG.debug("PUBLIC NETWORK ALREADY EXISTS")
|
||||
break
|
||||
else:
|
||||
public_network = create_network(self.admin_clients("neutron"),
|
||||
"public", True)
|
||||
create_subnet(self.admin_clients("neutron"), public_network,
|
||||
"public", "172.16.1.0/24")
|
||||
public_network_id = public_network['network']['id']
|
||||
return public_network_id
|
||||
|
||||
# create public network_id
|
||||
public_network_id = get_external_network()
|
||||
# create private network
|
||||
private_network = create_network(neutron_client, network_suffix)
|
||||
# create subnet
|
||||
private_subnet = create_subnet(neutron_client,
|
||||
private_network,
|
||||
network_suffix,
|
||||
cidr)
|
||||
# create router
|
||||
rally_router = create_router(private_subnet, public_network_id)
|
||||
|
||||
return rally_router, private_network, private_subnet
|
||||
|
||||
def _create_keypair(self, nova_client, key_name, key_file):
|
||||
"""Create keypair
|
||||
|
||||
:param nova_client: nova_client
|
||||
:param key_name: key_name
|
||||
:param key_file: key_file_name
|
||||
:return: keypair
|
||||
"""
|
||||
LOG.debug("ADDING NEW KEYPAIR")
|
||||
keypair = nova_client.keypairs.create(key_name)
|
||||
f = open(key_file, 'w')
|
||||
os.chmod(key_file, stat.S_IREAD | stat.S_IWRITE)
|
||||
f.write(keypair.private_key)
|
||||
f.close()
|
||||
return keypair
|
||||
|
||||
def _create_nova_vm(self, nova_client, keypair, **kwargs):
|
||||
"""Create nova instance
|
||||
|
||||
:param nova_client: nova client
|
||||
:param keypair: str, key-pair to allow ssh
|
||||
:return: new nova instance
|
||||
"""
|
||||
# add sec-group
|
||||
sec_group_suffix = "rally_secgroup_" + kwargs["sec_group_suffix"]
|
||||
LOG.debug("ADDING NEW SECURITY GROUP %s", sec_group_suffix)
|
||||
secgroup = nova_client.security_groups.create(sec_group_suffix,
|
||||
sec_group_suffix)
|
||||
# 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)
|
||||
|
||||
server = nova_client.servers.create(server_name,
|
||||
image=kwargs["image"],
|
||||
flavor=kwargs["flavor"],
|
||||
key_name=keypair.name,
|
||||
security_groups=[secgroup.id],
|
||||
nics=kwargs["nics"])
|
||||
# wait for instance to become active
|
||||
LOG.debug("WAITING FOR INSTANCE TO BECOME 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 if instance is 'active'
|
||||
assert('ACTIVE' == server.status), (
|
||||
"THE INSTANCE IS NOT IN ACTIVE STATE")
|
||||
return server
|
||||
|
||||
def _get_server_ip(self, nova_client, server_id, network_suffix):
|
||||
"""
|
||||
|
||||
:param nova_client: nova client
|
||||
:param nova_id: uuid of the nova instance whose ip is wanted
|
||||
:param network_suffix: network name suffix
|
||||
: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 _create_ike_policy(self,
|
||||
neutron_client,
|
||||
**kwargs):
|
||||
"""Creates IKE policy
|
||||
|
||||
:param neutron_client:neutron client
|
||||
:return:created ike_policy
|
||||
"""
|
||||
LOG.debug("CREATING IKE_POLICY")
|
||||
ike_policy = neutron_client.create_ikepolicy({
|
||||
"ikepolicy": {
|
||||
"phase1_negotiation_mode":
|
||||
kwargs["phase1_negotiation_mode"] or "main",
|
||||
"auth_algorithm": kwargs["auth_algorithm"] or "sha1",
|
||||
"encryption_algorithm":
|
||||
kwargs["encryption_algorithm"] or "aes-128",
|
||||
"pfs": kwargs["pfs"] or "group5",
|
||||
"lifetime": {
|
||||
"units": "seconds",
|
||||
"value": kwargs["value"] or 7200},
|
||||
"ike_version": kwargs["ike_version"] or "v1",
|
||||
"name": "rally_ikepolicy"
|
||||
}
|
||||
})
|
||||
return ike_policy
|
||||
|
||||
def _create_ipsec_policy(self,
|
||||
neutron_client,
|
||||
**kwargs):
|
||||
"""Creates IPSEC policy
|
||||
|
||||
:param neutron_client: neutron client
|
||||
:return: created IPSEC policy
|
||||
"""
|
||||
LOG.debug("CREATING IPSEC_POLICY")
|
||||
ipsec_policy = neutron_client.create_ipsecpolicy({
|
||||
"ipsecpolicy": {
|
||||
"name": "rally_ipsecpolicy",
|
||||
"transform_protocol": kwargs["transform_protocol"] or "esp",
|
||||
"auth_algorithm": kwargs["auth_algorithm"] or "sha1",
|
||||
"encapsulation_mode": kwargs["encapsulation_mode"] or "tunnel",
|
||||
"encryption_algorithm":
|
||||
kwargs["encryption_algorithm"] or "aes-128",
|
||||
"pfs": kwargs["pfs"] or "group5",
|
||||
"lifetime": {
|
||||
"units": "seconds",
|
||||
"value": kwargs["value"] or 7200
|
||||
}
|
||||
}
|
||||
})
|
||||
return ipsec_policy
|
||||
|
||||
def _create_vpn_service(self, neutron_client, rally_subnet, rally_router,
|
||||
name=None):
|
||||
"""Creates VPN service endpoints
|
||||
|
||||
:param neutron_client: neutron client
|
||||
:param name: name of vpn service
|
||||
:param rally_subnet: local subnet
|
||||
:param rally_router: router endpoint
|
||||
:param admin_state_up: admin state of the vpn_service
|
||||
:return: vpn_service
|
||||
"""
|
||||
LOG.debug("CREATING VPN_SERVICE")
|
||||
vpn_service = neutron_client.create_vpnservice({
|
||||
"vpnservice": {
|
||||
"subnet_id": rally_subnet["subnet"]["id"],
|
||||
"router_id": rally_router["router"]["id"],
|
||||
"name": "rally_vpn_service_" + name,
|
||||
"admin_state_up": True
|
||||
}
|
||||
})
|
||||
return vpn_service
|
||||
|
||||
def _create_ipsec_site_connection(
|
||||
self, neutron_client, ike_policy,
|
||||
ipsec_policy, peer_cidrs,
|
||||
peer_id, peer_address,
|
||||
vpn_service, name=None,
|
||||
mtu=None, secret=None):
|
||||
"""Creates IPSEC site connections
|
||||
|
||||
:param neutron_client: neutron client
|
||||
:param ike_policy: ikepolicy
|
||||
:param ipsec_policy: ipsecpolicy
|
||||
:param peer_cidrs: list of peer cidrs
|
||||
:param peer_id: peer_id
|
||||
:param peer_address: peer_address
|
||||
:param vpn_service: vpn_service
|
||||
:param secret: pre shared secret
|
||||
:param admin_state_up: admin state of the ipsec site connections
|
||||
:param mtu: max transmission unit
|
||||
:param name: name of the ipsec site connections
|
||||
:return:ipsec_site_connection
|
||||
"""
|
||||
LOG.debug("CREATING IPSEC_SITE_CONNECTION")
|
||||
ipsec_site_connection = neutron_client.create_ipsec_site_connection({
|
||||
"ipsec_site_connection": {
|
||||
"psk": secret or "secret",
|
||||
"initiator": "bi-directional",
|
||||
"ipsecpolicy_id": ipsec_policy["ipsecpolicy"]["id"],
|
||||
"admin_state_up": True,
|
||||
"peer_cidrs": peer_cidrs,
|
||||
"mtu": mtu or "1500",
|
||||
"ikepolicy_id": ike_policy["ikepolicy"]["id"],
|
||||
"dpd": {
|
||||
"action": "disabled",
|
||||
"interval": 60,
|
||||
"timeout": 240
|
||||
},
|
||||
"vpnservice_id": vpn_service["vpnservice"]["id"],
|
||||
"peer_address": peer_address,
|
||||
"peer_id": peer_id,
|
||||
"name": "rally_ipsec_site_connection_" + name
|
||||
}
|
||||
})
|
||||
return ipsec_site_connection
|
||||
|
||||
def _get_resource(self, resource_tag, resource_id):
|
||||
"""Gets the resource(vpn_service or ipsec_site_connection)
|
||||
|
||||
:param resource_tag: "vpnservice" or "ipsec_site_connection"
|
||||
:param resource_id: id of the resource
|
||||
:return:
|
||||
"""
|
||||
neutron_client = self.clients("neutron")
|
||||
if resource_tag == "vpnservice":
|
||||
vpn_service = neutron_client.show_vpnservice(resource_id)
|
||||
if vpn_service:
|
||||
return vpn_service
|
||||
elif resource_tag == 'ipsec_site_connection':
|
||||
ipsec_site_connection = neutron_client.show_ipsec_site_connection(
|
||||
resource_id)
|
||||
if ipsec_site_connection:
|
||||
return ipsec_site_connection
|
||||
|
||||
def _wait_for_status_change(self, resource, final_status,
|
||||
resource_tag, wait_timeout=60,
|
||||
check_interval=1):
|
||||
"""Wait for resource's status change
|
||||
|
||||
Wait till the status of the resource changes to final state or till
|
||||
the time exceeds the wait_timeout value.
|
||||
:param resource: resource whose status has to be checked
|
||||
:param final_status: desired final status of the resource
|
||||
:param resource_tag: to identify the resource as vpnservice or
|
||||
ipser_site_connection
|
||||
:param wait_timeout: timeout value in seconds
|
||||
:param check_interval: time to sleep before each check for the status
|
||||
change
|
||||
:return: resource
|
||||
"""
|
||||
start_time = time.time()
|
||||
while True:
|
||||
resource = self._get_resource(
|
||||
resource_tag,
|
||||
resource[resource_tag]['id'])
|
||||
current_status = resource[resource_tag]['status']
|
||||
if current_status == final_status:
|
||||
return resource
|
||||
time.sleep(check_interval)
|
||||
if time.time() - start_time > wait_timeout:
|
||||
self._cleanup(called_from="VpnUtils._wait_for_status_change")
|
||||
raise exceptions.Exception("Timeout while waiting for status "
|
||||
"change to %s.", final_status)
|
||||
|
||||
def _assert_statuses(self, vpn_service, ipsec_site_connection,
|
||||
ipsec_site_connection_creation_timeout=60,
|
||||
vpn_service_creation_timeout=60):
|
||||
"""Assert statuses of vpn_service and ipsec_site_connection
|
||||
|
||||
:param vpn_service: vpn_service
|
||||
:param ipsec_site_connection: ipsec_site_connection
|
||||
:param ipsec_site_connection_creation_timeout: timeout in seconds
|
||||
:param vpn_service_creation_timeout: timeout in seconds
|
||||
:return:
|
||||
"""
|
||||
|
||||
vpn_service = self._wait_for_status_change(
|
||||
vpn_service,
|
||||
resource_tag="vpnservice",
|
||||
final_status="ACTIVE",
|
||||
wait_timeout=vpn_service_creation_timeout,
|
||||
check_interval=5)
|
||||
LOG.debug("VPN-SERVICE STATUS: %s",
|
||||
vpn_service['vpnservice']['status'])
|
||||
|
||||
assert('ACTIVE' == vpn_service['vpnservice']['status']), (
|
||||
"VPN_SERVICE IS NOT IN ACTIVE STATE")
|
||||
|
||||
ipsec_site_connection = self._wait_for_status_change(
|
||||
ipsec_site_connection,
|
||||
resource_tag="ipsec_site_connection",
|
||||
final_status="ACTIVE",
|
||||
wait_timeout=ipsec_site_connection_creation_timeout,
|
||||
check_interval=5)
|
||||
LOG.debug("IPSEC_SITE_CONNECTION STATUS: %s",
|
||||
ipsec_site_connection['ipsec_site_connection']['status'])
|
||||
|
||||
assert('ACTIVE' ==
|
||||
ipsec_site_connection['ipsec_site_connection']['status']), (
|
||||
"THE INSTANCE IS NOT IN ACTIVE STATE")
|
||||
|
||||
def _verify_vpn_connectivity(self, server_ips, snat_namespaces,
|
||||
qrouter_namespaces, key_file_names,
|
||||
first, second):
|
||||
"""Verifies the vpn connectivity between the endpoints
|
||||
|
||||
:param server_ips: list of private ips of the servers between
|
||||
which the vpn connectivity has to verified.
|
||||
:param snat_namespaces: snat_namespaces of the 2 routers
|
||||
:param qrouter_namespaces: qrouter_namespaces of the 2 routers
|
||||
:param key_file_names: path to private key files
|
||||
:param first: parameter to point to the self
|
||||
:param second: parameter to point to the peer
|
||||
:return: True or False
|
||||
"""
|
||||
LOG.debug("VERIFY THE VPN CONNECTIVITY")
|
||||
qg = self._get_interfaces(snat_namespaces[second])
|
||||
if qg:
|
||||
p = re.compile(r"qg-\w+-\w+")
|
||||
m = p.search(qg)
|
||||
if m:
|
||||
qg_interface = m.group()
|
||||
else:
|
||||
qg_interface = None
|
||||
|
||||
if qg_interface:
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as e:
|
||||
tcpdump_future = e.submit(self._start_tcpdump,
|
||||
snat_namespaces[second],
|
||||
qg_interface)
|
||||
ssh_future = e.submit(self._ssh_and_ping_server,
|
||||
server_ips[first],
|
||||
server_ips[second],
|
||||
qrouter_namespaces[first],
|
||||
key_file_names[first])
|
||||
assert(True == ssh_future.result()), "SSH/Ping failed"
|
||||
lines = tcpdump_future.result().split('\n')
|
||||
for line in lines:
|
||||
if 'ESP' in line:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _get_namespace(self):
|
||||
"""Get namespaces
|
||||
|
||||
:return: namespaces
|
||||
"""
|
||||
LOG.debug("GET NAMESPACES USING 'ip netns'")
|
||||
try:
|
||||
cmd = ['ip', 'netns']
|
||||
cmd = ip_lib.add_namespace_to_cmd(cmd)
|
||||
namespaces = linux_utils.execute(cmd)
|
||||
LOG.debug("%s", namespaces)
|
||||
return namespaces
|
||||
except RuntimeError:
|
||||
return None
|
||||
|
||||
def _wait_for_namespace_creation(self, namespace, rally_router):
|
||||
"""Wait for namespace creation
|
||||
|
||||
:param namespace: snat/qrouter namespace
|
||||
:param rally_router: rally_router
|
||||
:return:
|
||||
"""
|
||||
start_time = time.time()
|
||||
while True:
|
||||
namespaces = self._get_namespace().split()
|
||||
for line in namespaces:
|
||||
if line == (namespace + rally_router["router"]["id"]):
|
||||
namespace = line
|
||||
return namespace
|
||||
time.sleep(1)
|
||||
if time.time() - start_time > 20:
|
||||
self._cleanup(called_from="_wait_for_namespace_creation")
|
||||
raise exceptions.Exception("Timeout while waiting for"
|
||||
" namespaces to be created")
|
||||
|
||||
def _ping(self, namespace, ip):
|
||||
"""Pings ip address from network namespace.
|
||||
|
||||
In order to ping it uses following cli command:
|
||||
ip netns exec <namespace> ping -c 4 -q <ip>
|
||||
:param namespace: namespace
|
||||
:param ip: ip to ping to
|
||||
"""
|
||||
LOG.debug("PING %s FROM THE NAMESPACE %s", ip, namespace)
|
||||
try:
|
||||
count = 4
|
||||
cmd = ['ping', '-w', 2 * count, '-c', count, ip]
|
||||
cmd = ip_lib.add_namespace_to_cmd(cmd, namespace)
|
||||
ping_result = linux_utils.execute(cmd, run_as_root=True)
|
||||
LOG.debug("%s", ping_result)
|
||||
return True
|
||||
|
||||
except RuntimeError:
|
||||
return False
|
||||
|
||||
def _get_interfaces(self, namespace):
|
||||
"""Do an "ip a".
|
||||
|
||||
In order to do "ip a" it uses following cli command:
|
||||
ip netns exec <namespace> ip a | grep qg
|
||||
:param namespace: namespace
|
||||
"""
|
||||
LOG.debug("GET THE INTERFACES BY USING 'ip a' FROM THE NAMESPACE %s",
|
||||
namespace)
|
||||
try:
|
||||
cmd = ['ip', 'a']
|
||||
cmd = ip_lib.add_namespace_to_cmd(cmd, namespace)
|
||||
interfaces = linux_utils.execute(cmd, run_as_root=True)
|
||||
LOG.debug("%s", interfaces)
|
||||
return interfaces
|
||||
|
||||
except RuntimeError:
|
||||
return None
|
||||
|
||||
def _start_tcpdump(self, namespace, interface):
|
||||
"""Starts tcpdump at the given interface
|
||||
|
||||
In order to start a "tcpdump" it uses the following command:
|
||||
ip netns exec <namespace> sudo tcpdump -i <interface>
|
||||
:param namespace: namespace
|
||||
:param interface: interface
|
||||
:return:
|
||||
"""
|
||||
LOG.debug("START THE TCPDUMP USING 'tcpdump -i <%s> FROM THE NAMESPACE"
|
||||
" %s", interface, namespace)
|
||||
try:
|
||||
cmd = ['timeout', '10', 'tcpdump', '-n',
|
||||
'-i', interface]
|
||||
cmd = ip_lib.add_namespace_to_cmd(cmd, namespace)
|
||||
tcpdump = linux_utils.execute(cmd, run_as_root=True,
|
||||
extra_ok_codes=[124])
|
||||
LOG.debug("%s", tcpdump)
|
||||
return tcpdump
|
||||
|
||||
except RuntimeError:
|
||||
return None
|
||||
|
||||
def _ssh_and_ping_server(self, ssh_server, ping_server,
|
||||
namespace, key_file_name):
|
||||
"""Ssh into the server from the namespace.
|
||||
|
||||
In order to ssh it uses the following command:
|
||||
ip netns exec <namespace> ssh -i <path to keyfile> cirros@<server_ip>
|
||||
:param ssh_server: ip of the server to ssh into
|
||||
:param ping_server: ip of the server to ping to
|
||||
:param namespace: qrouter namespace
|
||||
:param key_file_name: path to private key file
|
||||
:return:
|
||||
"""
|
||||
LOG.debug("SSH INTO SERVER %s AND PING THE PEER SERVER %s FROM THE"
|
||||
" NAMESPACE %s", ssh_server, ping_server, namespace)
|
||||
try:
|
||||
# ssh instance
|
||||
host = "cirros@" + ssh_server
|
||||
count = 20
|
||||
cmd = ['ssh', '-o', 'StrictHostKeyChecking=no',
|
||||
'-i', key_file_name, host,
|
||||
'ping', '-w',
|
||||
2 * count, '-c', count, ping_server]
|
||||
cmd = ip_lib.add_namespace_to_cmd(cmd, namespace)
|
||||
ping_result = linux_utils.execute(cmd, run_as_root=True)
|
||||
LOG.debug("%s", ping_result)
|
||||
return True
|
||||
|
||||
except RuntimeError:
|
||||
return False
|
||||
|
||||
def _delete_server(self, nova_client, server):
|
||||
"""Delete nova instance
|
||||
|
||||
:param server: instance to delete
|
||||
:return:
|
||||
"""
|
||||
# delete server
|
||||
sec_group_name = server.security_groups[0]['name']
|
||||
server_key_name = server.key_name
|
||||
|
||||
LOG.debug("DELETING NOVA INSTANCE: %s", server.id)
|
||||
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())
|
||||
|
||||
# delete sec-group
|
||||
for secgroup in nova_client.security_groups.list():
|
||||
if secgroup.name == sec_group_name:
|
||||
LOG.debug("DELETING SEC_GROUP: %s", sec_group_name)
|
||||
nova_client.security_groups.delete(secgroup.id)
|
||||
|
||||
# delete key-pair
|
||||
for key_pair in nova_client.keypairs.list():
|
||||
if key_pair.name == server_key_name:
|
||||
LOG.debug("DELETING KEY_PAIR: %s", server_key_name)
|
||||
nova_client.keypairs.delete(key_pair.id)
|
||||
|
||||
def _delete_ipsec_site_connection(self, neutron_client,
|
||||
ipsec_site_connection):
|
||||
"""Deletes ipsec site connection
|
||||
|
||||
:param neutron_client: neutron client
|
||||
:param ipsec_site_connection: ipsec_site_connection
|
||||
:return:
|
||||
"""
|
||||
LOG.debug("DELETING IPSEC_SITE_CONNECTION %s",
|
||||
ipsec_site_connection['id'])
|
||||
neutron_client.delete_ipsec_site_connection(
|
||||
ipsec_site_connection['id'])
|
||||
|
||||
def _delete_vpn_service(self, neutron_client, vpn_service):
|
||||
"""Deletes VPN service endpoints
|
||||
|
||||
:param neutron_client: neutron client
|
||||
:param vpn_services: vpn_service
|
||||
:return:
|
||||
"""
|
||||
LOG.debug("DELETING VPN_SERVICE %s", vpn_service['id'])
|
||||
neutron_client.delete_vpnservice(vpn_service['id'])
|
||||
|
||||
def _delete_ipsec_policy(self, neutron_client, ipsec_policy):
|
||||
"""Deletes IPSEC policy
|
||||
|
||||
:param neutron_client: neutron client
|
||||
:param ipsec_policy: ipsec_policy
|
||||
:return:
|
||||
"""
|
||||
LOG.debug("DELETING IPSEC POLICY")
|
||||
neutron_client.delete_ipsecpolicy(ipsec_policy['id'])
|
||||
|
||||
def _delete_ike_policy(self, neutron_client, ike_policy):
|
||||
"""Deletes IKE policy
|
||||
|
||||
:param neutron_client: neutron client
|
||||
:param ike_policy: ike_policy
|
||||
:return:
|
||||
"""
|
||||
LOG.debug("DELETING IKE POLICY")
|
||||
neutron_client.delete_ikepolicy(ike_policy['id'])
|
||||
|
||||
def _delete_network(self, neutron_client):
|
||||
"""Delete neutron network.
|
||||
|
||||
:param network_tuple: tuple, router, network and subnet to delete
|
||||
:return
|
||||
"""
|
||||
|
||||
try:
|
||||
# delete interface subnet-router
|
||||
LOG.debug("DELETING RALLY ROUTER INTERFACES & GATEWAYS")
|
||||
routers = neutron_client.list_routers()
|
||||
subnets = neutron_client.list_subnets()
|
||||
subnet_id = None
|
||||
p = re.compile(r"\d")
|
||||
if routers:
|
||||
for router in routers['routers']:
|
||||
if "rally" in router['name']:
|
||||
neutron_client.remove_gateway_router(router['id'])
|
||||
m = p.search(router['name'])
|
||||
if m:
|
||||
subnet_name = "rally_subnet_" + m.group()
|
||||
if subnets:
|
||||
for subnet in subnets['subnets']:
|
||||
if subnet_name == subnet['name']:
|
||||
subnet_id = subnet['id']
|
||||
neutron_client.remove_interface_router(
|
||||
router['id'],
|
||||
{"subnet_id": subnet_id})
|
||||
|
||||
# delete ports associated with interface
|
||||
LOG.debug("DELETING RALLY PORTS")
|
||||
ports = neutron_client.list_ports()
|
||||
if ports:
|
||||
for port in ports['ports']:
|
||||
neutron_client.delete_port(port['id'])
|
||||
|
||||
# delete router
|
||||
LOG.debug("DELETING RALLY ROUTERS")
|
||||
if routers:
|
||||
for router in routers['routers']:
|
||||
if "rally" in router['name']:
|
||||
neutron_client.delete_router(router['id'])
|
||||
|
||||
# Delete external network & subnet:
|
||||
LOG.debug("DELETING RALLY PUBLIC NETWORK")
|
||||
networks = neutron_client.list_networks()
|
||||
if networks:
|
||||
for network in networks['networks']:
|
||||
if network['router:external'] and (network['name']
|
||||
== "rally_network_public"):
|
||||
external_network = network
|
||||
self.admin_clients("neutron").delete_network(
|
||||
external_network["id"])
|
||||
|
||||
# delete network
|
||||
LOG.debug("DELETING RALLY NETWORKS")
|
||||
networks = neutron_client.list_networks()
|
||||
if networks:
|
||||
for network in networks['networks']:
|
||||
if "rally_network" in network['name']:
|
||||
neutron_client.delete_network(network['id'])
|
||||
|
||||
except Exception as err:
|
||||
LOG.exception(err)
|
||||
|
||||
def _delete_key_file(self, key_files):
|
||||
"""Delete ssh key file
|
||||
|
||||
:param key_files: list of paths to ssh key files
|
||||
:return:
|
||||
"""
|
||||
LOG.debug("DELETING RALLY KEY FILES")
|
||||
for key_file in key_files:
|
||||
if os.path.exists(key_file):
|
||||
os.remove(key_file)
|
||||
|
||||
def _delete_knownhosts_file(self):
|
||||
"""Removes the knownhosts file
|
||||
|
||||
:param server_ips: ips to be removed from /root/.ssh/knownhosts
|
||||
:return:
|
||||
"""
|
||||
LOG.debug("DELETE THE KNOWNHOST FILE")
|
||||
try:
|
||||
cmd = ['rm', '-rf', "~/.ssh/known_hosts"]
|
||||
cmd = ip_lib.add_namespace_to_cmd(cmd)
|
||||
linux_utils.execute(cmd)
|
||||
return True
|
||||
|
||||
except RuntimeError:
|
||||
return False
|
||||
|
||||
def _cleanup(self,
|
||||
key_file_names=None,
|
||||
called_from=None):
|
||||
|
||||
LOG.debug("CLEAN UP CALLED FROM %s", called_from)
|
||||
nova_client = self.clients("nova")
|
||||
neutron_client = self.clients("neutron")
|
||||
|
||||
servers = nova_client.servers.list()
|
||||
if servers:
|
||||
for server in servers:
|
||||
if "rally" in server.name:
|
||||
self._delete_server(nova_client, server)
|
||||
|
||||
if key_file_names:
|
||||
self._delete_key_file(key_file_names)
|
||||
|
||||
self._delete_knownhosts_file()
|
||||
|
||||
vpn_connections = neutron_client.list_ipsec_site_connections()
|
||||
if vpn_connections:
|
||||
for vpn_connection in vpn_connections['ipsec_site_connections']:
|
||||
if "rally" in vpn_connection['name']:
|
||||
self._delete_ipsec_site_connection(neutron_client,
|
||||
vpn_connection)
|
||||
|
||||
vpn_services = neutron_client.list_vpnservices()
|
||||
if vpn_services:
|
||||
for vpn_service in vpn_services['vpnservices']:
|
||||
if "rally" in vpn_service['name']:
|
||||
self._delete_vpn_service(neutron_client, vpn_service)
|
||||
|
||||
ipsec_policies = neutron_client.list_ipsecpolicies()
|
||||
if ipsec_policies:
|
||||
for ipsec_policy in ipsec_policies['ipsecpolicies']:
|
||||
if "rally" in ipsec_policy['name']:
|
||||
self._delete_ipsec_policy(neutron_client, ipsec_policy)
|
||||
|
||||
ike_policies = neutron_client.list_ikepolicies()
|
||||
if ike_policies:
|
||||
for ike_policy in ike_policies['ikepolicies']:
|
||||
if "rally" in ike_policy['name']:
|
||||
self._delete_ike_policy(neutron_client, ike_policy)
|
||||
|
||||
# Deletes entire network
|
||||
self._delete_network(neutron_client)
|
Loading…
Reference in New Issue
Block a user