#!/usr/bin/env python

# Copyright 2015 Dell Inc.
#
#    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.

from oslo_log import log as logging

from tempest import clients
from tempest import config
from tempest import test

LOG = logging.getLogger(__name__)
CONF = config.CONF

CONF_FLAVORS = None
CONF_IMAGES = None
CONF_NETWORKS = []
CONF_PRIV_NETWORK_NAME = None
CONF_PUB_NETWORK = None
CONF_PUB_ROUTER = None
CONF_TENANTS = None
CONF_USERS = None

IS_CEILOMETER = None
IS_CINDER = None
IS_GLANCE = None
IS_HEAT = None
IS_NEUTRON = None
IS_NOVA = None


def init_conf():
    global CONF_FLAVORS
    global CONF_IMAGES
    global CONF_NETWORKS
    global CONF_PRIV_NETWORK
    global CONF_PRIV_NETWORK_NAME
    global CONF_PUB_NETWORK
    global CONF_PUB_ROUTER
    global CONF_TENANTS
    global CONF_USERS
    global IS_CEILOMETER
    global IS_CINDER
    global IS_GLANCE
    global IS_HEAT
    global IS_NEUTRON
    global IS_NOVA

    IS_CEILOMETER = CONF.service_available.ceilometer
    IS_CINDER = CONF.service_available.cinder
    IS_GLANCE = CONF.service_available.glance
    IS_HEAT = CONF.service_available.heat
    IS_NEUTRON = CONF.service_available.neutron
    IS_NOVA = CONF.service_available.nova

    CONF_FLAVORS = [CONF.compute.flavor_ref, CONF.compute.flavor_ref_alt]
    CONF_IMAGES = [CONF.compute.image_ref, CONF.compute.image_ref_alt]
    CONF_PRIV_NETWORK_NAME = CONF.compute.fixed_network_name
    CONF_PUB_NETWORK = CONF.network.public_network_id
    CONF_PUB_ROUTER = CONF.network.public_router_id
    CONF_TENANTS = [CONF.identity.admin_tenant_name,
                    CONF.identity.tenant_name,
                    CONF.identity.alt_tenant_name]
    CONF_USERS = [CONF.identity.admin_username, CONF.identity.username,
                  CONF.identity.alt_username]

    if IS_NEUTRON:
        CONF_PRIV_NETWORK = _get_network_id(CONF.compute.fixed_network_name,
                                            CONF.identity.tenant_name)
        CONF_NETWORKS = [CONF_PUB_NETWORK, CONF_PRIV_NETWORK]


def _get_network_id(net_name, tenant_name):
    am = clients.AdminManager()
    net_cl = am.network_client
    id_cl = am.identity_client

    networks = net_cl.list_networks()
    tenant = id_cl.get_tenant_by_name(tenant_name)
    t_id = tenant['id']
    n_id = None
    for net in networks['networks']:
        if (net['tenant_id'] == t_id and net['name'] == net_name):
            n_id = net['id']
            break
    return n_id


class BaseService(object):
    def __init__(self, kwargs):
        self.client = None
        for key, value in kwargs.items():
            setattr(self, key, value)

        self.tenant_filter = {}
        if hasattr(self, 'tenant_id'):
            self.tenant_filter['tenant_id'] = self.tenant_id

    def _filter_by_tenant_id(self, item_list):
        if (item_list is None
                or len(item_list) == 0
                or not hasattr(self, 'tenant_id')
                or self.tenant_id is None
                or 'tenant_id' not in item_list[0]):
            return item_list

        return [item for item in item_list
                if item['tenant_id'] == self.tenant_id]

    def list(self):
        pass

    def delete(self):
        pass

    def dry_run(self):
        pass

    def save_state(self):
        pass

    def run(self):
        if self.is_dry_run:
            self.dry_run()
        elif self.is_save_state:
            self.save_state()
        else:
            self.delete()


class SnapshotService(BaseService):

    def __init__(self, manager, **kwargs):
        super(SnapshotService, self).__init__(kwargs)
        self.client = manager.snapshots_client

    def list(self):
        client = self.client
        snaps = client.list_snapshots()
        LOG.debug("List count, %s Snapshots" % len(snaps))
        return snaps

    def delete(self):
        snaps = self.list()
        client = self.client
        for snap in snaps:
            try:
                client.delete_snapshot(snap['id'])
            except Exception:
                LOG.exception("Delete Snapshot exception.")

    def dry_run(self):
        snaps = self.list()
        self.data['snapshots'] = snaps


class ServerService(BaseService):
    def __init__(self, manager, **kwargs):
        super(ServerService, self).__init__(kwargs)
        self.client = manager.servers_client

    def list(self):
        client = self.client
        servers_body = client.list_servers()
        servers = servers_body['servers']
        LOG.debug("List count, %s Servers" % len(servers))
        return servers

    def delete(self):
        client = self.client
        servers = self.list()
        for server in servers:
            try:
                client.delete_server(server['id'])
            except Exception:
                LOG.exception("Delete Server exception.")

    def dry_run(self):
        servers = self.list()
        self.data['servers'] = servers


class ServerGroupService(ServerService):

    def list(self):
        client = self.client
        sgs = client.list_server_groups()['server_groups']
        LOG.debug("List count, %s Server Groups" % len(sgs))
        return sgs

    def delete(self):
        client = self.client
        sgs = self.list()
        for sg in sgs:
            try:
                client.delete_server_group(sg['id'])
            except Exception:
                LOG.exception("Delete Server Group exception.")

    def dry_run(self):
        sgs = self.list()
        self.data['server_groups'] = sgs


class StackService(BaseService):
    def __init__(self, manager, **kwargs):
        super(StackService, self).__init__(kwargs)
        self.client = manager.orchestration_client

    def list(self):
        client = self.client
        stacks = client.list_stacks()['stacks']
        LOG.debug("List count, %s Stacks" % len(stacks))
        return stacks

    def delete(self):
        client = self.client
        stacks = self.list()
        for stack in stacks:
            try:
                client.delete_stack(stack['id'])
            except Exception:
                LOG.exception("Delete Stack exception.")

    def dry_run(self):
        stacks = self.list()
        self.data['stacks'] = stacks


class KeyPairService(BaseService):
    def __init__(self, manager, **kwargs):
        super(KeyPairService, self).__init__(kwargs)
        self.client = manager.keypairs_client

    def list(self):
        client = self.client
        keypairs = client.list_keypairs()['keypairs']
        LOG.debug("List count, %s Keypairs" % len(keypairs))
        return keypairs

    def delete(self):
        client = self.client
        keypairs = self.list()
        for k in keypairs:
            try:
                name = k['keypair']['name']
                client.delete_keypair(name)
            except Exception:
                LOG.exception("Delete Keypairs exception.")

    def dry_run(self):
        keypairs = self.list()
        self.data['keypairs'] = keypairs


class SecurityGroupService(BaseService):
    def __init__(self, manager, **kwargs):
        super(SecurityGroupService, self).__init__(kwargs)
        self.client = manager.security_groups_client

    def list(self):
        client = self.client
        secgrps = client.list_security_groups()['security_groups']
        secgrp_del = [grp for grp in secgrps if grp['name'] != 'default']
        LOG.debug("List count, %s Security Groups" % len(secgrp_del))
        return secgrp_del

    def delete(self):
        client = self.client
        secgrp_del = self.list()
        for g in secgrp_del:
            try:
                client.delete_security_group(g['id'])
            except Exception:
                LOG.exception("Delete Security Groups exception.")

    def dry_run(self):
        secgrp_del = self.list()
        self.data['security_groups'] = secgrp_del


class FloatingIpService(BaseService):
    def __init__(self, manager, **kwargs):
        super(FloatingIpService, self).__init__(kwargs)
        self.client = manager.floating_ips_client

    def list(self):
        client = self.client
        floating_ips = client.list_floating_ips()['floating_ips']
        LOG.debug("List count, %s Floating IPs" % len(floating_ips))
        return floating_ips

    def delete(self):
        client = self.client
        floating_ips = self.list()
        for f in floating_ips:
            try:
                client.delete_floating_ip(f['id'])
            except Exception:
                LOG.exception("Delete Floating IPs exception.")

    def dry_run(self):
        floating_ips = self.list()
        self.data['floating_ips'] = floating_ips


class VolumeService(BaseService):
    def __init__(self, manager, **kwargs):
        super(VolumeService, self).__init__(kwargs)
        self.client = manager.volumes_client

    def list(self):
        client = self.client
        vols = client.list_volumes()['volumes']
        LOG.debug("List count, %s Volumes" % len(vols))
        return vols

    def delete(self):
        client = self.client
        vols = self.list()
        for v in vols:
            try:
                client.delete_volume(v['id'])
            except Exception:
                LOG.exception("Delete Volume exception.")

    def dry_run(self):
        vols = self.list()
        self.data['volumes'] = vols


class VolumeQuotaService(BaseService):
    def __init__(self, manager, **kwargs):
        super(VolumeQuotaService, self).__init__(kwargs)
        self.client = manager.volume_quotas_client

    def delete(self):
        client = self.client
        try:
            client.delete_quota_set(self.tenant_id)
        except Exception:
            LOG.exception("Delete Volume Quotas exception.")

    def dry_run(self):
        quotas = self.client.show_quota_usage(self.tenant_id)['quota_set']
        self.data['volume_quotas'] = quotas


class NovaQuotaService(BaseService):
    def __init__(self, manager, **kwargs):
        super(NovaQuotaService, self).__init__(kwargs)
        self.client = manager.quotas_client
        self.limits_client = manager.limits_client

    def delete(self):
        client = self.client
        try:
            client.delete_quota_set(self.tenant_id)
        except Exception:
            LOG.exception("Delete Quotas exception.")

    def dry_run(self):
        client = self.limits_client
        quotas = client.show_limits()['limits']
        self.data['compute_quotas'] = quotas['absolute']


# Begin network service classes
class NetworkService(BaseService):
    def __init__(self, manager, **kwargs):
        super(NetworkService, self).__init__(kwargs)
        self.client = manager.network_client

    def _filter_by_conf_networks(self, item_list):
        if not item_list or not all(('network_id' in i for i in item_list)):
            return item_list

        return [item for item in item_list if item['network_id']
                not in CONF_NETWORKS]

    def list(self):
        client = self.client
        networks = client.list_networks(**self.tenant_filter)
        networks = networks['networks']
        # filter out networks declared in tempest.conf
        if self.is_preserve:
            networks = [network for network in networks
                        if network['id'] not in CONF_NETWORKS]
        LOG.debug("List count, %s Networks" % networks)
        return networks

    def delete(self):
        client = self.client
        networks = self.list()
        for n in networks:
            try:
                client.delete_network(n['id'])
            except Exception:
                LOG.exception("Delete Network exception.")

    def dry_run(self):
        networks = self.list()
        self.data['networks'] = networks


class NetworkFloatingIpService(NetworkService):

    def list(self):
        client = self.client
        flips = client.list_floatingips(**self.tenant_filter)
        flips = flips['floatingips']
        LOG.debug("List count, %s Network Floating IPs" % len(flips))
        return flips

    def delete(self):
        client = self.client
        flips = self.list()
        for flip in flips:
            try:
                client.delete_floatingip(flip['id'])
            except Exception:
                LOG.exception("Delete Network Floating IP exception.")

    def dry_run(self):
        flips = self.list()
        self.data['floating_ips'] = flips


class NetworkRouterService(NetworkService):

    def list(self):
        client = self.client
        routers = client.list_routers(**self.tenant_filter)
        routers = routers['routers']
        if self.is_preserve:
            routers = [router for router in routers
                       if router['id'] != CONF_PUB_ROUTER]

        LOG.debug("List count, %s Routers" % len(routers))
        return routers

    def delete(self):
        client = self.client
        routers = self.list()
        for router in routers:
            try:
                rid = router['id']
                ports = [port for port
                         in client.list_router_interfaces(rid)['ports']
                         if port["device_owner"] == "network:router_interface"]
                for port in ports:
                    client.remove_router_interface_with_port_id(rid,
                                                                port['id'])
                client.delete_router(rid)
            except Exception:
                LOG.exception("Delete Router exception.")

    def dry_run(self):
        routers = self.list()
        self.data['routers'] = routers


class NetworkHealthMonitorService(NetworkService):

    def list(self):
        client = self.client
        hms = client.list_health_monitors()
        hms = hms['health_monitors']
        hms = self._filter_by_tenant_id(hms)
        LOG.debug("List count, %s Health Monitors" % len(hms))
        return hms

    def delete(self):
        client = self.client
        hms = self.list()
        for hm in hms:
            try:
                client.delete_health_monitor(hm['id'])
            except Exception:
                LOG.exception("Delete Health Monitor exception.")

    def dry_run(self):
        hms = self.list()
        self.data['health_monitors'] = hms


class NetworkMemberService(NetworkService):

    def list(self):
        client = self.client
        members = client.list_members()
        members = members['members']
        members = self._filter_by_tenant_id(members)
        LOG.debug("List count, %s Members" % len(members))
        return members

    def delete(self):
        client = self.client
        members = self.list()
        for member in members:
            try:
                client.delete_member(member['id'])
            except Exception:
                LOG.exception("Delete Member exception.")

    def dry_run(self):
        members = self.list()
        self.data['members'] = members


class NetworkVipService(NetworkService):

    def list(self):
        client = self.client
        vips = client.list_vips()
        vips = vips['vips']
        vips = self._filter_by_tenant_id(vips)
        LOG.debug("List count, %s VIPs" % len(vips))
        return vips

    def delete(self):
        client = self.client
        vips = self.list()
        for vip in vips:
            try:
                client.delete_vip(vip['id'])
            except Exception:
                LOG.exception("Delete VIP exception.")

    def dry_run(self):
        vips = self.list()
        self.data['vips'] = vips


class NetworkPoolService(NetworkService):

    def list(self):
        client = self.client
        pools = client.list_pools()
        pools = pools['pools']
        pools = self._filter_by_tenant_id(pools)
        LOG.debug("List count, %s Pools" % len(pools))
        return pools

    def delete(self):
        client = self.client
        pools = self.list()
        for pool in pools:
            try:
                client.delete_pool(pool['id'])
            except Exception:
                LOG.exception("Delete Pool exception.")

    def dry_run(self):
        pools = self.list()
        self.data['pools'] = pools


class NetworkMeteringLabelRuleService(NetworkService):

    def list(self):
        client = self.client
        rules = client.list_metering_label_rules()
        rules = rules['metering_label_rules']
        rules = self._filter_by_tenant_id(rules)
        LOG.debug("List count, %s Metering Label Rules" % len(rules))
        return rules

    def delete(self):
        client = self.client
        rules = self.list()
        for rule in rules:
            try:
                client.delete_metering_label_rule(rule['id'])
            except Exception:
                LOG.exception("Delete Metering Label Rule exception.")

    def dry_run(self):
        rules = self.list()
        self.data['rules'] = rules


class NetworkMeteringLabelService(NetworkService):

    def list(self):
        client = self.client
        labels = client.list_metering_labels()
        labels = labels['metering_labels']
        labels = self._filter_by_tenant_id(labels)
        LOG.debug("List count, %s Metering Labels" % len(labels))
        return labels

    def delete(self):
        client = self.client
        labels = self.list()
        for label in labels:
            try:
                client.delete_metering_label(label['id'])
            except Exception:
                LOG.exception("Delete Metering Label exception.")

    def dry_run(self):
        labels = self.list()
        self.data['labels'] = labels


class NetworkPortService(NetworkService):

    def list(self):
        client = self.client
        ports = [port for port in
                 client.list_ports(**self.tenant_filter)['ports']
                 if port["device_owner"] == "" or
                 port["device_owner"].startswith("compute:")]

        if self.is_preserve:
            ports = self._filter_by_conf_networks(ports)

        LOG.debug("List count, %s Ports" % len(ports))
        return ports

    def delete(self):
        client = self.client
        ports = self.list()
        for port in ports:
            try:
                client.delete_port(port['id'])
            except Exception:
                LOG.exception("Delete Port exception.")

    def dry_run(self):
        ports = self.list()
        self.data['ports'] = ports


class NetworkSecGroupService(NetworkService):
    def list(self):
        client = self.client
        filter = self.tenant_filter
        # cannot delete default sec group so never show it.
        secgroups = [secgroup for secgroup in
                     client.list_security_groups(**filter)['security_groups']
                     if secgroup['name'] != 'default']

        if self.is_preserve:
            secgroups = self._filter_by_conf_networks(secgroups)
        LOG.debug("List count, %s securtiy_groups" % len(secgroups))
        return secgroups

    def delete(self):
        client = self.client
        secgroups = self.list()
        for secgroup in secgroups:
            try:
                client.delete_secgroup(secgroup['id'])
            except Exception:
                LOG.exception("Delete security_group exception.")

    def dry_run(self):
        secgroups = self.list()
        self.data['secgroups'] = secgroups


class NetworkSubnetService(NetworkService):

    def list(self):
        client = self.client
        subnets = client.list_subnets(**self.tenant_filter)
        subnets = subnets['subnets']
        if self.is_preserve:
            subnets = self._filter_by_conf_networks(subnets)
        LOG.debug("List count, %s Subnets" % len(subnets))
        return subnets

    def delete(self):
        client = self.client
        subnets = self.list()
        for subnet in subnets:
            try:
                client.delete_subnet(subnet['id'])
            except Exception:
                LOG.exception("Delete Subnet exception.")

    def dry_run(self):
        subnets = self.list()
        self.data['subnets'] = subnets


# Telemetry services
class TelemetryAlarmService(BaseService):
    def __init__(self, manager, **kwargs):
        super(TelemetryAlarmService, self).__init__(kwargs)
        self.client = manager.telemetry_client

    def list(self):
        client = self.client
        alarms = client.list_alarms()
        LOG.debug("List count, %s Alarms" % len(alarms))
        return alarms

    def delete(self):
        client = self.client
        alarms = self.list()
        for alarm in alarms:
            try:
                client.delete_alarm(alarm['id'])
            except Exception:
                LOG.exception("Delete Alarms exception.")

    def dry_run(self):
        alarms = self.list()
        self.data['alarms'] = alarms


# begin global services
class FlavorService(BaseService):
    def __init__(self, manager, **kwargs):
        super(FlavorService, self).__init__(kwargs)
        self.client = manager.flavors_client

    def list(self):
        client = self.client
        flavors = client.list_flavors({"is_public": None})['flavors']
        if not self.is_save_state:
            # recreate list removing saved flavors
            flavors = [flavor for flavor in flavors if flavor['id']
                       not in self.saved_state_json['flavors'].keys()]

        if self.is_preserve:
            flavors = [flavor for flavor in flavors
                       if flavor['id'] not in CONF_FLAVORS]
        LOG.debug("List count, %s Flavors after reconcile" % len(flavors))
        return flavors

    def delete(self):
        client = self.client
        flavors = self.list()
        for flavor in flavors:
            try:
                client.delete_flavor(flavor['id'])
            except Exception:
                LOG.exception("Delete Flavor exception.")

    def dry_run(self):
        flavors = self.list()
        self.data['flavors'] = flavors

    def save_state(self):
        flavors = self.list()
        self.data['flavors'] = {}
        for flavor in flavors:
            self.data['flavors'][flavor['id']] = flavor['name']


class ImageService(BaseService):
    def __init__(self, manager, **kwargs):
        super(ImageService, self).__init__(kwargs)
        self.client = manager.images_client

    def list(self):
        client = self.client
        images = client.list_images({"all_tenants": True})['images']
        if not self.is_save_state:
            images = [image for image in images if image['id']
                      not in self.saved_state_json['images'].keys()]
        if self.is_preserve:
            images = [image for image in images
                      if image['id'] not in CONF_IMAGES]
        LOG.debug("List count, %s Images after reconcile" % len(images))
        return images

    def delete(self):
        client = self.client
        images = self.list()
        for image in images:
            try:
                client.delete_image(image['id'])
            except Exception:
                LOG.exception("Delete Image exception.")

    def dry_run(self):
        images = self.list()
        self.data['images'] = images

    def save_state(self):
        self.data['images'] = {}
        images = self.list()
        for image in images:
            self.data['images'][image['id']] = image['name']


class IdentityService(BaseService):
    def __init__(self, manager, **kwargs):
        super(IdentityService, self).__init__(kwargs)
        self.client = manager.identity_client


class UserService(IdentityService):

    def list(self):
        client = self.client
        users = client.get_users()

        if not self.is_save_state:
            users = [user for user in users if user['id']
                     not in self.saved_state_json['users'].keys()]

        if self.is_preserve:
            users = [user for user in users if user['name']
                     not in CONF_USERS]

        elif not self.is_save_state:  # Never delete admin user
            users = [user for user in users if user['name'] !=
                     CONF.identity.admin_username]

        LOG.debug("List count, %s Users after reconcile" % len(users))
        return users

    def delete(self):
        client = self.client
        users = self.list()
        for user in users:
            try:
                client.delete_user(user['id'])
            except Exception:
                LOG.exception("Delete User exception.")

    def dry_run(self):
        users = self.list()
        self.data['users'] = users

    def save_state(self):
        users = self.list()
        self.data['users'] = {}
        for user in users:
            self.data['users'][user['id']] = user['name']


class RoleService(IdentityService):

    def list(self):
        client = self.client
        try:
            roles = client.list_roles()
            # reconcile roles with saved state and never list admin role
            if not self.is_save_state:
                roles = [role for role in roles if
                         (role['id'] not in
                          self.saved_state_json['roles'].keys()
                          and role['name'] != CONF.identity.admin_role)]
                LOG.debug("List count, %s Roles after reconcile" % len(roles))
            return roles
        except Exception:
            LOG.exception("Cannot retrieve Roles.")
            return []

    def delete(self):
        client = self.client
        roles = self.list()
        for role in roles:
            try:
                client.delete_role(role['id'])
            except Exception:
                LOG.exception("Delete Role exception.")

    def dry_run(self):
        roles = self.list()
        self.data['roles'] = roles

    def save_state(self):
        roles = self.list()
        self.data['roles'] = {}
        for role in roles:
            self.data['roles'][role['id']] = role['name']


class TenantService(IdentityService):

    def list(self):
        client = self.client
        tenants = client.list_tenants()['tenants']
        if not self.is_save_state:
            tenants = [tenant for tenant in tenants if (tenant['id']
                       not in self.saved_state_json['tenants'].keys()
                       and tenant['name'] != CONF.identity.admin_tenant_name)]

        if self.is_preserve:
            tenants = [tenant for tenant in tenants if tenant['name']
                       not in CONF_TENANTS]

        LOG.debug("List count, %s Tenants after reconcile" % len(tenants))
        return tenants

    def delete(self):
        client = self.client
        tenants = self.list()
        for tenant in tenants:
            try:
                client.delete_tenant(tenant['id'])
            except Exception:
                LOG.exception("Delete Tenant exception.")

    def dry_run(self):
        tenants = self.list()
        self.data['tenants'] = tenants

    def save_state(self):
        tenants = self.list()
        self.data['tenants'] = {}
        for tenant in tenants:
            self.data['tenants'][tenant['id']] = tenant['name']


class DomainService(BaseService):

    def __init__(self, manager, **kwargs):
        super(DomainService, self).__init__(kwargs)
        self.client = manager.identity_v3_client

    def list(self):
        client = self.client
        domains = client.list_domains()['domains']
        if not self.is_save_state:
            domains = [domain for domain in domains if domain['id']
                       not in self.saved_state_json['domains'].keys()]

        LOG.debug("List count, %s Domains after reconcile" % len(domains))
        return domains

    def delete(self):
        client = self.client
        domains = self.list()
        for domain in domains:
            try:
                client.update_domain(domain['id'], enabled=False)
                client.delete_domain(domain['id'])
            except Exception:
                LOG.exception("Delete Domain exception.")

    def dry_run(self):
        domains = self.list()
        self.data['domains'] = domains

    def save_state(self):
        domains = self.list()
        self.data['domains'] = {}
        for domain in domains:
            self.data['domains'][domain['id']] = domain['name']


def get_tenant_cleanup_services():
    tenant_services = []
    if IS_CEILOMETER:
        tenant_services.append(TelemetryAlarmService)
    if IS_NOVA:
        tenant_services.append(ServerService)
        tenant_services.append(KeyPairService)
        tenant_services.append(SecurityGroupService)
        tenant_services.append(ServerGroupService)
        if not IS_NEUTRON:
            tenant_services.append(FloatingIpService)
        tenant_services.append(NovaQuotaService)
    if IS_HEAT:
        tenant_services.append(StackService)
    if IS_NEUTRON:
        tenant_services.append(NetworkFloatingIpService)
        if test.is_extension_enabled('metering', 'network'):
            tenant_services.append(NetworkMeteringLabelRuleService)
            tenant_services.append(NetworkMeteringLabelService)
        tenant_services.append(NetworkRouterService)
        tenant_services.append(NetworkPortService)
        tenant_services.append(NetworkSubnetService)
        tenant_services.append(NetworkService)
        tenant_services.append(NetworkSecGroupService)
    if IS_CINDER:
        tenant_services.append(SnapshotService)
        tenant_services.append(VolumeService)
        tenant_services.append(VolumeQuotaService)
    return tenant_services


def get_global_cleanup_services():
    global_services = []
    if IS_NOVA:
        global_services.append(FlavorService)
    if IS_GLANCE:
        global_services.append(ImageService)
    global_services.append(UserService)
    global_services.append(TenantService)
    global_services.append(DomainService)
    global_services.append(RoleService)
    return global_services
