def test_ovn_nb_sync_mode_log(self): create_network_list = [] create_port_list = [] create_provnet_port_list = [] del_network_list = [] del_port_list = [] create_router_list = [] create_router_port_list = [] update_router_port_list = [] del_router_list = [] del_router_port_list = [] add_static_route_list = [] del_static_route_list = [] add_snat_list = [] del_snat_list = [] add_floating_ip_list = [] del_floating_ip_list = [] add_subnet_dhcp_options_list = [] delete_dhcp_options_list = [] add_port_groups_list = [] del_port_groups_list = [] ovn_nb_synchronizer = ovn_db_sync.OvnNbSynchronizer( self.plugin, self.mech_driver._nb_ovn, self.mech_driver._sb_ovn, 'log', self.mech_driver) self._test_ovn_nb_sync_helper( ovn_nb_synchronizer, self.networks, self.ports, self.routers, self.get_sync_router_ports, create_router_list, create_router_port_list, update_router_port_list, del_router_list, del_router_port_list, create_network_list, create_port_list, create_provnet_port_list, del_network_list, del_port_list, add_static_route_list, del_static_route_list, add_snat_list, del_snat_list, add_floating_ip_list, del_floating_ip_list, add_subnet_dhcp_options_list, delete_dhcp_options_list, add_port_groups_list, del_port_groups_list)
def migrate_to_stateless_fips(self): """Perform the migration from stateful to stateless Floating IPs. """ # Only the worker holding a valid lock within OVSDB will perform the # migration. if not self.has_lock: return admin_context = n_context.get_admin_context() nb_sync = ovn_db_sync.OvnNbSynchronizer( self._ovn_client._plugin, self._nb_idl, self._ovn_client._sb_idl, None, None) nb_sync.migrate_to_stateless_fips(admin_context) raise periodics.NeverAgain()
def migrate_to_port_groups(self): """Perform the migration from Address Sets to Port Groups. """ # TODO(dalvarez): Remove this in U cycle when we're sure that all # versions are running using Port Groups (and OVS >= 2.10). # If Port Groups are not supported or we've already migrated, we don't # need to attempt to migrate again. if not self._nb_idl.get_address_sets(): raise periodics.NeverAgain() # Only the worker holding a valid lock within OVSDB will perform the # migration. if not self.has_lock: return admin_context = n_context.get_admin_context() nb_sync = ovn_db_sync.OvnNbSynchronizer( self._ovn_client._plugin, self._nb_idl, self._ovn_client._sb_idl, None, None) nb_sync.migrate_to_port_groups(admin_context) raise periodics.NeverAgain()
def test_ovn_nb_sync_mode_repair(self): create_network_list = [{ 'net': { 'id': 'n2', 'mtu': 1450 }, 'ext_ids': {} }] del_network_list = ['neutron-n3'] del_port_list = [{ 'id': 'p3n1', 'lswitch': 'neutron-n1' }, { 'id': 'p1n1', 'lswitch': 'neutron-n1' }, { 'id': 'provnet-orphaned-segment', 'lswitch': 'neutron-n4' }] create_port_list = self.ports for port in create_port_list: if port['id'] in ['p1n1', 'fp1']: # this will be skipped by the logic, # because p1n1 is already in lswitch-port list # and fp1 is a floating IP port create_port_list.remove(port) create_provnet_port_list = [{ 'id': 'n1', 'mtu': 1450, 'provider:physical_network': 'physnet1', 'provider:segmentation_id': 1000 }] create_router_list = [{ 'id': 'r2', 'routes': [{ 'nexthop': '40.0.0.100', 'destination': '30.0.0.0/24' }], 'gw_port_id': 'gpr2', 'external_gateway_info': { 'network_id': "ext-net", 'enable_snat': True, 'external_fixed_ips': [{ 'subnet_id': 'ext-subnet', 'ip_address': '100.0.0.2' }] } }] # Test adding and deleting routes snats fips behaviors for router r1 # existing in both neutron DB and OVN DB. # Test adding behaviors for router r2 only existing in neutron DB. # Static routes with destination 0.0.0.0/0 are default gateway routes add_static_route_list = [{ 'nexthop': '20.0.0.101', 'destination': '12.0.0.0/24' }, { 'nexthop': '90.0.0.1', 'destination': '0.0.0.0/0' }, { 'nexthop': '40.0.0.100', 'destination': '30.0.0.0/24' }, { 'nexthop': '100.0.0.1', 'destination': '0.0.0.0/0' }] del_static_route_list = [{ 'nexthop': '20.0.0.100', 'destination': '10.0.0.0/24' }] add_snat_list = [{ 'logical_ip': '172.16.2.0/24', 'external_ip': '90.0.0.2', 'type': 'snat' }, { 'logical_ip': '192.168.2.0/24', 'external_ip': '100.0.0.2', 'type': 'snat' }] del_snat_list = [{ 'logical_ip': '172.16.1.0/24', 'external_ip': '90.0.0.2', 'type': 'snat' }] # fip 100.0.0.11 exists in OVN with distributed type and in Neutron # with centralized type. This fip is used to test # enable_distributed_floating_ip switch and migration add_floating_ip_list = [{ 'id': 'fip2', 'router_id': 'r1', 'floating_ip_address': '90.0.0.12', 'fixed_ip_address': '172.16.2.12' }, { 'id': 'fip3', 'router_id': 'r2', 'floating_ip_address': '100.0.0.10', 'fixed_ip_address': '192.168.2.10' }, { 'id': 'fip4', 'router_id': 'r2', 'floating_ip_address': '100.0.0.11', 'fixed_ip_address': '192.168.2.11' }] del_floating_ip_list = [{ 'logical_ip': '172.16.1.11', 'external_ip': '90.0.0.11', 'type': 'dnat_and_snat' }, { 'logical_ip': '192.168.2.11', 'external_ip': '100.0.0.11', 'type': 'dnat_and_snat', 'external_mac': '01:02:03:04:05:06', 'logical_port': 'vm1' }] del_router_list = [{'router': 'neutron-r3'}] del_router_port_list = [{'id': 'lrp-p3r1', 'router': 'neutron-r1'}] create_router_port_list = self.get_sync_router_ports[:2] update_router_port_list = [self.get_sync_router_ports[2]] update_router_port_list[0].update({'networks': self.lrport_networks}) add_port_groups_list = [{ 'external_ids': { ovn_const.OVN_SG_EXT_ID_KEY: 'sg2' }, 'name': 'pg_sg2', 'acls': [] }] del_port_groups_list = ['pg_unknown_del'] add_subnet_dhcp_options_list = [(self.subnets[2], self.networks[1]), (self.subnets[1], self.networks[0])] delete_dhcp_options_list = ['UUID2', 'UUID4', 'UUID5'] ovn_nb_synchronizer = ovn_db_sync.OvnNbSynchronizer( self.plugin, self.mech_driver._nb_ovn, self.mech_driver._sb_ovn, 'repair', self.mech_driver) self._test_ovn_nb_sync_helper( ovn_nb_synchronizer, self.networks, self.ports, self.routers, self.get_sync_router_ports, create_router_list, create_router_port_list, update_router_port_list, del_router_list, del_router_port_list, create_network_list, create_port_list, create_provnet_port_list, del_network_list, del_port_list, add_static_route_list, del_static_route_list, add_snat_list, del_snat_list, add_floating_ip_list, del_floating_ip_list, add_subnet_dhcp_options_list, delete_dhcp_options_list, add_port_groups_list, del_port_groups_list)
def main(): """Main method for syncing neutron networks and ports with ovn nb db. This script provides a utility for syncing the OVN Northbound Database with the Neutron database. This script is used for the migration from ML2/OVS to ML2/OVN. """ conf = setup_conf() # if no config file is passed or no configuration options are passed # then load configuration from /etc/neutron/neutron.conf try: conf(project='neutron') except TypeError: LOG.error('Error parsing the configuration values. Please verify.') return logging.setup(conf, 'neutron_ovn_db_sync_util') LOG.info('Started Neutron OVN db sync') mode = ovn_conf.get_ovn_neutron_sync_mode() if mode not in [ovn_db_sync.SYNC_MODE_LOG, ovn_db_sync.SYNC_MODE_REPAIR]: LOG.error('Invalid sync mode : ["%s"]. Should be "log" or "repair"', mode) return # Validate and modify core plugin and ML2 mechanism drivers for syncing. if (cfg.CONF.core_plugin.endswith('.Ml2Plugin') or cfg.CONF.core_plugin == 'ml2'): cfg.CONF.core_plugin = ( 'neutron.cmd.ovn.neutron_ovn_db_sync_util.Ml2Plugin') if not cfg.CONF.ml2.mechanism_drivers: LOG.error('please use --config-file to specify ' 'neutron and ml2 configuration file.') return if 'ovn' not in cfg.CONF.ml2.mechanism_drivers: LOG.error('No "ovn" mechanism driver found : "%s".', cfg.CONF.ml2.mechanism_drivers) return cfg.CONF.set_override('mechanism_drivers', ['ovn-sync'], 'ml2') conf.service_plugins = [ 'neutron.services.ovn_l3.plugin.OVNL3RouterPlugin', 'neutron.services.segments.plugin.Plugin', 'port_forwarding', ] else: LOG.error('Invalid core plugin : ["%s"].', cfg.CONF.core_plugin) return try: conn = impl_idl_ovn.get_connection(impl_idl_ovn.OvsdbNbOvnIdl) ovn_api = impl_idl_ovn.OvsdbNbOvnIdl(conn) except RuntimeError: LOG.error('Invalid --ovn-ovn_nb_connection parameter provided.') return try: sb_conn = impl_idl_ovn.get_connection(impl_idl_ovn.OvsdbSbOvnIdl) ovn_sb_api = impl_idl_ovn.OvsdbSbOvnIdl(sb_conn) except RuntimeError: LOG.error('Invalid --ovn-ovn_sb_connection parameter provided.') return manager.init() core_plugin = directory.get_plugin() driver = core_plugin.mechanism_manager.mech_drivers['ovn-sync'] # The L3 code looks for the OVSDB connection on the 'ovn' driver # and will fail with a KeyError if it isn't there core_plugin.mechanism_manager.mech_drivers['ovn'] = driver ovn_driver = driver.obj ovn_driver._nb_ovn = ovn_api ovn_driver._sb_ovn = ovn_sb_api synchronizer = ovn_db_sync.OvnNbSynchronizer(core_plugin, ovn_api, ovn_sb_api, mode, ovn_driver) LOG.info('Sync for Northbound db started with mode : %s', mode) synchronizer.do_sync() LOG.info('Sync completed for Northbound db') sb_synchronizer = ovn_db_sync.OvnSbSynchronizer(core_plugin, ovn_sb_api, ovn_driver) LOG.info('Sync for Southbound db started with mode : %s', mode) sb_synchronizer.do_sync() LOG.info('Sync completed for Southbound db')