From c94460eef60d18efc533adf30b49e7c56fa6b2ed Mon Sep 17 00:00:00 2001 From: George Paraskevopoulos Date: Fri, 17 Mar 2017 11:56:43 +0200 Subject: Add ODL cleanup utilities ODL does not clean all resources properly after tacker deletions, so we add this as a post processing step Change-Id: Ic485ee32b195f72235922ebe613af6c010cb57db Signed-off-by: George Paraskevopoulos (cherry picked from commit e48b950bc77e37fbda611415577a7388e19c1ff6) --- sfc/lib/cleanup.py | 28 ++++++++++++++++++++++--- sfc/lib/utils.py | 46 +++++++++++++++++++++++++++++++++++++++++ sfc/tests/functest/run_tests.py | 7 +++++-- 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/sfc/lib/cleanup.py b/sfc/lib/cleanup.py index cf3349d3..61f47b42 100644 --- a/sfc/lib/cleanup.py +++ b/sfc/lib/cleanup.py @@ -1,12 +1,22 @@ +import sys + import functest.utils.functest_logger as ft_logger import functest.utils.openstack_utils as os_utils import functest.utils.openstack_tacker as os_tacker -import utils +import sfc.lib.utils as utils logger = ft_logger.Logger(__name__).getLogger() +def delete_odl_resources(odl_ip, odl_port, resource): + rsrc_list = utils.get_odl_resource_list(odl_ip, odl_port, resource) + elem_names = utils.odl_resource_list_names(resource, rsrc_list) + for elem in elem_names: + logger.info("Removing ODL resource: {0}/{1}".format(resource, elem)) + utils.delete_odl_resource_elem(odl_ip, odl_port, resource, elem) + + def delete_vnfds(): t = os_tacker.get_tacker_client() for vnfd in os_tacker.list_vnfds(t): @@ -58,14 +68,26 @@ def delete_instances(): os_utils.delete_instance(n, inst.id) -def cleanup(): +def cleanup_odl(odl_ip, odl_port): + delete_odl_resources(odl_ip, odl_port, 'service-function-forwarder') + delete_odl_resources(odl_ip, odl_port, 'service-function-chain') + delete_odl_resources(odl_ip, odl_port, 'service-function-path') + delete_odl_resources(odl_ip, odl_port, 'service-function') + + +def cleanup(odl_ip=None, odl_port=None): delete_sfc_clfs() delete_sfcs() delete_vnfs() delete_stacks() delete_floating_ips() delete_instances() + if odl_ip is not None and odl_port is not None: + cleanup_odl(odl_ip, odl_port) if __name__ == '__main__': - cleanup() + if sys.argv > 2: + cleanup(sys.argv[1], sys.argv[2]) + else: + cleanup() diff --git a/sfc/lib/utils.py b/sfc/lib/utils.py index c3a587e0..39a8da91 100644 --- a/sfc/lib/utils.py +++ b/sfc/lib/utils.py @@ -11,7 +11,9 @@ import os import re import subprocess +import requests import time +import xmltodict import yaml import functest.utils.functest_logger as ft_logger @@ -472,3 +474,47 @@ def get_nova_id(tacker_client, resource, vnf_id=None, vnf_name=None): logger.error("Cannot get nova ID for VNF (id='%s', name='%s')" % (vnf_id, vnf_name)) return None + + +def get_odl_ip_port(nodes): + local_jetty = os.path.join(os.getcwd(), 'jetty.xml') + odl_node = next(n for n in nodes if n.is_odl()) + odl_node.get_file('/opt/opendaylight/etc/jetty.xml', local_jetty) + with open(local_jetty) as fd: + parsed = xmltodict.parse(fd.read(), dict_constructor=dict) + + ip = (parsed['Configure']['Call'][0]['Arg']['New'] + ['Set'][0]['Property']['@default']) + port = (parsed['Configure']['Call'][0]['Arg']['New'] + ['Set'][1]['Property']['@default']) + return ip, port + + +def pluralize(s): + return '{0}s'.format(s) + + +def format_odl_resource_list_url(odl_ip, odl_port, resource, + odl_user='admin', odl_pwd='admin'): + return ('http://{usr}:{pwd}@{ip}:{port}/restconf/config/{rsrc}:{rsrcs}' + .format(usr=odl_user, pwd=odl_pwd, ip=odl_ip, port=odl_port, + rsrc=resource, rsrcs=pluralize(resource))) + + +def format_odl_resource_elem_url(odl_ip, odl_port, resource, elem_name): + list_url = format_odl_resource_list_url(odl_ip, odl_port, resource) + return ('{0}/{1}/{2}'.format(list_url, resource, elem_name)) + + +def odl_resource_list_names(resource, resource_json): + return [r['name'] for r in resource_json[pluralize(resource)][resource]] + + +def get_odl_resource_list(odl_ip, odl_port, resource): + url = format_odl_resource_list_url(odl_ip, odl_port, resource) + return requests.get(url).json() + + +def delete_odl_resource_elem(odl_ip, odl_port, resource, elem_name): + url = format_odl_resource_elem_url(odl_ip, odl_port, resource, elem_name) + requests.delete(url) diff --git a/sfc/tests/functest/run_tests.py b/sfc/tests/functest/run_tests.py index 1539fca4..771f2c62 100644 --- a/sfc/tests/functest/run_tests.py +++ b/sfc/tests/functest/run_tests.py @@ -21,6 +21,7 @@ import functest.utils.openstack_utils as os_utils import opnfv.utils.ovs_logger as ovs_log import sfc.lib.cleanup as sfc_cleanup import sfc.lib.config as sfc_config +import sfc.lib.utils as sfc_utils from opnfv.deployment.factory import Factory as DeploymentFactory @@ -68,8 +69,8 @@ def main(): a_controller = [node for node in nodes if node.is_controller()][0] - rc_file = fetch_tackerc_file(a_controller) + rc_file = fetch_tackerc_file(a_controller) os_utils.source_credentials(rc_file) logger.info("Updating env with {0}".format(rc_file)) @@ -78,6 +79,8 @@ def main(): if var.startswith("OS_"): logger.info("\t{0}={1}".format(var, value)) + odl_ip, odl_port = sfc_utils.get_odl_ip_port(nodes) + ovs_logger = ovs_log.OVSLogger( os.path.join(COMMON_CONFIG.sfc_test_dir, 'ovs-logs'), COMMON_CONFIG.functest_results_dir) @@ -137,7 +140,7 @@ def main(): details = result.get("details") push_results( test_name_db, start_time, end_time, status, details) - sfc_cleanup.cleanup() + sfc_cleanup.cleanup(odl_ip=odl_ip, odl_port=odl_port) overall_end_time = time.time() if args.report: -- cgit 1.2.3-korg