Example #1
0
    def test_execute_migrate_all_tenants(self):
        tenant_name = "Tenant_on_source_cloud"
        tenant_to_migrate = self.migration_task.ks_source.tenants.create(
            tenant_name, "for tenant migration test", True)

        tenant_name2 = "Tenant_on_source_cloud2"
        tenant_to_migrate2 = self.migration_task.ks_source.tenants.create(
            tenant_name2, "for tenant migration test", True)

        migrated_tenant = None
        migrated_tenant2 = None
        try:
            # migrate nothing
            self.migration_task.execute([])

            # migrate all tenant resources
            self.migration_task.execute(None)

            # get the tenant data that has been migrated from src to dst
            values = [
                tenant_name, cfg.CONF.SOURCE.os_cloud_name,
                cfg.CONF.TARGET.os_cloud_name
            ]
            tenant_data = tenants.get_migrated_tenant(values)

            tenant_new_name = tenant_data['new_project_name']
            migrated_tenant = self.migration_task.ks_target.tenants.\
                find(name=tenant_new_name)

            self.assertIsNotNone(migrated_tenant)

            values = [
                tenant_name2, cfg.CONF.SOURCE.os_cloud_name,
                cfg.CONF.TARGET.os_cloud_name
            ]
            tenant_data2 = tenants.get_migrated_tenant(values)

            tenant_new_name2 = tenant_data2['new_project_name']
            migrated_tenant2 = self.migration_task.ks_target.tenants.\
                find(name=tenant_new_name2)

            self.assertIsNotNone(migrated_tenant2)

        except keystone_exceptions.NotFound:
            self.fail()
        finally:
            self.clean_up(tenant_to_migrate, migrated_tenant)
            self.clean_up(tenant_to_migrate2, migrated_tenant2)
    def test_get_migrated_tenant(self):
        db_handler.initialise_tenants_mapping()
        tenant_data = {'project_name': "name",
                       'src_uuid': "123",
                       'src_cloud': "cloud1",
                       'new_project_name': "new_name",
                       'dst_uuid': "234",
                       'dst_cloud': "cloud2",
                       'images_migrated': '0',
                       'quota_updated': '0',
                       'state': "unknown"}
        db_handler.record_tenant_migrated([tenant_data])

        values = ["name", "cloud1", "cloud2"]
        return_data = db_handler.get_migrated_tenant(values)

        self.assertIsNot(None, return_data)

        table_name = "tenants"
        w_dict = {'project_name': "name",
                'src_uuid': "123",
                'src_cloud': "cloud1",
                'dst_cloud': "cloud2"}

        delete_record(table_name, w_dict)
    def execute(self):
        LOG.info("Start Project quota updating ...")
        tenants = self.ks_source.tenants.list()

        for tenant in tenants:
            tenant_name = tenant.name
            # get the tenant data that has been migrated from src to dst
            values = [tenant_name, self.s_cloud_name, self.t_cloud_name]
            tenant_data = db_handler.get_migrated_tenant(values)

            # only update quotas for project that has been completed migrated
            if tenant_data is not None:
                if tenant_data['state'] == "proxy_created":
                    if tenant_data['quota_updated'] == '1':
                        LOG.info("The quota of project {0} has been updated."
                                 .format(tenant_data['project_name']))

                    else:
                        new_name_dst = tenant_data['new_project_name']

                        # get source project quota
                        src_quota = self.nv_source.quotas.get(tenant.id)
                        # update destination project quota
                        self.update_quota(new_name_dst,
                                          src_quota,
                                          tenant_data)

                else:
                    LOG.info("The corresponding project {0} has not been "
                             "migrated.".format(tenant_data['project_name']))

            else:
                LOG.info("Tenant {} in could {} has not been migrated."
                         .format(tenant.name, self.s_cloud_name))
    def execute(self):
        LOG.info("Start Project quota updating ...")
        tenants = self.ks_source.tenants.list()

        for tenant in tenants:
            tenant_name = tenant.name
            # get the tenant data that has been migrated from src to dst
            values = [tenant_name, self.s_cloud_name, self.t_cloud_name]
            tenant_data = db_handler.get_migrated_tenant(values)

            # only update quotas for project that has been completed migrated
            if tenant_data is not None:
                if tenant_data['state'] == "proxy_created":
                    if tenant_data['quota_updated'] == '1':
                        LOG.info("The quota of project {0} has been updated.".
                                 format(tenant_data['project_name']))

                    else:
                        new_name_dst = tenant_data['new_project_name']

                        # get source project quota
                        src_quota = self.nv_source.quotas.get(tenant.id)
                        # update destination project quota
                        self.update_quota(new_name_dst, src_quota, tenant_data)

                else:
                    LOG.info("The corresponding project {0} has not been "
                             "migrated.".format(tenant_data['project_name']))

            else:
                LOG.info("Tenant {} in could {} has not been migrated.".format(
                    tenant.name, self.s_cloud_name))
    def execute(self):
        print "project quota updating ..."
        tenants = self.ks_source.tenants.list()

        for tenant in tenants:
            tenant_name = tenant.name
            # get the tenant data that has been migrated from src to dst
            values = [tenant_name, self.s_cloud_name, self.t_cloud_name]
            tenant_data = db_handler.get_migrated_tenant(values)

            # only update quotas for project that has been completed migrated
            if tenant_data is not None:
                if tenant_data['state'] == "proxy_created":
                    if tenant_data['quota_updated'] == '1':
                        print "The quota of project {0} has been updated.".\
                            format(tenant_data['project_name'])

                    else:
                        new_name_dst = tenant_data['new_project_name']

                        # get source project quota
                        src_quota = self.nv_source.quotas.get(tenant.id)
                        # update destination project quota
                        self.update_quota(new_name_dst, src_quota)

                        tenant_data.update({'quota_updated': '1'})
                        db_handler.update_migration_record(**tenant_data)

                else:
                    print "The corresponding project {0} " \
                          "has not been migrated.".\
                        format(tenant_data['project_name'])
Example #6
0
    def test_get_migrated_tenant(self):
        db_handler.initialise_tenants_mapping()
        tenant_data = {
            'project_name': "name",
            'src_uuid': "123",
            'src_cloud': "cloud1",
            'new_project_name': "new_name",
            'dst_uuid': "234",
            'dst_cloud': "cloud2",
            'images_migrated': '0',
            'quota_updated': '0',
            'state': "unknown"
        }
        db_handler.record_tenant_migrated([tenant_data])

        values = ["name", "cloud1", "cloud2"]
        return_data = db_handler.get_migrated_tenant(values)

        self.assertIsNot(None, return_data)

        table_name = "tenants"
        w_dict = {
            'project_name': "name",
            'src_uuid': "123",
            'src_cloud': "cloud1",
            'dst_cloud': "cloud2"
        }

        delete_record(table_name, w_dict)
Example #7
0
    def migrate_one_tenant(self, tenant_name):
        try:
            s_tenant = self.ks_source.tenants.find(name=tenant_name)
        except keystone_exceptions.NotFound:
            # encapsulate exceptions to make it more understandable
            # to user. Other exception handling mechanism can be added later
            LOG.error(exceptions.ResourceNotFoundException(
                ResourceType.tenant, tenant_name,
                cfg.CONF.SOURCE.os_cloud_name))
            return

        s_cloud_name = cfg.CONF.SOURCE.os_cloud_name
        t_cloud_name = cfg.CONF.TARGET.os_cloud_name

        # check whether the tenant has been migrated
        values = [tenant_name, s_cloud_name, t_cloud_name]
        m_tenant = tenants.get_migrated_tenant(values)

        # this task is intent to create proxy tenant only. Tenant related
        # resource can be migrated in separated task. Open to suggestions.
        if m_tenant is not None and m_tenant['state'] == "proxy_created":
            LOG.info("tenant {0} in cloud {1} has already been migrated"
                     .format(m_tenant["project_name"], s_cloud_name))
            return

        # check for tenant name duplication
        new_tenant_name = s_tenant.name
        try:
            found = self.ks_target.tenants.find(name=new_tenant_name)
            if found:
                LOG.info("Skipping Tenant '{0}' duplicates found on cloud '{1}'"
                         .format(found.name, t_cloud_name))
                return

        except keystone_exceptions.NotFound:
            # irrelevant exception - swallow
            pass

        # preparing for database record update
        tenant_data = {'project_name': s_tenant.name,
                       'src_uuid': s_tenant.id,
                       'src_cloud': s_cloud_name,
                       'new_project_name': new_tenant_name,
                       'dst_uuid': s_tenant.id,
                       'dst_cloud': t_cloud_name,
                       'images_migrated': '0',
                       'quota_updated': '0',
                       'state': "unknown"}

        # create a new tenant
        migrated_tenant = None
        try:
            migrated_tenant = self.ks_target.tenants.create(
                new_tenant_name,
                s_tenant.description,
                s_tenant.enabled)
        except IOError as (err_no, strerror):
            LOG.error("I/O error({0}): {1}".format(err_no, strerror))
    def test_execute_migrate_all_tenants(self):
        tenant_name = "Tenant_on_source_cloud"
        tenant_to_migrate = self.migration_task.ks_source.tenants.create(
            tenant_name, "for tenant migration test", True)

        tenant_name2 = "Tenant_on_source_cloud2"
        tenant_to_migrate2 = self.migration_task.ks_source.tenants.create(
            tenant_name2, "for tenant migration test", True)

        migrated_tenant = None
        migrated_tenant2 = None
        try:
            # migrate nothing
            self.migration_task.execute([])

            # migrate all tenant resources
            self.migration_task.execute(None)

            # get the tenant data that has been migrated from src to dst
            values = [tenant_name, cfg.CONF.SOURCE.os_cloud_name,
                      cfg.CONF.TARGET.os_cloud_name]
            tenant_data = tenants.get_migrated_tenant(values)

            tenant_new_name = tenant_data['new_project_name']
            migrated_tenant = self.migration_task.ks_target.tenants.\
                find(name=tenant_new_name)

            self.assertIsNotNone(migrated_tenant)

            values = [tenant_name2, cfg.CONF.SOURCE.os_cloud_name,
                      cfg.CONF.TARGET.os_cloud_name]
            tenant_data2 = tenants.get_migrated_tenant(values)

            tenant_new_name2 = tenant_data2['new_project_name']
            migrated_tenant2 = self.migration_task.ks_target.tenants.\
                find(name=tenant_new_name2)

            self.assertIsNotNone(migrated_tenant2)

        except keystone_exceptions.NotFound:
            self.fail()
        finally:
            self.clean_up(tenant_to_migrate, migrated_tenant)
            self.clean_up(tenant_to_migrate2, migrated_tenant2)
    def test_execute(self):
        tenant_name = "tenant_name"
        tenant_to_migrate = self.tenant_migration_task.ks_source.tenants. \
            create(tenant_name, "for projects quotas updating test", True)
        user_name = "user_name"
        user_to_migrate = self.tenant_migration_task.ks_source.users. \
            create(name=user_name, password="******")
        role_name = "role_name"
        role_to_migrate = self.tenant_migration_task.ks_source.roles. \
            create(role_name)
        self.tenant_migration_task.ks_source.roles.add_user_role(
            user_to_migrate,
            role_to_migrate,
            tenant_to_migrate)
        self.assertIn(role_to_migrate, self.tenant_migration_task.ks_source.
                      roles.roles_for_user(user_to_migrate,
                                           tenant_to_migrate))

        migrated_tenant = None
        migrated_user = None
        migrated_role = None
        try:
            self.tenant_migration_task.execute([tenant_name])
            self.role_migration_task.execute(None)
            self.user_migration_task.execute(None)
            self.binding_task.execute()

            # get the tenant data that has been migrated from src to dst
            values = [tenant_name, self.s_cloud_name, self.t_cloud_name]
            tenant_data = db_handler.get_migrated_tenant(values)
            tenant_new_name = tenant_data['new_project_name']

            migrated_tenant = self.tenant_migration_task.ks_target.tenants. \
                find(name=tenant_new_name)
            migrated_user = self.user_migration_task.ks_target.users. \
                find(name=user_name)
            migrated_role = self.role_migration_task.ks_target.roles. \
                find(name=role_name)

            self.assertIn(migrated_role, self.tenant_migration_task.ks_target.
                          roles.roles_for_user(migrated_user,
                                               migrated_tenant))

        except keystone_exceptions.NotFound as e:
            self.fail(e.message)
        finally:
            self.clean_up(tenant_to_migrate, migrated_tenant,
                          user_to_migrate, migrated_user,
                          role_to_migrate, migrated_role)
    def test_execute(self):
        tenant_name = "tenant_name"
        tenant_to_migrate = self.tenant_migration_task.ks_source.tenants. \
            create(tenant_name, "for projects quotas updating test", True)
        user_name = "user_name"
        user_to_migrate = self.tenant_migration_task.ks_source.users. \
            create(name=user_name, password="******")
        role_name = "role_name"
        role_to_migrate = self.tenant_migration_task.ks_source.roles. \
            create(role_name)
        self.tenant_migration_task.ks_source.roles.add_user_role(
            user_to_migrate, role_to_migrate, tenant_to_migrate)
        self.assertIn(
            role_to_migrate,
            self.tenant_migration_task.ks_source.roles.roles_for_user(
                user_to_migrate, tenant_to_migrate))

        migrated_tenant = None
        migrated_user = None
        migrated_role = None
        try:
            self.tenant_migration_task.execute([tenant_name])
            self.role_migration_task.execute(None)
            self.user_migration_task.execute(None)
            self.binding_task.execute()

            # get the tenant data that has been migrated from src to dst
            values = [tenant_name, self.s_cloud_name, self.t_cloud_name]
            tenant_data = db_handler.get_migrated_tenant(values)
            tenant_new_name = tenant_data['new_project_name']

            migrated_tenant = self.tenant_migration_task.ks_target.tenants. \
                find(name=tenant_new_name)
            migrated_user = self.user_migration_task.ks_target.users. \
                find(name=user_name)
            migrated_role = self.role_migration_task.ks_target.roles. \
                find(name=role_name)

            self.assertIn(
                migrated_role,
                self.tenant_migration_task.ks_target.roles.roles_for_user(
                    migrated_user, migrated_tenant))

        except keystone_exceptions.NotFound as e:
            self.fail(e.message)
        finally:
            self.clean_up(tenant_to_migrate, migrated_tenant, user_to_migrate,
                          migrated_user, role_to_migrate, migrated_role)
    def test_execute(self):
        tenant_name = "tenant_name"
        tenant_to_migrate = self.migration_task.ks_source.tenants.create(
            tenant_name, "for projects quotas updating test", True)

        migrated_tenant = None
        try:
            self.migration_task.execute([tenant_name])
            self.task.execute()

            # get the tenant data that has been migrated from src to dst
            values = [tenant_name, self.s_cloud_name, self.t_cloud_name]
            tenant_data = db_handler.get_migrated_tenant(values)

            tenant_new_name = tenant_data['new_project_name']
            migrated_tenant = self.migration_task.ks_target.tenants.\
                find(name=tenant_new_name)

            # get source project quota
            src_quota = self.nv_source.quotas.get(tenant_to_migrate.id)
            # get dest project quota
            dest_quota = self.nv_source.quotas.get(migrated_tenant.id)

            self.assertIsNotNone(migrated_tenant)
            self.assertEqual(1, tenant_data['quota_updated'])
            self.assertEqual(src_quota.metadata_items,
                             dest_quota.metadata_items)
            self.assertEqual(src_quota.injected_file_content_bytes,
                             dest_quota.injected_file_content_bytes)
            self.assertEqual(src_quota.ram, dest_quota.ram)
            self.assertEqual(src_quota.floating_ips,
                             dest_quota.floating_ips)
            self.assertEqual(src_quota.instances, dest_quota.instances)
            self.assertEqual(src_quota.injected_files,
                             dest_quota.injected_files)
            self.assertEqual(src_quota.cores, dest_quota.cores)

        except keystone_exceptions.NotFound as e:
            print str(e)
        finally:
            self.clean_up(tenant_to_migrate, migrated_tenant)
    def test_execute(self):
        tenant_name = "tenant_name"
        tenant_to_migrate = self.migration_task.ks_source.tenants.create(
            tenant_name, "for projects quotas updating test", True)

        migrated_tenant = None
        try:
            self.migration_task.execute([tenant_name])
            self.task.execute()

            # get the tenant data that has been migrated from src to dst
            values = [tenant_name, self.s_cloud_name, self.t_cloud_name]
            tenant_data = db_handler.get_migrated_tenant(values)

            tenant_new_name = tenant_data['new_project_name']
            migrated_tenant = self.migration_task.ks_target.tenants.\
                find(name=tenant_new_name)

            # get source project quota
            src_quota = self.nv_source.quotas.get(tenant_to_migrate.id)
            # get dest project quota
            dest_quota = self.nv_source.quotas.get(migrated_tenant.id)

            self.assertIsNotNone(migrated_tenant)
            self.assertEqual(1, tenant_data['quota_updated'])
            self.assertEqual(src_quota.metadata_items,
                             dest_quota.metadata_items)
            self.assertEqual(src_quota.injected_file_content_bytes,
                             dest_quota.injected_file_content_bytes)
            self.assertEqual(src_quota.ram, dest_quota.ram)
            self.assertEqual(src_quota.floating_ips, dest_quota.floating_ips)
            self.assertEqual(src_quota.instances, dest_quota.instances)
            self.assertEqual(src_quota.injected_files,
                             dest_quota.injected_files)
            self.assertEqual(src_quota.cores, dest_quota.cores)

        except keystone_exceptions.NotFound as e:
            self.fail(e.message)
        finally:
            self.clean_up(tenant_to_migrate, migrated_tenant)
    def test_tenant_migration(self):
        tenant_name = "tenant_test"
        tenant_to_migrate = self.ks_source.tenants.create(
            tenant_name, "for testing", True)

        self.reset_value()
        self.value['tenants_to_move'].append(tenant_name)
        flow.execute(self.value)

        tenant_target = None
        values_t = [tenant_name, self.s_cloud_name, self.t_cloud_name]
        try:
            tenant_target = self.ks_target.tenants.find(name=tenant_name)

            self.assertIsNotNone(tenant_target)

            tenant_data = tenants.get_migrated_tenant(values_t)

            self.assertEqual("proxy_created", tenant_data['state'])

        except ks_exceptions.NotFound, e:
            self.fail(e)
    def test_tenant_migration(self):
        tenant_name = "tenant_test"
        tenant_to_migrate = self.ks_source.tenants.create(
            tenant_name, "for testing", True)

        self.reset_value()
        self.value['tenants_to_move'].append(tenant_name)
        flow.execute(self.value)

        tenant_target = None
        values_t = [tenant_name, self.s_cloud_name, self.t_cloud_name]
        try:
            tenant_target = self.ks_target.tenants.find(name=tenant_name)

            self.assertIsNotNone(tenant_target)

            tenant_data = tenants.get_migrated_tenant(values_t)

            self.assertEqual("proxy_created", tenant_data['state'])

        except ks_exceptions.NotFound, e:
            self.fail(e)
    def test_execute(self):
        tenant_name = "Tenant_on_source_cloud"
        tenant_to_migrate = self.migration_task.ks_source.tenants.create(
            tenant_name, "for tenant migration test", True)

        migrated_tenant = None
        try:
            self.migration_task.execute(tenant_name)

            # get the tenant data that has been migrated from src to dst
            values = [tenant_name, cfg.CONF.SOURCE.os_cloud_name,
                      cfg.CONF.TARGET.os_cloud_name]
            tenant_data = tenants.get_migrated_tenant(values)

            tenant_new_name = tenant_data['new_project_name']
            migrated_tenant = self.migration_task.ks_target.tenants.\
                find(name=tenant_new_name)

            self.assertIsNotNone(migrated_tenant)

        except keystone_exceptions.NotFound as e:
            print str(e)
        finally:
            self.clean_up(tenant_to_migrate, migrated_tenant)
    def revert(self, images_to_migrate, tenant_to_process):

        if type(images_to_migrate) is list \
                and len(images_to_migrate) == 0 \
                and type(tenant_to_process) is list \
                and len(tenant_to_process) == 0:
            LOG.info("No image resource needs to be reverted.")
            return

        images_to_revert = []
        # revert given images
        if images_to_migrate:
            for img_id in images_to_migrate:
                try:
                    img = self.gl_source.images.get(img_id)
                    if img:
                        images_to_revert.append(img_id)

                except exc.HTTPNotFound:
                    LOG.error("Can not find image of id: '{0}' on cloud '{1}'"
                              .format(img_id, cfg.CONF.SOURCE.os_cloud_name))

        else:
            owner_tenants = tenant_to_process
            if not owner_tenants:
                owner_tenants = []
                for tenant in self.ks_source.tenants.list():
                    owner_tenants.append(tenant.name)

            all_images = self.gl_source.images.list()
            for image in all_images:
                if not image.is_public:
                    continue
                images_to_revert.append(image.id)

            for tenant_name in owner_tenants:

                s_cloud_name = cfg.CONF.SOURCE.os_cloud_name
                t_cloud_name = cfg.CONF.TARGET.os_cloud_name

                filter_values = [tenant_name, s_cloud_name, t_cloud_name]

                m_tenants = tenants.get_migrated_tenant(filter_values)
                migrated_tenant = m_tenants if m_tenants else None
                if not migrated_tenant:
                    LOG.info("Skipping image migration for tenant '%s'"
                             "since it has no migration record."
                             % tenant_name)
                    continue

                owned_images = self.gl_source.images.list(
                    owner=migrated_tenant['src_uuid'])
                for img in owned_images:
                    images_to_revert.append(img.id)

        for img_id in images_to_revert:
            # delete image from the target cloud
            try:
                img = self.gl_target.images.get(img_id)
                if img:
                    self.gl_target.images.delete(img)
            except exc.HTTPNotFound:
                LOG.info("Can not find image of id: '{0}' on cloud '{1}'"
                         .format(img_id, cfg.CONF.TARGET.os_cloud_name))

            # delete image record from flyway database
            try:
                img = self.gl_source.images.get(img_id)
                if img:
                    filter_values = [img.name, img.id, img.owner,
                                     cfg.CONF.SOURCE.os_cloud_name,
                                     cfg.CONF.TARGET.os_cloud_name]
                    m_image = images.get_migrated_image(filter_values)

                    if m_image is not None:
                        images.delete_migration_record(filter_values)

            except exc.HTTPNotFound:
                LOG.info("Can not find image of id: '{0}' on cloud '{1}'"
                         .format(img_id, cfg.CONF.SOURCE.os_cloud_name))
Example #17
0
    def execute(self, tenant_vm_dicts):

        """execute instance migration task

        :param tenant_vm_dicts: a dictionary which provides the tenant and
        particular instances of the tenant desired to migrate

        'tenant_vm_dicts' structure:
        ---- {tenant_name: list of vm ids,
        ----  tenant_name: list of vm ids,
        ----  ...}
        """

        if type(tenant_vm_dicts) is dict and len(tenant_vm_dicts) == 0:
            LOG.info("No VMs to be migrated.")
            return

        # collect servers from each given or existing tenant
        # vm_to_migrate is a <nova_client, vm_list> dictionary
        vm_to_migrate = {}
        source_nova_client = None

        if tenant_vm_dicts is not None:
            LOG.info("Migrating instances for tenants : [%s]"
                     % tenant_vm_dicts.keys())
            for tenant_name, vm_id_list in tenant_vm_dicts.iteritems():
                vm_list = []
                for vm_id in vm_id_list:
                    source_nova_client = get_nova_source(tenant_name)
                    try:
                        server = source_nova_client.servers.find(id=vm_id)
                    except nova_exceptions.NotFound:
                        raise exceptions.ResourceNotFoundException(
                            ResourceType.vm, vm_id, self.s_cloud_name)
                    vm_list.append(server)

                vm_to_migrate.update({source_nova_client: vm_list})
        else:
            LOG.info('Migrating instances for all tenants...')
            for tenant in self.ks_source.tenants.list():

                source_nova_client = get_nova_source(tenant.name)
                vm_list = []
                for server in source_nova_client.servers.list():
                    vm_list.append(server)

                vm_to_migrate.update({source_nova_client: vm_list})

        # migrate each server from each given or existing tenant
        for source_nova_client, vm_list in vm_to_migrate.iteritems():

            source_cloud = cfg.CONF.SOURCE.os_cloud_name
            target_cloud = cfg.CONF.TARGET.os_cloud_name
            tenant_name = source_nova_client.projectid
            values = [tenant_name, source_cloud, target_cloud]

            migrated_tenant = tenants.get_migrated_tenant(values)
            if not migrated_tenant:
                LOG.info("Skipping instances migration for tenant '%s' since "
                         "the tenant itself hasn't been migrated" % tenant_name)
                continue

            # check migrated tenant actually exist on target cloud
            dst_uuid = migrated_tenant['dst_uuid']
            try:
                dst_tenant = self.ks_target.tenants.find(id=dst_uuid)
            except keystone_exceptions.NotFound:
                LOG.error(
                    "Migrated tenant '{0}' required does not exist on "
                    "destination cloud {1}".format(tenant_name, target_cloud))
                # encapsulate exceptions to make it more understandable
                # to user. Other exception handling mechanism can be added later
                raise exceptions.ResourceNotFoundException(
                    ResourceType.tenant, tenant_name, self.t_cloud_name)

            target_nova_client = get_nova_target(dst_tenant.name)

            for vm in vm_list:
                self.create_proxy_vm(vm, source_nova_client,
                                     target_nova_client)

            # all VMs that has proxy created will potentially
            # be stopped and being migration. Loading details of them

            # There are several stages of migrating instances and the program
            # can fail at any stage. Loading migration record from database
            # can help with picking up from migration state left over in last
            #  run if there were any interruptions

            # states that are valid starting point of stopping instances
            stop_status = [InstanceMigrationState.proxy_launched,
                           InstanceMigrationState.stop_instance_failed]
            servers_to_stop = self.load_instances(stop_status)
            if servers_to_stop:
                self.stop_vms(target_nova_client, servers_to_stop)

            # only copy disk file for those instances of which the
            # corresponding destination instance that has been stopped
            # states that are valid starting point of stopping instances
            copy_states = [InstanceMigrationState.dst_instance_stopped,
                           InstanceMigrationState.disk_file_migrate_failed]
            servers_to_copy = self.load_instances(copy_states)
            if servers_to_copy:
                self.migrate_vms(source_nova_client, target_nova_client,
                                 servers_to_copy)

            # boot those instances that has disk file copied over
            boot_states = [InstanceMigrationState.disk_file_migrated,
                           InstanceMigrationState.instance_booting_failed]
            servers_to_boot = self.load_instances(boot_states)
            if servers_to_boot:
                self.start_vms(target_nova_client, source_nova_client,
                               servers_to_boot)
    def execute(self, images_to_migrate, tenant_to_process):
        """execute the image migration task

        :param tenant_to_process: list of tenants of which
        all images will be migrated
        :param images_to_migrate: list of IDs of images to be migrated
        """

        if type(images_to_migrate) is list \
                and len(images_to_migrate) == 0 \
                and type(tenant_to_process) is list \
                and len(tenant_to_process) == 0:
            LOG.info("No image resource needs to be migrated.")
            return

        images_to_move = []
        # migrate given images
        if images_to_migrate:
            for img_id in images_to_migrate:
                try:
                    img = self.gl_source.images.get(img_id)
                    img_owner_pair = {'img': img,
                                      'owner': getattr(img, 'owner', None)}
                    images_to_move.append(dict(img_owner_pair))

                except exc.HTTPNotFound:
                    LOG.error("Can not find image of id: '{0}' on cloud '{1}'"
                              .format(img_id, cfg.CONF.SOURCE.os_cloud_name))

        # migrate images from given tenants or all images
        else:
            owner_tenants = tenant_to_process
            if not owner_tenants:
                owner_tenants = []
                LOG.info("Migrating images for all tenants...")
                for tenant in self.ks_source.tenants.list():
                    owner_tenants.append(tenant.name)

            # migrate all public images
            all_images = self.gl_source.images.list()
            for image in all_images:
                if not image.is_public:
                    continue

                # check whether it has been migrated
                if self.check_image_migrated(image):
                    continue

                img_owner_pair = {'img': image, 'owner': None}
                images_to_move.append(dict(img_owner_pair))

            # migrate images owned by tenants
            for tenant_name in owner_tenants:

                s_cloud_name = cfg.CONF.SOURCE.os_cloud_name
                t_cloud_name = cfg.CONF.TARGET.os_cloud_name

                LOG.info("Processing tenant '%s'..." % tenant_name)
                filter_values = [tenant_name, s_cloud_name, t_cloud_name]

                m_tenants = tenants.get_migrated_tenant(filter_values)
                migrated_tenant = m_tenants if m_tenants else None
                if not migrated_tenant:
                    LOG.info("Skipping image migration for tenant '%s'"
                             "since it has no migration record."
                             % tenant_name)
                    continue
                if migrated_tenant['images_migrated']:
                    # images already migrated for this tenant
                    LOG.info("All images have been migrated for tenant '%s'"
                             % migrated_tenant['project_name'])
                    return

                owned_images = self.gl_source.images.list(
                    owner=migrated_tenant['src_uuid'])
                for img in owned_images:
                    img_owner_pair = {'img': img,
                                      'owner': migrated_tenant['dst_uuid']}
                    images_to_move.append(dict(img_owner_pair))

        if image_scheduler is not None:
            images_to_move = image_scheduler.sort(images_to_move)

        for image_owner_pair in images_to_move:
            # check whether it has been migrated
            if self.check_image_migrated(image_owner_pair['img']):
                LOG.info("image [Name: '{0}', ID: '{1}' has been migrated"
                         .format(image_owner_pair['img'].name,
                                 image_owner_pair['img'].id))
                continue

            self.migrate_one_image(image_owner_pair['img'],
                                   image_owner_pair['owner'])
    def revert(self, images_to_migrate, tenant_to_process):

        if type(images_to_migrate) is list \
                and len(images_to_migrate) == 0 \
                and type(tenant_to_process) is list \
                and len(tenant_to_process) == 0:
            LOG.info("No image resource needs to be reverted.")
            return

        images_to_revert = []
        # revert given images
        if images_to_migrate:
            for img_id in images_to_migrate:
                try:
                    img = self.gl_source.images.get(img_id)
                    if img:
                        images_to_revert.append(img_id)

                except exc.HTTPNotFound:
                    LOG.error("Can not find image of id: '{0}' on cloud '{1}'".
                              format(img_id, cfg.CONF.SOURCE.os_cloud_name))

        else:
            owner_tenants = tenant_to_process
            if not owner_tenants:
                owner_tenants = []
                for tenant in self.ks_source.tenants.list():
                    owner_tenants.append(tenant.name)

            all_images = self.gl_source.images.list()
            for image in all_images:
                if not image.is_public:
                    continue
                images_to_revert.append(image.id)

            for tenant_name in owner_tenants:

                s_cloud_name = cfg.CONF.SOURCE.os_cloud_name
                t_cloud_name = cfg.CONF.TARGET.os_cloud_name

                filter_values = [tenant_name, s_cloud_name, t_cloud_name]

                m_tenants = tenants.get_migrated_tenant(filter_values)
                migrated_tenant = m_tenants if m_tenants else None
                if not migrated_tenant:
                    LOG.info("Skipping image migration for tenant '%s'"
                             "since it has no migration record." % tenant_name)
                    continue

                owned_images = self.gl_source.images.list(
                    owner=migrated_tenant['src_uuid'])
                for img in owned_images:
                    images_to_revert.append(img.id)

        for img_id in images_to_revert:
            # delete image from the target cloud
            try:
                img = self.gl_target.images.get(img_id)
                if img:
                    self.gl_target.images.delete(img)
            except exc.HTTPNotFound:
                LOG.info(
                    "Can not find image of id: '{0}' on cloud '{1}'".format(
                        img_id, cfg.CONF.TARGET.os_cloud_name))

            # delete image record from flyway database
            try:
                img = self.gl_source.images.get(img_id)
                if img:
                    filter_values = [
                        img.name, img.id, img.owner,
                        cfg.CONF.SOURCE.os_cloud_name,
                        cfg.CONF.TARGET.os_cloud_name
                    ]
                    m_image = images.get_migrated_image(filter_values)

                    if m_image is not None:
                        images.delete_migration_record(filter_values)

            except exc.HTTPNotFound:
                LOG.info(
                    "Can not find image of id: '{0}' on cloud '{1}'".format(
                        img_id, cfg.CONF.SOURCE.os_cloud_name))
    def execute(self, images_to_migrate, tenant_to_process):
        """execute the image migration task

        :param tenant_to_process: list of tenants of which
        all images will be migrated
        :param images_to_migrate: list of IDs of images to be migrated
        """

        if type(images_to_migrate) is list \
                and len(images_to_migrate) == 0 \
                and type(tenant_to_process) is list \
                and len(tenant_to_process) == 0:
            LOG.info("No image resource needs to be migrated.")
            return

        images_to_move = []
        # migrate given images
        if images_to_migrate:
            for img_id in images_to_migrate:
                try:
                    img = self.gl_source.images.get(img_id)
                    img_owner_pair = {
                        'img': img,
                        'owner': getattr(img, 'owner', None)
                    }
                    images_to_move.append(dict(img_owner_pair))

                except exc.HTTPNotFound:
                    LOG.error("Can not find image of id: '{0}' on cloud '{1}'".
                              format(img_id, cfg.CONF.SOURCE.os_cloud_name))

        # migrate images from given tenants or all images
        else:
            owner_tenants = tenant_to_process
            if not owner_tenants:
                owner_tenants = []
                LOG.info("Migrating images for all tenants...")
                for tenant in self.ks_source.tenants.list():
                    owner_tenants.append(tenant.name)

            # migrate all public images
            all_images = self.gl_source.images.list()
            for image in all_images:
                if not image.is_public:
                    continue

                # check whether it has been migrated
                if self.check_image_migrated(image):
                    continue

                img_owner_pair = {'img': image, 'owner': None}
                images_to_move.append(dict(img_owner_pair))

            # migrate images owned by tenants
            for tenant_name in owner_tenants:

                s_cloud_name = cfg.CONF.SOURCE.os_cloud_name
                t_cloud_name = cfg.CONF.TARGET.os_cloud_name

                LOG.info("Processing tenant '%s'..." % tenant_name)
                filter_values = [tenant_name, s_cloud_name, t_cloud_name]

                m_tenants = tenants.get_migrated_tenant(filter_values)
                migrated_tenant = m_tenants if m_tenants else None
                if not migrated_tenant:
                    LOG.info("Skipping image migration for tenant '%s'"
                             "since it has no migration record." % tenant_name)
                    continue
                if migrated_tenant['images_migrated']:
                    # images already migrated for this tenant
                    LOG.info("All images have been migrated for tenant '%s'" %
                             migrated_tenant['project_name'])
                    return

                owned_images = self.gl_source.images.list(
                    owner=migrated_tenant['src_uuid'])
                for img in owned_images:
                    img_owner_pair = {
                        'img': img,
                        'owner': migrated_tenant['dst_uuid']
                    }
                    images_to_move.append(dict(img_owner_pair))

        if image_scheduler is not None:
            images_to_move = image_scheduler.sort(images_to_move)

        for image_owner_pair in images_to_move:
            # check whether it has been migrated
            if self.check_image_migrated(image_owner_pair['img']):
                LOG.info(
                    "image [Name: '{0}', ID: '{1}' has been migrated".format(
                        image_owner_pair['img'].name,
                        image_owner_pair['img'].id))
                continue

            self.migrate_one_image(image_owner_pair['img'],
                                   image_owner_pair['owner'])