Beispiel #1
0
    def test_ovn_nb_sync_mode_log(self):
        create_network_list = []
        create_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_address_set_list = []
        del_address_set_list = []
        update_address_set_list = []
        add_subnet_dhcp_options_list = []
        delete_dhcp_options_list = []

        ovn_nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
            self.plugin, self.mech_driver._nb_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,
            del_network_list, del_port_list, add_static_route_list,
            del_static_route_list, add_address_set_list, del_address_set_list,
            update_address_set_list, add_subnet_dhcp_options_list,
            delete_dhcp_options_list)
    def post_fork_initialize(self, resource, event, trigger, payload=None):
        # NOTE(rtheis): This will initialize all workers (API, RPC,
        # plugin service and OVN) with OVN IDL connections.
        self._post_fork_event.clear()
        self._ovn_client_inst = None
        self._nb_ovn, self._sb_ovn = impl_idl_ovn.get_ovn_idls(self, trigger)
        # Now IDL connections can be safely used.
        self._post_fork_event.set()

        if trigger.im_class == ovsdb_monitor.OvnWorker:
            # Call the synchronization task if its ovn worker
            # This sync neutron DB to OVN-NB DB only in inconsistent states
            self.nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
                self._plugin, self._nb_ovn, config.get_ovn_neutron_sync_mode(),
                self)
            self.nb_synchronizer.sync()

            # This sync neutron DB to OVN-SB DB only in inconsistent states
            self.sb_synchronizer = ovn_db_sync.OvnSbSynchronizer(
                self._plugin, self._sb_ovn, self)
            self.sb_synchronizer.sync()

        if trigger.im_class == maintenance.MaintenanceWorker:
            self._maintenance_thread = maintenance.MaintenanceThread()
            self._maintenance_thread.add_periodics(
                maintenance.DBInconsistenciesPeriodics(self._ovn_client))
            self._maintenance_thread.start()
    def _sync_resources(self, mode):
        # TODO(numans) - Need to sync ACLs
        nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
            self.plugin, self.mech_driver._nb_ovn, mode, self.mech_driver)

        ctx = context.get_admin_context()
        nb_synchronizer.sync_networks_and_ports(ctx)
        nb_synchronizer.sync_routers_and_rports(ctx)
Beispiel #4
0
    def _sync_resources(self, mode):
        nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
            self.plugin, self.mech_driver._nb_ovn, mode, self.mech_driver)

        ctx = context.get_admin_context()
        nb_synchronizer.sync_address_sets(ctx)
        nb_synchronizer.sync_networks_ports_and_dhcp_opts(ctx)
        nb_synchronizer.sync_acls(ctx)
        nb_synchronizer.sync_routers_and_rports(ctx)
    def test_ovn_nb_sync_mode_repair(self):
        create_network_list = [{'net': {'id': 'n2'}, 'ext_ids': {}}]
        del_network_list = ['neutron-n3']
        del_port_list = [{'id': 'p3n1', 'lswitch': 'neutron-n1'},
                         {'id': 'p1n1', 'lswitch': 'neutron-n1'}]
        create_port_list = self.ports
        for port in create_port_list:
            if port['id'] == 'p1n1':
                # this will be skipped by the logic,
                # because it is already in lswitch-port list
                create_port_list.remove(port)

        create_router_list = [{'id': 'r2', 'routes': [{'nexthop': '40.0.0.100',
                               'destination': '30.0.0.0/24'}]}]
        add_static_route_list = [{'destination': '30.0.0.0/24',
                                  'nexthop': '40.0.0.100'}]
        del_static_route_list = [{'nexthop': '20.0.0.100',
                                  'destination': '10.0.0.0/24'}]

        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

        add_address_set_list = [
            {'external_ids': {ovn_const.OVN_SG_NAME_EXT_ID_KEY:
                              'all-tcp'},
             'name': 'as_ip6_sg1',
             'addresses': ['fd79:e1c:a55::816:eff:eff:ff2']}]
        del_address_set_list = [{'name': 'as_ip4_del'}]
        update_address_set_list = [
            {'addrs_remove': [],
             'addrs_add': ['10.0.0.4'],
             'name': 'as_ip4_sg2'},
            {'addrs_remove': ['fd79:e1c:a55::816:eff:eff:ff3'],
             'addrs_add': [],
             'name': 'as_ip6_sg2'}]

        ovn_nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
            self.plugin, self.mech_driver._nb_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,
                                      del_router_list, del_router_port_list,
                                      create_network_list, create_port_list,
                                      del_network_list, del_port_list,
                                      add_static_route_list,
                                      del_static_route_list,
                                      add_address_set_list,
                                      del_address_set_list,
                                      update_address_set_list)
Beispiel #6
0
    def __reconnect__(self, leader_info=None):
        if leader_info != OvsdbNbOvnIdl.leader_info:
            OvsdbNbOvnIdl.ovsdb_connection.stop()
            self.__init_connect__(leader_info)
            OvsdbNbOvnIdl.leader_info = leader_info

            self.idl = OvsdbNbOvnIdl.ovsdb_connection.idl
            self.nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
                manager.NeutronManager.get_plugin(), self,
                cfg.get_ovn_neutron_sync_mode(), self.driver)
            self.nb_synchronizer.sync()
Beispiel #7
0
    def post_fork_initialize(self, resource, event, trigger, **kwargs):
        # NOTE(rtheis): This will initialize all workers (API, RPC,
        # plugin service and OVN) with OVN IDL connections.
        self._nb_ovn, self._sb_ovn = impl_idl_ovn.get_ovn_idls(self, trigger)

        if trigger.im_class == ovsdb_monitor.OvnWorker:
            # Call the synchronization task if its ovn worker
            # This sync neutron DB to OVN-NB DB only in inconsistent states
            self.nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
                self._plugin, self._nb_ovn, config.get_ovn_neutron_sync_mode(),
                self)
            self.nb_synchronizer.sync()
Beispiel #8
0
    def _sync_resources(self, mode):
        nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
            self.plugin, self.mech_driver._nb_ovn, mode, self.mech_driver)

        ctx = context.get_admin_context()
        # TODO(rtheis): Temporarily synchronize all security groups until the
        # sync Address Set support is available. This is needed since the
        # entire OVN NB DB is deleted during the *repair_delete_ovn_nb_db test.
        # See https://review.openstack.org/#/c/341882/ for the coming support.
        for sg in self.plugin.get_security_groups(ctx):
            self.mech_driver._process_sg_notification(resources.SECURITY_GROUP,
                                                      events.AFTER_CREATE,
                                                      None,
                                                      security_group=sg)
        nb_synchronizer.sync_networks_and_ports(ctx)
        nb_synchronizer.sync_acls(ctx)
        nb_synchronizer.sync_routers_and_rports(ctx)
    def test_ovn_nb_sync_mode_repair(self):
        create_network_list = [{'net': {'id': 'n2'}, 'ext_ids': {}}]
        del_network_list = ['neutron-n3']
        del_port_list = [{
            'id': 'p3n1',
            'lswitch': 'neutron-n1'
        }, {
            'id': 'p1n1',
            'lswitch': 'neutron-n1'
        }]
        create_port_list = self.ports
        for port in create_port_list:
            if port['id'] == 'p1n1':
                # this will be skipped by the logic,
                # because it is already in lswitch-port list
                create_port_list.remove(port)

        create_router_list = [{
            'id':
            'r2',
            'routes': [{
                'nexthop': '40.0.0.100',
                'destination': '30.0.0.0/24'
            }]
        }]
        add_static_route_list = [{
            'destination': '30.0.0.0/24',
            'nexthop': '40.0.0.100'
        }]
        del_static_route_list = [{
            'nexthop': '20.0.0.100',
            'destination': '10.0.0.0/24'
        }]

        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

        ovn_nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
            self.plugin, self.mech_driver._nb_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, del_router_list, del_router_port_list,
            create_network_list, create_port_list, del_network_list,
            del_port_list, add_static_route_list, del_static_route_list)
Beispiel #10
0
    def post_fork_initialize(self, resource, event, trigger, payload=None):
        # NOTE(rtheis): This will initialize all workers (API, RPC,
        # plugin service and OVN) with OVN IDL connections.
        self._post_fork_event.clear()
        self._ovn_client_inst = None

        is_maintenance = (
            utils.get_method_class(trigger) == worker.MaintenanceWorker)
        if not is_maintenance:
            self.node_uuid = db_hash_ring.add_node(self.hash_ring_group)

        self._nb_ovn, self._sb_ovn = impl_idl_ovn.get_ovn_idls(
            self, trigger, binding_events=not is_maintenance)

        # Override agents API methods
        self.patch_plugin_merge("get_agents", get_agents)
        self.patch_plugin_choose("get_agent", get_agent)
        self.patch_plugin_choose("update_agent", update_agent)
        self.patch_plugin_choose("delete_agent", delete_agent)

        # Now IDL connections can be safely used.
        self._post_fork_event.set()

        if is_maintenance:
            # Call the synchronization task if its maintenance worker
            # This sync neutron DB to OVN-NB DB only in inconsistent states
            self.nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
                self._plugin, self._nb_ovn, self._sb_ovn,
                config.get_ovn_neutron_sync_mode(), self)
            self.nb_synchronizer.sync()

            # This sync neutron DB to OVN-SB DB only in inconsistent states
            self.sb_synchronizer = ovn_db_sync.OvnSbSynchronizer(
                self._plugin, self._sb_ovn, self)
            self.sb_synchronizer.sync()

            self._maintenance_thread = maintenance.MaintenanceThread()
            self._maintenance_thread.add_periodics(
                maintenance.DBInconsistenciesPeriodics(self._ovn_client))
            self._maintenance_thread.add_periodics(
                maintenance.HashRingHealthCheckPeriodics(self.hash_ring_group))
            self._maintenance_thread.start()
    def _test_ovn_nb_sync_mode_log_helper(self, port_groups_supported=True):
        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_address_set_list = []
        del_address_set_list = []
        update_address_set_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_address_set_list, del_address_set_list,
            update_address_set_list, add_subnet_dhcp_options_list,
            delete_dhcp_options_list, add_port_groups_list,
            del_port_groups_list, port_groups_supported)
Beispiel #12
0
    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.is_port_groups_supported() or
                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()
Beispiel #13
0
    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'
        }]
        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'
        }]
        add_floating_ip_list = [{
            'logical_ip': '172.16.2.12',
            'external_ip': '90.0.0.12',
            'type': 'dnat_and_snat'
        }, {
            'logical_ip': '192.168.2.10',
            'external_ip': '100.0.0.10',
            'type': 'dnat_and_snat'
        }]
        del_floating_ip_list = [{
            'logical_ip': '172.16.1.11',
            'external_ip': '90.0.0.11',
            'type': 'dnat_and_snat'
        }]

        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 = [('r4', self.get_sync_router_ports[2])]
        update_router_port_list[0][1].update(
            {'networks': self.lrport_networks})

        add_address_set_list = [{
            'external_ids': {
                ovn_const.OVN_SG_NAME_EXT_ID_KEY: 'all-tcp'
            },
            'name': 'as_ip6_sg1',
            'addresses': ['fd79:e1c:a55::816:eff:eff:ff2']
        }]
        del_address_set_list = [{'name': 'as_ip4_del'}]
        update_address_set_list = [{
            'addrs_remove': [],
            'addrs_add': ['10.0.0.4'],
            'name': 'as_ip4_sg2'
        }, {
            'addrs_remove': ['fd79:e1c:a55::816:eff:eff:ff3'],
            'addrs_add': [],
            'name':
            'as_ip6_sg2'
        }]

        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, '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_address_set_list, del_address_set_list,
            update_address_set_list, add_subnet_dhcp_options_list,
            delete_dhcp_options_list)
Beispiel #14
0
def main():
    """Main method for syncing neutron networks and ports with ovn nb db.

    The utility syncs neutron db with ovn nb db.
    """
    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(
            _LE('Error parsing the configuration values. '
                'Please verify.'))
        return

    logging.setup(conf, 'neutron_ovn_db_sync_util')
    LOG.info(_LI('Started Neutron OVN db sync'))
    mode = ovn_config.get_ovn_neutron_sync_mode()
    if mode not in [ovn_db_sync.SYNC_MODE_LOG, ovn_db_sync.SYNC_MODE_REPAIR]:
        LOG.error(
            _LE('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'):
        cfg.CONF.core_plugin = (
            'networking_ovn.cmd.neutron_ovn_db_sync_util.Ml2Plugin')
        if 'ovn' not in cfg.CONF.ml2.mechanism_drivers:
            LOG.error(_LE('No "ovn" mechanism driver found : "%s".'),
                      cfg.CONF.ml2.mechanism_drivers)
            return
        cfg.CONF.set_override('mechanism_drivers', ['ovn-sync'], 'ml2')
        conf.service_plugins = ['networking_ovn.l3.l3_ovn.OVNL3RouterPlugin']
    else:
        LOG.error(_LE('Invalid core plugin : ["%s"].'), cfg.CONF.core_plugin)
        return

    try:
        ovn_api = impl_idl_ovn.OvsdbNbOvnIdl(None)
    except RuntimeError:
        LOG.error(_LE('Invalid --ovn-ovn_nb_connection parameter provided.'))
        return

    core_plugin = manager.NeutronManager.get_plugin()
    ovn_driver = core_plugin.mechanism_manager.mech_drivers['ovn-sync'].obj
    ovn_driver._nb_ovn = ovn_api

    synchronizer = ovn_db_sync.OvnNbSynchronizer(core_plugin, ovn_api, mode,
                                                 ovn_driver)

    ctx = context.get_admin_context()

    LOG.info(_LI('Syncing the networks and ports with mode : %s'), mode)
    try:
        synchronizer.sync_address_sets(ctx)
    except Exception:
        LOG.exception(
            _LE("Error syncing  the Address Sets. Check the "
                "--database-connection value again"))
        return
    try:
        synchronizer.sync_networks_ports_and_dhcp_opts(ctx)
    except Exception:
        LOG.exception(
            _LE("Error syncing  Networks, Ports and DHCP options "
                "for unknown reason please try again"))
        return
    try:
        synchronizer.sync_acls(ctx)
    except Exception:
        LOG.exception(
            _LE("Error syncing  ACLs for unknown "
                "reason please try again"))
        return
    try:
        synchronizer.sync_routers_and_rports(ctx)
    except Exception:
        LOG.exception(
            _LE("Error syncing  Routers and Router ports "
                "please try again"))
        return
    LOG.info(_LI('Sync completed'))
Beispiel #15
0
def main():
    """Main method for syncing neutron networks and ports with ovn nb db.

    The utility syncs neutron db with ovn nb db.
    """
    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_config.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 = (
            'networking_ovn.cmd.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 = ['networking_ovn.l3.l3_ovn.OVNL3RouterPlugin']
    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()
    ovn_driver = core_plugin.mechanism_manager.mech_drivers['ovn-sync'].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')
    def _test_ovn_nb_sync_mode_repair_helper(self, port_groups_supported=True):

        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'
        }]
        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})

        if not port_groups_supported:
            add_address_set_list = [{
                'external_ids': {
                    ovn_const.OVN_SG_EXT_ID_KEY: 'sg1'
                },
                'name':
                'as_ip6_sg1',
                'addresses': ['fd79:e1c:a55::816:eff:eff:ff2']
            }]
            del_address_set_list = [{'name': 'as_ip4_del'}]
            update_address_set_list = [{
                'addrs_remove': [],
                'addrs_add': ['10.0.0.4'],
                'name': 'as_ip4_sg2'
            }, {
                'addrs_remove': ['fd79:e1c:a55::816:eff:eff:ff3'],
                'addrs_add': [],
                'name':
                'as_ip6_sg2'
            }]
            # If Port Groups are not supported, we don't expect any of those
            # to be created/deleted.
            add_port_groups_list = []
            del_port_groups_list = []
        else:
            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']
            # If using Port Groups, no Address Set shall be created/updated
            # and all the existing ones have to be removed.
            add_address_set_list = []
            update_address_set_list = []
            del_address_set_list = [{
                'name': 'as_ip4_sg1'
            }, {
                'name': 'as_ip4_sg2'
            }, {
                'name': 'as_ip6_sg2'
            }, {
                'name': 'as_ip4_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_address_set_list, del_address_set_list,
            update_address_set_list, add_subnet_dhcp_options_list,
            delete_dhcp_options_list, add_port_groups_list,
            del_port_groups_list, port_groups_supported)