summaryrefslogtreecommitdiffstats
path: root/.gitreview
blob: 1608e3a2ccf8ffd5b02281e0cd14abf968f425f1 (plain)
1
2
3
4
[gerrit]
host=gerrit.opnfv.org
port=29418
project=opnfvdocs.git
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
#!/usr/bin/env python
#
# Description:
#   Cleans possible leftovers after running functest tests:
#       - Nova instances
#       - Glance images
#       - Cinder volumes
#       - Floating IPs
#       - Neutron networks, subnets and ports
#       - Routers
#       - Users and tenants
#
# Author:
#    jose.lausuch@ericsson.com
#
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
#

import argparse
import logging
import os
import re
import sys
import time
import yaml

from novaclient import client as novaclient
from neutronclient.v2_0 import client as neutronclient
from keystoneclient.v2_0 import client as keystoneclient
from cinderclient import client as cinderclient

parser = argparse.ArgumentParser()
parser.add_argument("-d", "--debug", help="Debug mode",  action="store_true")
args = parser.parse_args()


""" logging configuration """
logger = logging.getLogger('clean_openstack')
logger.setLevel(logging.DEBUG)

ch = logging.StreamHandler()
if args.debug:
    ch.setLevel(logging.DEBUG)
else:
    ch.setLevel(logging.INFO)

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)

REPO_PATH=os.environ['repos_dir']+'/functest/'
if not os.path.exists(REPO_PATH):
    logger.error("Functest repository directory not found '%s'" % REPO_PATH)
    exit(-1)
sys.path.append(REPO_PATH + "testcases/")
import functest_utils

with open(REPO_PATH+"testcases/VIM/OpenStack/CI/libraries/os_defaults.yaml") as f:
    defaults_yaml = yaml.safe_load(f)
f.close()

installer = os.environ["INSTALLER_TYPE"]

default_images = defaults_yaml.get(installer).get("images")
default_networks = defaults_yaml.get(installer).get("networks") +\
    defaults_yaml.get("common").get("networks")
default_routers = defaults_yaml.get(installer).get("routers") +\
    defaults_yaml.get("common").get("routers")
default_security_groups = defaults_yaml.get(installer).get("security_groups")
default_users = defaults_yaml.get(installer).get("users")
default_tenants = defaults_yaml.get(installer).get("tenants")

def separator():
    logger.info("-------------------------------------------")

def remove_instances(nova_client):
    logger.info("Removing Nova instances...")
    instances = functest_utils.get_instances(nova_client)
    if instances is None or len(instances) == 0:
        logger.debug("No instances found.")
        return

    for instance in instances:
        instance_name = getattr(instance, 'name')
        instance_id = getattr(instance, 'id')
        logger.debug("Removing instance '%s', ID=%s ..." % (instance_name,instance_id))
        if functest_utils.delete_instance(nova_client, instance_id):
            logger.debug("  > Done!")
        else:
            logger.info("  > ERROR: There has been a problem removing the "
                        "instance %s..." % instance_id)

    timeout = 50
    while timeout > 0:
        instances = functest_utils.get_instances(nova_client)
        if instances is None or len(instances) == 0:
            break
        else:
            logger.debug("Waiting for instances to be terminated...")
            timeout -= 1
            time.sleep(1)


def remove_images(nova_client):
    logger.info("Removing Glance images...")
    images = functest_utils.get_images(nova_client)
    if images is None or len(images) == 0:
        logger.debug("No images found.")
        return

    for image in images:
        image_name = getattr(image, 'name')
        image_id = getattr(image, 'id')
        logger.debug("'%s', ID=%s " %(image_name,image_id))
        if image_name not in default_images:
            logger.debug("Removing image '%s', ID=%s ..." % (image_name,image_id))
            if functest_utils.delete_glance_image(nova_client, image_id):
                logger.debug("  > Done!")
            else:
                logger.info("  > ERROR: There has been a problem removing the"
                            "image %s..." % image_id)
        else:
            logger.debug("   > this is a default image and will NOT be deleted.")


def remove_volumes(cinder_client):
    logger.info("Removing Cinder volumes...")
    volumes = functest_utils.get_volumes(cinder_client)
    if volumes is None or len(volumes) == 0:
        logger.debug("No volumes found.")
        return

    for volume in volumes:
        volume_id = getattr(volume, 'id')
        logger.debug("Removing cinder volume %s ..." % volume_id)
        if functest_utils.delete_volume(cinder_client, volume_id):
            logger.debug("  > Done!")
        else:
            logger.debug("Trying forced removal...")
            if functest_utils.delete_volume(cinder_client,
                                            volume_id,
                                            forced=True):
                logger.debug("  > Done!")
            else:
                logger.info("  > ERROR: There has been a problem removing the "
                            "volume %s..." % volume_id)


def remove_floatingips(nova_client):
    logger.info("Removing floating IPs...")
    floatingips = functest_utils.get_floating_ips(nova_client)
    if floatingips is None or len(floatingips) == 0:
        logger.debug("No floating IPs found.")
        return

    for fip in floatingips:
        fip_id = getattr(fip, 'id')
        logger.debug("Removing floating IP %s ..." % fip_id)
        if functest_utils.delete_floating_ip(nova_client, fip_id):
            logger.debug("  > Done!")
        else:
            logger.info("  > ERROR: There has been a problem removing the "
                        "floating IP %s..." % fip_id)

    timeout = 50
    while timeout > 0:
        floatingips = functest_utils.get_floating_ips(nova_client)
        if floatingips is None or len(floatingips) == 0:
            break
        else:
            logger.debug("Waiting for floating ips to be released...")
            timeout -= 1
            time.sleep(1)


def remove_networks(neutron_client):
    logger.info("Removing Neutron objects")
    network_ids = []
    networks = functest_utils.get_network_list(neutron_client)
    if networks == None:
        logger.debug("There are no networks in the deployment. ")
    else:
        logger.debug("Existing networks:")
        for network in networks:
            net_id = network['id']
            net_name = network['name']
            logger.debug(" '%s', ID=%s " %(net_name,net_id))
            if net_name in default_networks:
                logger.debug("   > this is a default network and will NOT be deleted.")
            elif network['router:external'] == True:
                logger.debug("   > this is an external network and will NOT be deleted.")
            else:
                logger.debug("   > this network will be deleted.")
                network_ids.append(net_id)

    #delete ports
    ports = functest_utils.get_port_list(neutron_client)
    if ports is None:
        logger.debug("There are no ports in the deployment. ")
    else:
        remove_ports(neutron_client, ports, network_ids)

    #remove routers
    routers = functest_utils.get_router_list(neutron_client)
    if routers is None:
        logger.debug("There are no routers in the deployment. ")
    else:
        remove_routers(neutron_client, routers)

    #remove networks
    if network_ids != None:
        for net_id in network_ids:
            logger.debug("Removing network %s ..." % net_id)
            if functest_utils.delete_neutron_net(neutron_client, net_id):
                logger.debug("  > Done!")
            else:
                logger.info("  > ERROR: There has been a problem removing the "
                            "network %s..." % net_id)


def remove_ports(neutron_client, ports, network_ids):
    for port in ports:
        if port['network_id'] in network_ids:
            port_id = port['id']
            try:
                subnet_id = port['fixed_ips'][0]['subnet_id']
            except:
                logger.info("  > WARNING: Port %s does not contain 'fixed_ips'" % port_id)
                print port
            router_id = port['device_id']
            if len(port['fixed_ips']) == 0 and router_id == '':
                logger.debug("Removing port %s ..." % port_id)
                if functest_utils.delete_neutron_port(neutron_client, port_id):
                    logger.debug("  > Done!")
                else:
                    logger.info("  > ERROR: There has been a problem removing the "
                                "port %s ..." %port_id)
                    force_remove_port(neutron_client, port_id)

            elif port['device_owner'] == 'network:router_interface':
                logger.debug("Detaching port %s (subnet %s) from router %s ..."
                             % (port_id,subnet_id,router_id))
                if functest_utils.remove_interface_router(neutron_client,
                                                          router_id, subnet_id):
                    time.sleep(5) # leave 5 seconds to detach before doing anything else
                    logger.debug("  > Done!")
                else:
                    logger.info("  > ERROR: There has been a problem removing the "
                                "interface %s from router %s..." %(subnet_id,router_id))
                    force_remove_port(neutron_client, port_id)
            else:
                force_remove_port(neutron_client, port_id)


def force_remove_port(neutron_client, port_id):
    logger.debug("Clearing device_owner for port %s ..." % port_id)
    functest_utils.update_neutron_port(neutron_client,
                                       port_id,
                                       device_owner='clear')
    logger.debug("Removing port %s ..." % port_id)
    if functest_utils.delete_neutron_port(neutron_client, port_id):
        logger.debug("  > Done!")
    else:
        logger.info("  > ERROR: Deleting port %s failed" % port_id)


def remove_routers(neutron_client, routers):
    for router in routers:
        router_id = router['id']
        router_name = router['name']
        if router_name not in default_routers:
            logger.debug("Checking '%s' with ID=(%s) ..." % (router_name,router_id))
            if router['external_gateway_info'] != None:
                logger.debug("Router has gateway to external network. Removing link...")
                if functest_utils.remove_gateway_router(neutron_client, router_id):
                    logger.debug("  > Done!")
                else:
                    logger.info("  > ERROR: There has been a problem removing "
                                "the gateway...")
            else:
                logger.debug("Router is not connected to anything. Ready to remove...")
            logger.debug("Removing router %s(%s) ..." % (router_name, router_id))
            if functest_utils.delete_neutron_router(neutron_client, router_id):
                logger.debug("  > Done!")
            else:
                logger.info("  > ERROR: There has been a problem removing the "
                            "router '%s'(%s)..." % (router_name, router_id))


def remove_security_groups(neutron_client):
    logger.info("Removing Security groups...")
    secgroups = functest_utils.get_security_groups(neutron_client)
    if secgroups is None or len(secgroups) == 0:
        logger.debug("No security groups found.")
        return

    for secgroup in secgroups:
        secgroup_name = secgroup['name']
        secgroup_id = secgroup['id']
        logger.debug("'%s', ID=%s " %(secgroup_name,secgroup_id))
        if secgroup_name not in default_security_groups:
            logger.debug(" Removing '%s'..." % secgroup_name)
            if functest_utils.delete_security_group(neutron_client, secgroup_id):
                logger.debug("  > Done!")
            else:
                logger.info("  > ERROR: There has been a problem removing the "
                            "security group %s..." % secgroup_id)
        else:
            logger.debug("   > this is a default security group and will NOT "
                         "be deleted.")


def remove_users(keystone_client):
    logger.info("Removing Users...")
    users = functest_utils.get_users(keystone_client)
    if users == None:
        logger.debug("There are no users in the deployment. ")
        return

    for user in users:
        user_name = getattr(user, 'name')
        user_id = getattr(user, 'id')
        logger.debug("'%s', ID=%s " %(user_name,user_id))
        if user_name not in default_users:
            logger.debug(" Removing '%s'..." % user_name)
            if functest_utils.delete_user(keystone_client,user_id):
                logger.debug("  > Done!")
            else:
                logger.info("  > ERROR: There has been a problem removing the "
                            "user '%s'(%s)..." % (user_name,user_id))
        else:
            logger.debug("   > this is a default user and will NOT be deleted.")


def remove_tenants(keystone_client):
    logger.info("Removing Tenants...")
    tenants = functest_utils.get_tenants(keystone_client)
    if tenants == None:
        logger.debug("There are no tenants in the deployment. ")
        return

    for tenant in tenants:
        tenant_name=getattr(tenant, 'name')
        tenant_id = getattr(tenant, 'id')
        logger.debug("'%s', ID=%s " %(tenant_name,tenant_id))
        if tenant_name not in default_tenants:
            logger.debug(" Removing '%s'..." % tenant_name)
            if functest_utils.delete_tenant(keystone_client,tenant_id):
                logger.debug("  > Done!")
            else:
                logger.info("  > ERROR: There has been a problem removing the "
                            "tenant '%s'(%s)..." % (tenant_name,tenant_id))
        else:
            logger.debug("   > this is a default tenant and will NOT be deleted.")



def main():
    creds_nova = functest_utils.get_credentials("nova")
    nova_client = novaclient.Client('2',**creds_nova)

    creds_neutron = functest_utils.get_credentials("neutron")
    neutron_client = neutronclient.Client(**creds_neutron)

    creds_keystone = functest_utils.get_credentials("keystone")
    keystone_client = keystoneclient.Client(**creds_keystone)

    creds_cinder = functest_utils.get_credentials("cinder")
    #cinder_client = cinderclient.Client(**creds_cinder)
    cinder_client = cinderclient.Client('1',creds_cinder['username'],
                                        creds_cinder['api_key'],
                                        creds_cinder['project_id'],
                                        creds_cinder['auth_url'],
                                        service_type="volume")

    if not functest_utils.check_credentials():
        logger.error("Please source the openrc credentials and run the script again.")
        exit(-1)

    remove_instances(nova_client)
    separator()
    remove_images(nova_client)
    separator()
    remove_volumes(cinder_client)
    separator()
    remove_floatingips(nova_client)
    separator()
    remove_networks(neutron_client)
    separator()
    remove_security_groups(neutron_client)
    separator()
    remove_users(keystone_client)
    separator()
    remove_tenants(keystone_client)
    separator()

    exit(0)


if __name__ == '__main__':
    main()