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')
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
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')
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')
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)
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)
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')
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.")