def _get_dns_ips(self, member, dns_member_settings): member_dns_ip = None member_dns_ipv6 = None member_name = member['host_name'] member_ip, member_ipv6 = self._get_lan1_ips(member) if member_name in dns_member_settings: dns_settings = dns_member_settings[member_name] # Assign IPv4 address if dns_settings.get('use_lan_port'): member_dns_ip = member_ip elif dns_settings.get('use_lan2_port'): l2 = member.get('lan2_port_setting') if l2 and l2.get('network_setting'): member_dns_ip = l2['network_setting'].get('address') elif dns_settings.get('use_mgmt_port'): n_info = member.get('node_info') if n_info and n_info[0].get('mgmt_network_setting'): member_dns_ip = n_info[0]['mgmt_network_setting'].get( 'address') elif dns_settings.get('additional_ip_list'): for ip in dns_settings.get('additional_ip_list'): if utils.get_ip_version(ip) == 4: member_dns_ip = ip break # If ip is still blank fallback to member ip if not member_dns_ip: member_dns_ip = member_ip # Assign IPv6 address if dns_settings.get('use_lan_ipv6_port'): member_dns_ipv6 = member_ipv6 elif dns_settings.get('use_lan2_ipv6_port'): l2 = member.get('lan2_port_setting') if l2 and l2.get('v6_network_setting'): member_dns_ipv6 = l2['v6_network_setting'].get( 'virtual_ip') elif dns_settings.get('use_mgmt_ipv6_port'): n_info = member.get('node_info') if n_info and n_info[0].get('v6_mgmt_network_setting'): member_dns_ipv6 = n_info[0]['v6_mgmt_network_setting'].get( 'virtual_ip') elif dns_settings.get('additional_ip_list'): for ip in dns_settings.get('additional_ip_list'): if utils.get_ip_version(ip) == 6: member_dns_ipv6 = ip break # If ipv6 is still blank fallback to member ipv6 if not member_dns_ipv6: member_dns_ipv6 = member_ipv6 return member_dns_ip, member_dns_ipv6
def _get_dns_ips(self, member, dns_member_settings): member_dns_ip = None member_dns_ipv6 = None member_name = member['host_name'] member_ip, member_ipv6 = self._get_lan1_ips(member) if member_name in dns_member_settings: dns_settings = dns_member_settings[member_name] # Assign IPv4 address if dns_settings.get('use_lan_port'): member_dns_ip = member_ip elif dns_settings.get('use_lan2_port'): l2 = member.get('lan2_port_setting') if l2 and l2.get('network_setting'): member_dns_ip = l2['network_setting'].get('address') elif dns_settings.get('use_mgmt_port'): n_info = member.get('node_info') if n_info and n_info[0].get('mgmt_network_setting'): member_dns_ip = n_info[0]['mgmt_network_setting'].get( 'address') elif dns_settings.get('additional_ip_list'): for ip in dns_settings.get('additional_ip_list'): if utils.get_ip_version(ip) == 4: member_dns_ip = ip break # If ip is still blank fallback to member ip if not member_dns_ip: member_dns_ip = member_ip # Assign IPv6 address if dns_settings.get('use_lan_ipv6_port'): member_dns_ipv6 = member_ipv6 elif dns_settings.get('use_lan2_ipv6_port'): l2 = member.get('lan2_port_setting') if l2 and l2.get('v6_network_setting'): member_dns_ipv6 = l2['v6_network_setting'].get( 'virtual_ip') elif dns_settings.get('use_mgmt_ipv6_port'): n_info = member.get('node_info') if n_info and n_info[0].get('v6_mgmt_network_setting'): member_dns_ipv6 = n_info[0]['v6_mgmt_network_setting'].get( 'virtual_ip') elif dns_settings.get('additional_ip_list'): for ip in dns_settings.get('additional_ip_list'): if utils.get_ip_version(ip) == 6: member_dns_ipv6 = ip break # If ipv6 is still blank fallback to member ipv6 if not member_dns_ipv6: member_dns_ipv6 = member_ipv6 return member_dns_ip, member_dns_ipv6
def test_get_ip_version(self): ips = ('10.10.0.1', '8.8.8.8') for ip in ips: self.assertEqual(4, utils.get_ip_version(ip)) ips = ('fffe::1', '2001:ff::1') for ip in ips: self.assertEqual(6, utils.get_ip_version(ip)) # invalid addresses ips = ('1.0.1.555', '2001:gg:1') for ip in ips: self.assertRaises(netaddr.core.AddrFormatError, utils.get_ip_version, ip)
def test_get_ip_version(self): ips = ('10.10.0.1', '8.8.8.8') for ip in ips: self.assertEqual(4, utils.get_ip_version(ip)) ips = ('fffe::1', '2001:ff::1') for ip in ips: self.assertEqual(6, utils.get_ip_version(ip)) # invalid addresses ips = ('1.0.1.555', '2001:gg:1') for ip in ips: self.assertRaises(netaddr.core.AddrFormatError, utils.get_ip_version, ip)
def _report_sync_time(self): if self.grid_config.report_grid_sync_time is False: return conn = self.grid_config.gm_connector host_ip = getattr(conn, "host") if utils.get_ip_version(host_ip) == 4: gm = ib_objects.Member.search(conn, ipv4_address=host_ip) else: gm = ib_objects.Member.search(conn, ipv6_address=host_ip) sync_info = ( str(self.grid_config.grid_id) + ":" + self.hostname + " => " + self.last_sync_time.strftime("%Y-%m-%d %H:%M:%S") ) sync_info_list = gm.extattrs.get(const.EA_LAST_GRID_SYNC_TIME) if sync_info_list: # if a single entry exits. NIOS returns as string rather than list. if isinstance(sync_info_list, six.string_types): sync_info_list = [sync_info_list] found_sync_idx_lst = [idx for idx, si in enumerate(sync_info_list) if self.hostname in si] if found_sync_idx_lst: sync_info_list[found_sync_idx_lst[0]] = sync_info else: sync_info_list.append(sync_info) else: sync_info_list = [sync_info] gm.extattrs.set(const.EA_LAST_GRID_SYNC_TIME, sync_info_list) gm.update()
def _get_gm_info(self): """Get detail GM info. 'grid_master_host' configuration accepts host IP or name of GM, so we need to figure whether hostname is used or ip address for either ipv4 or ipv6. """ gm_ipv4 = None gm_ipv6 = None gm_hostname = None gm_host = self._grid_config.grid_master_host if utils.is_valid_ip(gm_host): ip_version = utils.get_ip_version(gm_host) if ip_version == 4: gm_ipv4 = gm_host else: gm_ipv6 = gm_host else: gm_hostname = gm_host return {'ipv4': gm_ipv4, 'ipv6': gm_ipv6, 'host': gm_hostname}
def _get_gm_info(self): """Get detail GM info. 'grid_master_host' configuration accepts host IP or name of GM, so we need to figure whether hostname is used or ip address for either ipv4 or ipv6. """ gm_ipv4 = None gm_ipv6 = None gm_hostname = None gm_host = self._grid_config.grid_master_host if utils.is_valid_ip(gm_host): ip_version = utils.get_ip_version(gm_host) if ip_version == 4: gm_ipv4 = gm_host else: gm_ipv6 = gm_host else: gm_hostname = gm_host return {'ipv4': gm_ipv4, 'ipv6': gm_ipv6, 'host': gm_hostname}
def sync_neutron_to_infoblox(context, credentials, grid_manager): """Sync neutron objects to Infoblox grid Prerequisites: 1. network views to sync must have "Cloud Adapter ID" EA set. 2. infoblox agent sync should have been processed and updated members and network views. """ LOG.info("Starting migration...\n") delete_unknown_ips = cfg.CONF.delete_unknown_ips grid_config = grid_manager.grid_config grid_id = grid_config.grid_id session = context.session neutron_api = neutron_client.Client(**credentials) payload = neutron_api.list_networks() networks = payload['networks'] if not networks: LOG.info("No network exists...Exiting...") return payload = neutron_api.list_subnets() subnets = payload['subnets'] if not subnets: LOG.info("No subnet exists...Exiting...") return payload = neutron_api.list_ports() ports = payload['ports'] nova_api = nova_client.Client(NOVA_API_VERSION, session=credentials['session']) instance_names_by_instance_id = dict() instance_names_by_floating_ip = dict() for server in nova_api.servers.list(search_opts={'all_tenants': 1}): instance_names_by_instance_id[server.id] = server.name floating_ips = [] for net in server.addresses: floating_ips += [ ip['addr'] for ip in server.addresses[net] if ip['OS-EXT-IPS:type'] == 'floating' ] for fip in floating_ips: instance_names_by_floating_ip[fip] = server.name user_id = neutron_api.httpclient.get_user_id() user_tenant_id = neutron_api.httpclient.get_project_id() ib_networks = [] should_exit = False # sync subnets for subnet in subnets: subnet_id = subnet['id'] subnet_name = subnet['name'] network_id = subnet['network_id'] network = utils.find_one_in_list('id', network_id, networks) if not network: LOG.warning("network (%s) is not found. Skipping subnet (%s)", network_id, subnet_id) continue network_name = network['name'] ib_cxt = ib_context.InfobloxContext(context, user_id, network, subnet, grid_config, plugin=neutron_api) db_mapped_netview = dbi.get_network_view_by_mapping( session, grid_id=grid_id, network_id=network_id, subnet_id=subnet_id) if db_mapped_netview: LOG.info("Mapping found for network (%s), subnet (%s)", network_name, subnet_name) if len(db_mapped_netview) > 1: LOG.warning("More that one db_mapped_netview returned") if delete_unknown_ips: ib_network = ib_objects.Network.search( ib_cxt.connector, network_view=db_mapped_netview[0].network_view, cidr=subnet.get('cidr')) ib_networks.append(ib_network) continue ipam_controller = ipam.IpamSyncController(ib_cxt) dns_controller = dns.DnsController(ib_cxt) rollback_list = [] try: ib_network = ipam_controller.create_subnet(rollback_list) if ib_network: if delete_unknown_ips: ib_networks.append(ib_network) dns_controller.create_dns_zones(rollback_list) LOG.info("Created network (%s), subnet (%s)", network_name, subnet_name) except Exception as e: LOG.error(_LE("Error occurred: %(error)s"), {'error': e}) for ib_obj in reversed(rollback_list): try: ib_obj.delete() except ib_exc.InfobloxException as e: LOG.warning( _LW("Unable to delete %(obj)s due to " "error: %(error)s."), { 'obj': ib_obj, 'error': e }) should_exit = True break if should_exit: LOG.info("Exiting due to the error in creating subnet...") return # sync ports for port in ports: port_id = port['id'] port_name = port['name'] port_mac_address = port['mac_address'] tenant_id = port.get('tenant_id') or user_tenant_id network_id = port['network_id'] device_owner = port['device_owner'] device_id = port['device_id'] instance_name = (instance_names_by_instance_id[device_id] if device_id in instance_names_by_instance_id else None) network = utils.find_one_in_list('id', network_id, networks) if not network: LOG.error("network (%s) not found", network_id) break for ip_set in port.get('fixed_ips'): subnet_id = ip_set['subnet_id'] ip_address = ip_set['ip_address'] LOG.info("Adding port for %s: %s...", device_owner, ip_address) subnet = utils.find_one_in_list('id', subnet_id, subnets) if not subnet: should_exit = True LOG.error("subnet (%s) not found", subnet_id) break ib_cxt = ib_context.InfobloxContext(context, user_id, network, subnet, grid_config, plugin=neutron_api) connector = ib_cxt.connector netview = ib_cxt.mapping.network_view search_fields = {'network_view': netview, 'ip_address': ip_address} obj_type = ('ipv4address' if utils.get_ip_version(ip_address) == 4 else 'ipv6address') ib_address = connector.get_object(obj_type, search_fields, return_fields=['objects'], force_proxy=True) if ib_address and ib_address[0]['objects']: LOG.info("%s is found...no need to create", ip_address) continue ipam_controller = ipam.IpamSyncController(ib_cxt) dns_controller = dns.DnsController(ib_cxt) # for a floating ip port, check for its association. # if associated, then port info needs to be the associated port, # not the floating ip port because the associated port contains # actual attached device info is_floating_ip = False if ip_address in instance_names_by_floating_ip: db_floatingip = dbi.get_floatingip_by_ip_address( session, ip_address) db_port = dbi.get_port_by_id(session, db_floatingip.fixed_port_id) port_id = db_port.id port_name = db_port.name tenant_id = db_port.tenant_id device_id = db_port.device_id device_owner = db_port.device_owner instance_name = instance_names_by_floating_ip[ip_address] is_floating_ip = True allocated_ip = ipam_controller.allocate_specific_ip( ip_address, port_mac_address, port_id, tenant_id, device_id, device_owner) if allocated_ip and device_owner: try: dns_controller.bind_names(allocated_ip, instance_name, port_id, tenant_id, device_id, device_owner, is_floating_ip, port_name) except Exception as e: should_exit = True LOG.error("Unable to allocate ip (%s): %s", ip_address, e) ipam_controller.deallocate_ip(allocated_ip) break LOG.info("Allocated %s", ip_address) if should_exit: LOG.info("Existing due to error in port creation...") break if delete_unknown_ips: LOG.info("Start deleting unknown Fixed IP's from Infoblox...") for ib_network in ib_networks: nw_ea = ib_network.extattrs # Skip network if it doesn't have EA or if EA indicates it's # shared or external. if (not nw_ea or nw_ea.get('Is External') or nw_ea.get('Is Shared')): continue LOG.info("Searching for Fixed IP: network_view='%s', cidr='%s'" % (ib_network.network_view, ib_network.network)) fixed_ips = ib_objects.FixedAddress.search_all( ib_cxt.connector, network_view=ib_network.network_view, network=ib_network.network) if not fixed_ips: LOG.info("No FixedIP found: network_view='%s', cidr='%s'" % (ib_network.network_view, ib_network.network)) continue for fixed_ip in fixed_ips: ea = fixed_ip.extattrs port_id = None if ea: port_id = ea.get('Port ID') # Delete Fixed IP if: # - Fixed IP does not have 'Port ID' EA, or # - No port_id in neutron matches 'Port ID' EA value if not (port_id and utils.find_one_in_list('id', port_id, ports)): LOG.info("Deleting Fixed IP from Infoblox: '%s'" % fixed_ip) fixed_ip.delete() LOG.info("Ending migration...")
def sync_neutron_to_infoblox(context, credentials, grid_manager): """Sync neutron objects to Infoblox grid Prerequisites: 1. network views to sync must have "Cloud Adapter ID" EA set. 2. infoblox agent sync should have been processed and updated members and network views. """ LOG.info("Starting migration...\n") delete_unknown_ips = cfg.CONF.delete_unknown_ips grid_config = grid_manager.grid_config grid_id = grid_config.grid_id session = context.session neutron_api = neutron_client.Client(**credentials) payload = neutron_api.list_networks() networks = payload['networks'] if not networks: LOG.info("No network exists...Exiting...") return payload = neutron_api.list_subnets() subnets = payload['subnets'] if not subnets: LOG.info("No subnet exists...Exiting...") return payload = neutron_api.list_ports() ports = payload['ports'] nova_api = nova_client.Client(NOVA_API_VERSION, session=credentials['session']) instance_names_by_instance_id = dict() instance_names_by_floating_ip = dict() for server in nova_api.servers.list(search_opts={'all_tenants': 1}): instance_names_by_instance_id[server.id] = server.name floating_ips = [] for net in server.addresses: floating_ips += [ip['addr'] for ip in server.addresses[net] if ip['OS-EXT-IPS:type'] == 'floating'] for fip in floating_ips: instance_names_by_floating_ip[fip] = server.name user_id = neutron_api.httpclient.get_user_id() user_tenant_id = neutron_api.httpclient.get_project_id() ib_networks = [] should_exit = False # sync subnets for subnet in subnets: subnet_id = subnet['id'] subnet_name = subnet['name'] network_id = subnet['network_id'] network = utils.find_one_in_list('id', network_id, networks) if not network: LOG.warning("network (%s) is not found. Skipping subnet (%s)", network_id, subnet_id) continue network_name = network['name'] ib_cxt = ib_context.InfobloxContext(context, user_id, network, subnet, grid_config, plugin=neutron_api) db_mapped_netview = dbi.get_network_view_by_mapping( session, grid_id=grid_id, network_id=network_id, subnet_id=subnet_id) if db_mapped_netview: LOG.info("Mapping found for network (%s), subnet (%s)", network_name, subnet_name) if len(db_mapped_netview) > 1: LOG.warning("More that one db_mapped_netview returned") if delete_unknown_ips: ib_network = ib_objects.Network.search( ib_cxt.connector, network_view=db_mapped_netview[0].network_view, cidr=subnet.get('cidr')) ib_networks.append(ib_network) continue ipam_controller = ipam.IpamSyncController(ib_cxt) dns_controller = dns.DnsController(ib_cxt) rollback_list = [] try: ib_network = ipam_controller.create_subnet(rollback_list) if ib_network: if delete_unknown_ips: ib_networks.append(ib_network) dns_controller.create_dns_zones(rollback_list) LOG.info("Created network (%s), subnet (%s)", network_name, subnet_name) except Exception as e: LOG.error(_LE("Error occurred: %(error)s"), {'error': e}) for ib_obj in reversed(rollback_list): try: ib_obj.delete() except ib_exc.InfobloxException as e: LOG.warning(_LW("Unable to delete %(obj)s due to " "error: %(error)s."), {'obj': ib_obj, 'error': e}) should_exit = True break if should_exit: LOG.info("Exiting due to the error in creating subnet...") return # sync ports for port in ports: port_id = port['id'] port_name = port['name'] port_mac_address = port['mac_address'] tenant_id = port.get('tenant_id') or user_tenant_id network_id = port['network_id'] device_owner = port['device_owner'] device_id = port['device_id'] instance_name = (instance_names_by_instance_id[device_id] if device_id in instance_names_by_instance_id else None) network = utils.find_one_in_list('id', network_id, networks) if not network: LOG.error("network (%s) not found", network_id) break for ip_set in port.get('fixed_ips'): subnet_id = ip_set['subnet_id'] ip_address = ip_set['ip_address'] LOG.info("Adding port for %s: %s...", device_owner, ip_address) subnet = utils.find_one_in_list('id', subnet_id, subnets) if not subnet: should_exit = True LOG.error("subnet (%s) not found", subnet_id) break ib_cxt = ib_context.InfobloxContext(context, user_id, network, subnet, grid_config, plugin=neutron_api) connector = ib_cxt.connector netview = ib_cxt.mapping.network_view search_fields = { 'network_view': netview, 'ip_address': ip_address } obj_type = ('ipv4address'if utils.get_ip_version(ip_address) == 4 else 'ipv6address') ib_address = connector.get_object(obj_type, search_fields, return_fields=['objects'], force_proxy=True) if ib_address and ib_address[0]['objects']: LOG.info("%s is found...no need to create", ip_address) continue ipam_controller = ipam.IpamSyncController(ib_cxt) dns_controller = dns.DnsController(ib_cxt) # for a floating ip port, check for its association. # if associated, then port info needs to be the associated port, # not the floating ip port because the associated port contains # actual attached device info is_floating_ip = False if ip_address in instance_names_by_floating_ip: db_floatingip = dbi.get_floatingip_by_ip_address(session, ip_address) db_port = dbi.get_port_by_id(session, db_floatingip.fixed_port_id) port_id = db_port.id port_name = db_port.name tenant_id = db_port.tenant_id device_id = db_port.device_id device_owner = db_port.device_owner instance_name = instance_names_by_floating_ip[ip_address] is_floating_ip = True allocated_ip = ipam_controller.allocate_specific_ip( ip_address, port_mac_address, port_id, tenant_id, device_id, device_owner) if allocated_ip and device_owner: try: dns_controller.bind_names( allocated_ip, instance_name, port_id, tenant_id, device_id, device_owner, is_floating_ip, port_name) except Exception as e: should_exit = True LOG.error("Unable to allocate ip (%s): %s", ip_address, e) ipam_controller.deallocate_ip(allocated_ip) break LOG.info("Allocated %s", ip_address) if should_exit: LOG.info("Existing due to error in port creation...") break if delete_unknown_ips: LOG.info("Start deleting unknown Fixed IP's from Infoblox...") for ib_network in ib_networks: nw_ea = ib_network.extattrs # Skip network if it doesn't have EA or if EA indicates it's # shared or external. if (not nw_ea or nw_ea.get('Is External') or nw_ea.get('Is Shared')): continue LOG.info("Searching for Fixed IP: network_view='%s', cidr='%s'" % (ib_network.network_view, ib_network.network)) fixed_ips = ib_objects.FixedAddress.search_all( ib_cxt.connector, network_view=ib_network.network_view, network=ib_network.network) if not fixed_ips: LOG.info("No FixedIP found: network_view='%s', cidr='%s'" % (ib_network.network_view, ib_network.network)) continue for fixed_ip in fixed_ips: ea = fixed_ip.extattrs port_id = None if ea: port_id = ea.get('Port ID') # Delete Fixed IP if: # - Fixed IP does not have 'Port ID' EA, or # - No port_id in neutron matches 'Port ID' EA value if not (port_id and utils.find_one_in_list('id', port_id, ports)): LOG.info("Deleting Fixed IP from Infoblox: '%s'" % fixed_ip) fixed_ip.delete() LOG.info("Ending migration...")