예제 #1
0
 def __init__(self, cloud):
     super(ServerGroupsHandler, self).__init__()
     self.cloud = cloud
     self.compute = self.cloud.resources[utils.COMPUTE_RESOURCE]
     self.identity = self.cloud.resources[utils.IDENTITY_RESOURCE]
     self.config = copy.deepcopy(self.identity.config)
     self.tenant_name_map = mapper.Mapper('tenant_map')
예제 #2
0
    def get_similar_tenants(self):
        """
        Get SRC tenant ID to DST tenant ID mapping.

        :return dict: {<src_tenant_id>: <dst_tenant_id>, ...}
        """

        src_identity = self.src_cloud.resources[utils.IDENTITY_RESOURCE]
        dst_identity = self.dst_cloud.resources[utils.IDENTITY_RESOURCE]
        tenant_name_map = mapper.Mapper('tenant_map')

        src_tenants = src_identity.get_tenants_list()
        dst_tenants = dst_identity.get_tenants_list()

        dst_tenant_map = {
            tenant.name.lower(): tenant.id
            for tenant in dst_tenants
        }

        similar_tenants = {}

        for src_tenant in src_tenants:
            src_tnt_name = tenant_name_map.map(src_tenant.name).lower()
            if src_tnt_name in dst_tenant_map:
                similar_tenants[src_tenant.id] = dst_tenant_map[src_tnt_name]

        return similar_tenants
예제 #3
0
 def __init__(self, config, cloud):
     super(KeystoneIdentity, self).__init__()
     self.config = config
     self.cloud = cloud
     self.filter_tenant_id = None
     self.mysql_connector = cloud.mysql_connector('keystone')
     self.templater = Templater()
     self.generator = GeneratorPassword()
     self.defaults = {}
     self.tenant_name_map = mapper.Mapper('tenant_map')
예제 #4
0
 def __init__(self, config, cloud):
     super(CinderStorage, self).__init__(config)
     self.ssh_host = config.cloud.ssh_host
     self.mysql_host = config.mysql.db_host \
         if config.mysql.db_host else self.ssh_host
     self.cloud = cloud
     self.identity_client = cloud.resources[utils.IDENTITY_RESOURCE]
     self.mysql_connector = cloud.mysql_connector('cinder')
     self.volume_filter = None
     self.filter_tenant_id = None
     self.tenant_name_map = mapper.Mapper('tenant_map')
     self.attr_override = override.AttributeOverrides.from_filename(
         config.migrate.override_rules, 'volumes')
예제 #5
0
 def __init__(self, config, cloud):
     super(KeystoneIdentity, self).__init__()
     self.config = config
     self.cloud = cloud
     self.filter_tenant_id = None
     self.mysql_connector = cloud.mysql_connector('keystone')
     self.templater = Templater()
     self.generator = GeneratorPassword()
     self.defaults = {}
     self.tenant_name_map = mapper.Mapper('tenant_map')
     self.state_notifier = notifiers.MigrationStateNotifier()
     for observer in cloud.migration_observers:
         self.state_notifier.add_observer(observer)
예제 #6
0
 def __init__(self, config, cloud):
     self.config = config
     self.ssh_host = config.cloud.ssh_host
     self.cloud = cloud
     self.identity_client = cloud.resources['identity']
     self.filter_tenant_id = None
     self.filter_image = []
     # get mysql settings
     self.mysql_connector = cloud.mysql_connector('glance')
     self.runner = remote_runner.RemoteRunner(self.ssh_host,
                                              self.config.cloud.ssh_user)
     self._image_filter = None
     self.tenant_name_map = mapper.Mapper('tenant_map')
     super(GlanceImage, self).__init__(config)
예제 #7
0
 def __init__(self, config, cloud):
     super(NovaCompute, self).__init__()
     self.config = config
     self.cloud = cloud
     self.filter_tenant_id = None
     self.identity = cloud.resources['identity']
     self.mysql_connector = cloud.mysql_connector('nova')
     # List of instance IDs which failed to create
     self.processing_instances = []
     self.failed_instances = []
     self.tenant_name_map = mapper.Mapper('tenant_map')
     self.instance_info_caches = instance_info_caches.InstanceInfoCaches(
         self.get_db_connection())
     self.attr_override = override.AttributeOverrides.from_filename(
         config.migrate.override_rules, 'servers')
예제 #8
0
    def run(self, **kwargs):
        LOG.debug("Checking networks...")
        has_overlapping_resources = False
        has_invalid_resources = False

        src_net = self.src_cloud.resources[utils.NETWORK_RESOURCE]
        dst_net = self.dst_cloud.resources[utils.NETWORK_RESOURCE]
        src_compute = self.src_cloud.resources[utils.COMPUTE_RESOURCE]

        tenant_ids = kwargs.get('search_opts_tenant', {}).get('tenant_id')
        search_opts = kwargs.get('search_opts', {})

        LOG.debug("Retrieving Network information from Source cloud...")
        ports = src_net.get_ports_list()
        src_net_info = NetworkInfo(src_net.read_info(tenant_id=tenant_ids),
                                   ports)
        LOG.debug("Retrieving Network information from Destination cloud...")
        dst_net_info = NetworkInfo(dst_net.read_info())
        LOG.debug("Retrieving Compute information from Source cloud...")
        src_compute_info = ComputeInfo(src_compute, search_opts, tenant_ids)

        ext_net_map = mapper.Mapper('ext_network_map')

        # Check external networks mapping
        if ext_net_map:
            LOG.info("Check external networks mapping...")
            invalid_ext_net_ids = src_net_info.get_invalid_ext_net_ids(
                dst_net_info, ext_net_map)
            if invalid_ext_net_ids['src_nets'] or \
                    invalid_ext_net_ids['dst_nets']:
                invalid_src_nets = invalid_ext_net_ids['src_nets']
                invalid_dst_nets = invalid_ext_net_ids['dst_nets']
                invalid_nets_str = ""

                if invalid_src_nets:
                    invalid_nets_str = 'Source cloud:\n' + \
                                       '\n'.join(invalid_src_nets) + '\n'
                if invalid_dst_nets:
                    invalid_nets_str += 'Destination cloud:\n' + \
                                        '\n'.join(invalid_dst_nets) + '\n'

                LOG.error(
                    "External networks mapping file has non-existing "
                    "network UUIDs defined:\n%s\nPlease update '%s' "
                    "file with correct values and re-run networks "
                    "check.", invalid_nets_str, self.cfg.migrate.ext_net_map)
                has_invalid_resources = True

        # Check networks' segmentation IDs overlap
        LOG.info("Check networks' segmentation IDs overlapping...")
        nets_overlapping_seg_ids = (
            src_net_info.get_overlapping_seg_ids(dst_net_info))
        if nets_overlapping_seg_ids:
            LOG.warning(
                "Segmentation IDs for these networks in source cloud "
                "WILL NOT BE KEPT regardless of options defined in "
                "config, because networks with the same segmentation "
                "IDs already exist in destination: %s.",
                '\n'.join([n['src_net_id'] for n in nets_overlapping_seg_ids]))

        # Check external subnets overlap
        LOG.info("Check external subnets overlapping...")
        overlapping_external_subnets = (
            src_net_info.get_overlapping_external_subnets(
                dst_net_info, ext_net_map))
        if overlapping_external_subnets:
            pool_fmt = '"{pool}" pool of subnet "{snet_name}" ({snet_id})'
            fmt = "{src_pool} overlaps with {dst_pool}"
            overlapping_nets = []

            for snet in overlapping_external_subnets:
                overlapping_nets.append(
                    fmt.format(src_pool=pool_fmt.format(
                        pool=snet['src_subnet']['allocation_pools'],
                        snet_name=snet['src_subnet']['name'],
                        snet_id=snet['src_subnet']['id']),
                               dst_pool=pool_fmt.format(
                                   pool=snet['dst_subnet']['allocation_pools'],
                                   snet_name=snet['dst_subnet']['name'],
                                   snet_id=snet['dst_subnet']['id'],
                               )))

            message = ("Following external networks have overlapping "
                       "allocation pools in source and destination:\n{}.\nTo "
                       "resolve this:\n"
                       " 1. Manually change allocation pools in source or "
                       "destination networks to be identical;\n"
                       " 2. Use '[migrate] ext_net_map' external networks "
                       "mapping. Floating IPs will NOT BE KEPT in that "
                       "case.".format('\n'.join(overlapping_nets)))

            LOG.error(message)
            has_overlapping_resources = True

        # Check floating IPs overlap
        LOG.info("Check floating IPs overlapping...")
        floating_ips = src_net_info.list_overlapping_floating_ips(
            dst_net_info, ext_net_map)
        if floating_ips:
            LOG.error(
                "Following floating IPs from source cloud already exist "
                "in destination, but either tenant, or external "
                "network doesn't match source cloud floating IP: %s\n"
                "In order to resolve you'd need to either delete "
                "floating IP from destination, or recreate floating "
                "IP so that they match fully in source and destination.",
                '\n'.join(floating_ips))
            has_overlapping_resources = True

        # Check busy physical networks on DST of FLAT network type
        LOG.info("Check busy physical networks for FLAT network type...")
        busy_flat_physnets = src_net_info.busy_flat_physnets(
            dst_net_info, ext_net_map)
        if busy_flat_physnets:
            LOG.error(
                "Flat network(s) allocated in different physical "
                "network(s) exist in destination cloud:\n%s\nIn order "
                "to resolve flat networks in the list must be "
                "connected to the same physical network in source and "
                "destination.",
                '\n'.join([str(n) for n in busy_flat_physnets]))
            has_overlapping_resources = True

        # Check physical networks existence on DST for VLAN network type
        LOG.info("Check physical networks existence for VLAN network type...")
        dst_neutron_client = dst_net.neutron_client
        missing_vlan_physnets = src_net_info.missing_vlan_physnets(
            dst_net_info, dst_neutron_client, ext_net_map)
        if missing_vlan_physnets:
            LOG.error(
                "Following physical networks are not present in "
                "destination, but required by source cloud networks: "
                "%s\nIn order to resolve make sure neutron has "
                "required physical networks defined in config.",
                '\n'.join(missing_vlan_physnets))

            has_overlapping_resources = True

        # Check VMs spawned directly in external network
        LOG.info("Check VMs spawned directly in external networks...")
        devices = src_net_info.get_devices_from_external_networks()
        vms_list = src_compute_info.list_vms_in_external_network(devices)
        if vms_list:
            LOG.warning(
                'Following VMs are booted directly in external '
                'network, which is not recommended: %s', vms_list)

        # Print LOG message with all overlapping stuff and abort migration
        if has_overlapping_resources or has_invalid_resources:
            raise exception.AbortMigrationError(
                "There is a number of overlapping/invalid network resources "
                "which require manual resolution. See error messages above "
                "for details.")