def test_ovn_sb_sync(self): ovn_sb_synchronizer = ovn_db_sync.OvnSbSynchronizer( self.plugin, self.mech_driver._sb_ovn, self.mech_driver) ovn_api = ovn_sb_synchronizer.ovn_api hostname_with_physnets = { 'hostname1': ['physnet1', 'physnet2'], 'hostname2': ['physnet1'] } ovn_api.get_chassis_hostname_and_physnets.return_value = ( hostname_with_physnets) ovn_driver = ovn_sb_synchronizer.ovn_driver ovn_driver.update_segment_host_mapping = mock.Mock() hosts_in_neutron = {'hostname2', 'hostname3'} with mock.patch.object(ovn_db_sync.segments_db, 'get_hosts_mapped_with_segments', return_value=hosts_in_neutron): ovn_sb_synchronizer.sync_hostname_and_physical_networks(mock.ANY) all_hosts = set(hostname_with_physnets.keys()) | hosts_in_neutron self.assertEqual(len(all_hosts), ovn_driver.update_segment_host_mapping.call_count) update_segment_host_mapping_calls = [ mock.call(host, hostname_with_physnets[host]) for host in hostname_with_physnets ] update_segment_host_mapping_calls += [ mock.call(host, []) for host in hosts_in_neutron - set(hostname_with_physnets.keys()) ] ovn_driver.update_segment_host_mapping.assert_has_calls( update_segment_host_mapping_calls, any_order=True)
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')