示例#1
0
 def test_chassis_delete_event(self):
     self._test_chassis_helper('delete', self.row_json)
     self.driver.update_segment_host_mapping.assert_called_once_with(
         'fake-hostname', [])
     if ovn_config.is_ovn_l3():
         self.assertEqual(
             1, self.l3_plugin.schedule_unhosted_routers.call_count)
示例#2
0
    def add_router_interface(self, context, router_id, interface_info):
        router_interface_info = super(OVNPlugin, self).add_router_interface(
            context, router_id, interface_info)

        if not config.is_ovn_l3():
            LOG.debug(_("OVN L3 mode is disabled, skipping "
                        "add_router_interface"))
            return router_interface_info

        port = self.get_port(context, router_interface_info['port_id'])
        subnet_id = port['fixed_ips'][0]['subnet_id']
        subnet = self.get_subnet(context, subnet_id)
        lrouter = utils.ovn_name(router_id)
        cidr = netaddr.IPNetwork(subnet['cidr'])
        network = "%s/%s" % (port['fixed_ips'][0]['ip_address'],
                             str(cidr.prefixlen))

        self._ovn.add_lrouter_port(port['id'], lrouter,
                                   mac=port['mac_address'],
                                   network=network).execute(check_error=True)
        # TODO(chandrav)
        # The following code is to update the options column in the lport
        # table with {router-port: "UUID of logical_router_port"}. Ideally this
        # should have been handled ine one transaction with add_lrouter_port,
        # but due to a bug in idl, we are forced to update it in a separate
        # transaction. After the transaction is committed idl does not update
        # the UUID that is part of a string from old to new.
        self._ovn.set_lrouter_port_in_lport(port['id']).execute(
            check_error=True)
        return router_interface_info
示例#3
0
    def add_router_interface(self, context, router_id, interface_info):
        router_interface_info = super(OVNPlugin, self).add_router_interface(
            context, router_id, interface_info)

        if not config.is_ovn_l3():
            LOG.debug("OVN L3 mode is disabled, skipping "
                      "add_router_interface")
            return router_interface_info

        port = self.get_port(context, router_interface_info['port_id'])
        subnet_id = port['fixed_ips'][0]['subnet_id']
        subnet = self.get_subnet(context, subnet_id)
        lrouter = utils.ovn_name(router_id)
        cidr = netaddr.IPNetwork(subnet['cidr'])
        network = "%s/%s" % (port['fixed_ips'][0]['ip_address'],
                             str(cidr.prefixlen))

        lrouter_port_name = utils.ovn_lrouter_port_name(port['id'])
        with self._ovn.transaction(check_error=True) as txn:
            txn.add(self._ovn.add_lrouter_port(name=lrouter_port_name,
                                               lrouter=lrouter,
                                               mac=port['mac_address'],
                                               network=network))

            txn.add(self._ovn.set_lrouter_port_in_lport(port['id'],
                                                        lrouter_port_name))
        return router_interface_info
 def test_chassis_delete_event(self):
     self._test_chassis_helper('delete', self.row_json)
     self.driver.update_segment_host_mapping.assert_called_once_with(
         'fake-hostname', [])
     if ovn_config.is_ovn_l3():
         self.assertEqual(
             1,
             self.l3_plugin.schedule_unhosted_routers.call_count)
示例#5
0
 def _start_rpc_notifiers(self):
     """Initialize RPC notifiers for agents."""
     self.agent_notifiers[const.AGENT_TYPE_DHCP] = (
         dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
     )
     if not config.is_ovn_l3():
         self.agent_notifiers[const.AGENT_TYPE_L3] = (
             l3_rpc_agent_api.L3AgentNotifyAPI()
         )
示例#6
0
 def test_chassis_update_event(self):
     old_row_json = copy.deepcopy(self.row_json)
     old_row_json['external_ids'][1][0][1] = ("fake-phynet2:fake-br2")
     self._test_chassis_helper('update', self.row_json, old_row_json)
     self.driver.update_segment_host_mapping.assert_called_once_with(
         'fake-hostname', ['fake-phynet1'])
     if ovn_config.is_ovn_l3():
         self.assertEqual(
             1, self.l3_plugin.schedule_unhosted_routers.call_count)
示例#7
0
 def start_rpc_listeners(self):
     self._setup_rpc()
     self.conn = n_rpc.create_connection()
     self.conn.create_consumer(topics.PLUGIN, self.endpoints, fanout=False)
     if not config.is_ovn_l3():
         self.conn.create_consumer(topics.L3PLUGIN, self.endpoints,
                                   fanout=False)
     self.conn.create_consumer(topics.REPORTS,
                               [agents_db.AgentExtRpcCallback()],
                               fanout=False)
     return self.conn.consume_in_threads()
示例#8
0
    def run(self, event, row, old):
        host = row.hostname
        phy_nets = []
        if event != self.ROW_DELETE:
            bridge_mappings = row.external_ids.get('ovn-bridge-mappings', '')
            mapping_dict = helpers.parse_mappings(bridge_mappings.split(','))
            phy_nets = list(mapping_dict)

        self.driver.update_segment_host_mapping(host, phy_nets)
        if ovn_config.is_ovn_l3():
            self.l3_plugin.schedule_unhosted_routers()
示例#9
0
    def run(self, event, row, old):
        host = row.hostname
        phy_nets = []
        if event != self.ROW_DELETE:
            bridge_mappings = row.external_ids.get('ovn-bridge-mappings', '')
            mapping_dict = helpers.parse_mappings(bridge_mappings.split(','))
            phy_nets = list(mapping_dict)

        self.driver.update_segment_host_mapping(host, phy_nets)
        if ovn_config.is_ovn_l3():
            self.l3_plugin.schedule_unhosted_gateways()
 def test_chassis_update_event(self):
     old_row_json = copy.deepcopy(self.row_json)
     old_row_json['external_ids'][1][0][1] = (
         "fake-phynet2:fake-br2")
     self._test_chassis_helper('update', self.row_json, old_row_json)
     self.driver.update_segment_host_mapping.assert_called_once_with(
         'fake-hostname', ['fake-phynet1'])
     if ovn_config.is_ovn_l3():
         self.assertEqual(
             1,
             self.l3_plugin.schedule_unhosted_routers.call_count)
示例#11
0
    def do_sync(self):
        """Method to sync the OVN_Southbound DB with neutron DB.

        OvnSbSynchronizer will sync data from OVN_Southbound to neutron. And
        the synchronization will always be performed, no matter what mode it
        is.
        """
        LOG.debug("Starting OVN-Southbound DB sync process")

        ctx = context.get_admin_context()
        self.sync_hostname_and_physical_networks(ctx)
        if config.is_ovn_l3():
            self.l3_plugin.schedule_unhosted_gateways()
 def run(self, event, row, old):
     chassis = getattr(row, 'chassis', [])
     if chassis:
         router = row.datapath.external_ids.get('name',
                                                '').replace('neutron-', '')
         host = chassis[0].hostname
         LOG.info("Router %(router)s is bound to host %(host)s", {
             'router': router,
             'host': host
         })
         if ovn_config.is_ovn_l3():
             self.l3_plugin.update_router_gateway_port_bindings(
                 router, host)
示例#13
0
    def _sync(self):
        """Method to sync the OVN_Southbound DB with neutron DB.

        OvnSbSynchronizer will sync data from OVN_Southbound to neutron. And
        the synchronization will always be performed, no matter what mode it
        is.
        """
        # Initial delay until service is up
        greenthread.sleep(10)
        LOG.debug("Starting OVN-Southbound DB sync process")

        ctx = context.get_admin_context()
        self.sync_hostname_and_physical_networks(ctx)
        if config.is_ovn_l3():
            self.l3_plugin.schedule_unhosted_routers()
示例#14
0
    def setUp(self):
        super(TestOvnSbIdlNotifyHandler, self).setUp()
        sb_helper = ovs_idl.SchemaHelper(schema_json=OVN_SB_SCHEMA)
        sb_helper.register_table('Chassis')
        self.sb_idl = ovsdb_monitor.OvnSbIdl(self.driver, "remote", sb_helper)
        self.sb_idl.lock_name = self.sb_idl.event_lock_name
        self.sb_idl.has_lock = True
        self.sb_idl.post_initialize(self.driver)
        self.chassis_table = self.sb_idl.tables.get('Chassis')
        self.driver.update_segment_host_mapping = mock.Mock()
        self.l3_plugin = directory.get_plugin(constants.L3)
        if ovn_config.is_ovn_l3():
            self.l3_plugin.schedule_unhosted_gateways = mock.Mock()

        self.row_json = {
            "name": "fake-name",
            "hostname": "fake-hostname",
            "external_ids": ['map', [["ovn-bridge-mappings",
                                      "fake-phynet1:fake-br1"]]]
        }
    def setUp(self):
        super(TestOvnSbIdlNotifyHandler, self).setUp()
        sb_helper = ovs_idl.SchemaHelper(schema_json=OVN_SB_SCHEMA)
        sb_helper.register_table('Chassis')
        self.sb_idl = ovsdb_monitor.OvnSbIdl(self.driver, "remote", sb_helper)
        self.sb_idl.lock_name = self.sb_idl.event_lock_name
        self.sb_idl.has_lock = True
        self.sb_idl.post_initialize(self.driver)
        self.chassis_table = self.sb_idl.tables.get('Chassis')
        self.driver.update_segment_host_mapping = mock.Mock()
        mgr = manager.NeutronManager.get_instance()
        self.l3_plugin = mgr.get_service_plugins().get(
            constants.L3)
        if ovn_config.is_ovn_l3():
            self.l3_plugin.schedule_unhosted_routers = mock.Mock()

        self.row_json = {
            "name": "fake-name",
            "hostname": "fake-hostname",
            "external_ids": ['map', [["ovn-bridge-mappings",
                                      "fake-phynet1:fake-br1"]]]
        }
示例#16
0
    def remove_router_interface(self, context, router_id, interface_info):
        if not config.is_ovn_l3():
            LOG.debug("OVN L3 mode is disabled, skipping "
                      "remove_router_interface")
            return super(OVNPlugin, self).remove_router_interface(
                context, router_id, interface_info)
        # TODO(chandrav)
        # Need to rework this code to get the port_id when the incoming request
        # contains only the subnet_id. Also need to figure out if OVN needs to
        # care about multiple prefix subnets on a single router interface.
        # This code is duplicated from neutron. Probably a better thing to do
        # is to handle everything in the plugin and just call delete_port
        # update_port.
        port_id = None
        if 'port_id' in interface_info:
            port_id = interface_info['port_id']
        elif 'subnet_id' in interface_info:
            subnet_id = interface_info['subnet_id']
            subnet = self.get_subnet(context, subnet_id)
            device_filter = {'device_id': [router_id],
                             'device_owner': [const.DEVICE_OWNER_ROUTER_INTF],
                             'network_id': [subnet['network_id']]}
            ports = super(OVNPlugin, self).get_ports(context,
                                                     filters=device_filter)
            for p in ports:
                port_subnets = [fip['subnet_id'] for fip in p['fixed_ips']]
                if subnet_id in port_subnets and len(port_subnets) == 1:
                    port_id = p['id']
                    break

        router_interface_info = super(OVNPlugin, self).remove_router_interface(
            context, router_id, interface_info)

        if port_id is not None:
            self._ovn.delete_lrouter_port(utils.ovn_lrouter_port_name(port_id),
                                          utils.ovn_name(router_id),
                                          if_exists=False
                                          ).execute(check_error=True)
        return router_interface_info
示例#17
0
    def sync_routers_and_rports(self, ctx):
        """Sync Routers between neutron and NB.

        @param ctx: neutron context
        @type  ctx: object of type neutron.context.Context
        @var   db_routers: List of Routers from neutron DB
        @var   db_router_ports: List of Router ports from neutron DB
        @var   lrouters: NB dictionary of logical routers and
               the corresponding logical router ports.
               vs list-of-acls
        @var   del_lrouters_list: List of Routers that need to be
               deleted from NB
        @var   del_lrouter_ports_list: List of Router ports that need to be
               deleted from NB
        @return: Nothing
        """
        if not config.is_ovn_l3():
            LOG.debug("OVN L3 mode is disabled, skipping "
                      "sync routers and router ports")
            return

        LOG.debug('OVN-NB Sync Routers and Router ports started')
        db_routers = {}
        db_router_ports = {}
        for router in self.l3_plugin.get_routers(ctx):
            db_routers[router['id']] = router

        interfaces = self.l3_plugin._get_sync_interfaces(
            ctx, db_routers.keys())
        for interface in interfaces:
            db_router_ports[interface['id']] = interface
        lrouters = self.ovn_api.get_all_logical_routers_with_rports()
        del_lrouters_list = []
        del_lrouter_ports_list = []
        update_sroutes_list = []
        for lrouter in lrouters:
            if lrouter['name'] in db_routers:
                for lrport in lrouter['ports']:
                    if lrport in db_router_ports:
                        del db_router_ports[lrport]
                    else:
                        del_lrouter_ports_list.append({
                            'port':
                            lrport,
                            'lrouter':
                            lrouter['name']
                        })
                if 'routes' in db_routers[lrouter['name']]:
                    db_routes = db_routers[lrouter['name']]['routes']
                else:
                    db_routes = []
                ovn_routes = lrouter['static_routes']
                add_routes, del_routes = n_utils.diff_list_of_dict(
                    ovn_routes, db_routes)
                update_sroutes_list.append({
                    'id': lrouter['name'],
                    'add': add_routes,
                    'del': del_routes
                })
                del db_routers[lrouter['name']]
            else:
                del_lrouters_list.append(lrouter)

        for r_id, router in db_routers.items():
            LOG.warning(
                _LW("Router found in Neutron but not in "
                    "OVN DB, router id=%s"), router['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(_LW("Creating the router %s in OVN NB DB"),
                                router['id'])
                    self.l3_plugin.create_lrouter_in_ovn(router)
                    if 'routes' in router:
                        update_sroutes_list.append({
                            'id': router['id'],
                            'add': router['routes'],
                            'del': []
                        })
                except RuntimeError:
                    LOG.warning(
                        _LW("Create router in OVN NB failed for"
                            " router %s"), router['id'])

        for rp_id, rrport in db_router_ports.items():
            LOG.warning(
                _LW("Router Port found in Neutron but not in OVN "
                    "DB, router port_id=%s"), rrport['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(
                        _LW("Creating the router port %s in "
                            "OVN NB DB"), rrport['id'])
                    self.l3_plugin.create_lrouter_port_in_ovn(
                        ctx, rrport['device_id'], rrport)
                except RuntimeError:
                    LOG.warning(
                        _LW("Create router port in OVN "
                            "NB failed for"
                            " router port %s"), rrport['id'])

        with self.ovn_api.transaction(check_error=True) as txn:
            for lrouter in del_lrouters_list:
                LOG.warning(
                    _LW("Router found in OVN but not in "
                        "Neutron, router id=%s"), lrouter['name'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.warning(_LW("Deleting the router %s from OVN NB DB"),
                                lrouter['name'])
                    txn.add(
                        self.ovn_api.delete_lrouter(
                            utils.ovn_name(lrouter['name'])))

            for lrport_info in del_lrouter_ports_list:
                LOG.warning(
                    _LW("Router Port found in OVN but not in "
                        "Neutron, port_id=%s"), lrport_info['port'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.warning(_LW("Deleting the port %s from OVN NB DB"),
                                lrport_info['port'])
                    txn.add(
                        self.ovn_api.delete_lrouter_port(
                            utils.ovn_lrouter_port_name(lrport_info['port']),
                            utils.ovn_name(lrport_info['lrouter']),
                            if_exists=False))
            for sroute in update_sroutes_list:
                if sroute['add']:
                    LOG.warning(
                        _LW("Router %(id)s static routes %(route)s "
                            "found in Neutron but not in OVN"), {
                                'id': sroute['id'],
                                'route': sroute['add']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(_LW("Add static routes %s to OVN NB DB"),
                                    sroute['add'])
                        for route in sroute['add']:
                            txn.add(
                                self.ovn_api.add_static_route(
                                    utils.ovn_name(sroute['id']),
                                    ip_prefix=route['destination'],
                                    nexthop=route['nexthop']))
                if sroute['del']:
                    LOG.warning(
                        _LW("Router %(id)s static routes %(route)s "
                            "found in OVN but not in Neutron"), {
                                'id': sroute['id'],
                                'route': sroute['del']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(
                            _LW("Delete static routes %s from OVN "
                                "NB DB"), sroute['del'])
                        for route in sroute['del']:
                            txn.add(
                                self.ovn_api.delete_static_route(
                                    utils.ovn_name(sroute['id']),
                                    ip_prefix=route['destination'],
                                    nexthop=route['nexthop']))
        LOG.debug('OVN-NB Sync routers and router ports finished')
示例#18
0
    def sync_routers_and_rports(self, ctx):
        """Sync Routers between neutron and NB.

        @param ctx: neutron context
        @type  ctx: object of type neutron.context.Context
        @var   db_routers: List of Routers from neutron DB
        @var   db_router_ports: List of Router ports from neutron DB
        @var   lrouters: NB dictionary of logical routers and
               the corresponding logical router ports.
               vs list-of-acls
        @var   del_lrouters_list: List of Routers that need to be
               deleted from NB
        @var   del_lrouter_ports_list: List of Router ports that need to be
               deleted from NB
        @return: Nothing
        """
        if not config.is_ovn_l3():
            LOG.debug("OVN L3 mode is disabled, skipping "
                      "sync routers and router ports")
            return

        LOG.debug('OVN-NB Sync Routers and Router ports started')
        db_routers = {}
        db_router_ports = {}
        db_gateway_ports = {}
        db_fips = {}
        for router in self.l3_plugin.get_routers(ctx):
            db_routers[router['id']] = router
            db_routers[router['id']]['floating_ips'] = []

        db_routers_keys = db_routers.keys()
        fips = self.l3_plugin.get_floatingips(ctx,
                                              {'router_id': db_routers_keys})
        interfaces = self.l3_plugin._get_sync_interfaces(
            ctx, db_routers_keys, [
                lib_constants.DEVICE_OWNER_ROUTER_INTF,
                lib_constants.DEVICE_OWNER_ROUTER_GW
            ])
        for fip in fips:
            db_routers[fip['router_id']]['floating_ips'].append({
                'floating_ip_address':
                fip['floating_ip_address'],
                'fixed_ip_address':
                fip['fixed_ip_address']
            })
        for interface in interfaces:
            if (interface['device_owner'] ==
                    lib_constants.DEVICE_OWNER_ROUTER_INTF):
                db_router_ports[interface['id']] = interface
                db_router_ports[interface['id']]['networks'] = sorted(
                    self.l3_plugin.get_networks_for_lrouter_port(
                        ctx, interface['fixed_ips']))
            else:
                db_gateway_ports[interface['id']] = interface
                db_gateway_ports[interface['id']]['networks'] = sorted(
                    self.l3_plugin.get_networks_for_lrouter_port(
                        ctx, interface['fixed_ips']))

        LOG.debug("Get neutron routers=%s", db_routers)
        LOG.debug("Get neutron router ports=%s", db_router_ports)
        LOG.debug("Get neutron gateway ports=%s", db_gateway_ports)

        lrouters = self.ovn_api.get_all_logical_routers_with_rports()
        LOG.debug("Get ovn routers=%s", lrouters)
        del_lrouters_list = []
        del_lrouter_ports_list = []
        del_gwrouter_ports_list = []
        update_sroutes_list = []
        update_fips_list = []
        update_lrport_list = []
        for lrouter in lrouters:
            if lrouter['name'] in db_routers:
                for lrport, lrport_nets in lrouter['ports'].items():
                    if lrport in db_router_ports:
                        db_lrport_nets = db_router_ports[lrport]['networks']
                        if db_lrport_nets != sorted(lrport_nets):
                            update_lrport_list.append(
                                (lrouter['name'], db_router_ports[lrport]))
                        del db_router_ports[lrport]
                    else:
                        del_lrouter_ports_list.append({
                            'port':
                            lrport,
                            'lrouter':
                            lrouter['name']
                        })

                for gwport, gwport_nets in lrouter['gateway_ports'].items():
                    if gwport in db_gateway_ports:
                        del db_gateway_ports[gwport]
                    else:
                        del_gwrouter_ports_list.append({
                            'port':
                            gwport,
                            'lrouter':
                            lrouter['name'],
                            'next_hop':
                            lrouter['next_hop']
                        })

                if 'routes' in db_routers[lrouter['name']]:
                    db_routes = db_routers[lrouter['name']]['routes']
                else:
                    db_routes = []
                ovn_routes = lrouter['static_routes']
                add_routes, del_routes = n_utils.diff_list_of_dict(
                    ovn_routes, db_routes)
                update_sroutes_list.append({
                    'id': lrouter['name'],
                    'del': del_routes,
                    'add': add_routes
                })
                ovn_fips = lrouter['floating_ips']
                db_fips = db_routers[lrouter['name']]['floating_ips']
                add_fips, del_fips = n_utils.diff_list_of_dict(
                    ovn_fips, db_fips)
                update_fips_list.append({
                    'id': lrouter['name'],
                    'add': add_fips,
                    'del': del_fips
                })
                del db_routers[lrouter['name']]
            else:
                del_lrouters_list.append(lrouter)

        for r_id, router in db_routers.items():
            LOG.warning(
                _LW("Router found in Neutron but not in "
                    "OVN DB, router id=%s"), router['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(_LW("Creating the router %s in OVN NB DB"),
                                router['id'])
                    self.l3_plugin.create_lrouter_in_ovn(router)
                    if 'routes' in router:
                        update_sroutes_list.append({
                            'id': router['id'],
                            'add': router['routes'],
                            'del': []
                        })
                    if 'floating_ips' in router:
                        update_fips_list.append({
                            'id': router['id'],
                            'add': router['floating_ips'],
                            'del': []
                        })
                except RuntimeError:
                    LOG.warning(
                        _LW("Create router in OVN NB failed for"
                            " router %s"), router['id'])

        for rp_id, rrport in db_router_ports.items():
            LOG.warning(
                _LW("Router Port found in Neutron but not in OVN "
                    "DB, router port_id=%s"), rrport['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(
                        _LW("Creating the router port %s in "
                            "OVN NB DB"), rrport['id'])
                    self.l3_plugin.create_lrouter_port_in_ovn(
                        ctx, rrport['device_id'], rrport)
                except RuntimeError:
                    LOG.warning(
                        _LW("Create router port in OVN "
                            "NB failed for"
                            " router port %s"), rrport['id'])

        for router_id, rport in update_lrport_list:
            LOG.warning(
                _LW("Router Port port_id=%s needs to be updated"
                    " for networks changed"), rport['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(
                        _LW("Updating networks on router port %s in "
                            "OVN NB DB"), rport['id'])
                    self.l3_plugin.update_lrouter_port_in_ovn(
                        ctx, router_id, rport, rport['networks'])
                except RuntimeError:
                    LOG.warning(
                        _LW("Update router port networks in OVN "
                            "NB failed for"
                            " router port %s"), rport['id'])

        for gwport_info in del_gwrouter_ports_list:
            LOG.warning(
                _LW("Gateway Port found in OVN but not in "
                    "Neutron, port_id=%s"), gwport_info['port'])
            if self.mode == SYNC_MODE_REPAIR:
                LOG.warning(_LW("Deleting the port %s from OVN NB DB"),
                            gwport_info['port'])
                self.l3_plugin.delete_gw_router_port_in_ovn(
                    gwport_info['lrouter'], gwport_info['port'],
                    gwport_info['next_hop'])

        for gwp_id, gwport in db_gateway_ports.items():
            LOG.warning(
                _LW("Gateway Port found in Neutron but not in OVN "
                    "DB, gateway port_id=%s"), gwport['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(
                        _LW("Creating the gateway port %s in "
                            "OVN NB DB"), gwport['id'])
                    self.l3_plugin.create_gw_router_port_in_ovn(
                        ctx, gwport['device_id'], gwport)
                except RuntimeError:
                    LOG.warning(
                        _LW("Create gateway port in OVN "
                            "NB failed for"
                            " gateway port %s"), gwport['id'])

        with self.ovn_api.transaction(check_error=True) as txn:
            for lrouter in del_lrouters_list:
                LOG.warning(
                    _LW("Router found in OVN but not in "
                        "Neutron, router id=%s"), lrouter['name'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.warning(_LW("Deleting the router %s from OVN NB DB"),
                                lrouter['name'])
                    txn.add(
                        self.ovn_api.delete_lrouter(
                            utils.ovn_name(lrouter['name'])))
                    txn.add(
                        self.ovn_api.delete_lrouter(
                            utils.ovn_gateway_name(lrouter['name'])))
                    txn.add(
                        self.ovn_api.delete_lswitch(
                            utils.ovn_transit_name(lrouter['name'])))

            for lrport_info in del_lrouter_ports_list:
                LOG.warning(
                    _LW("Router Port found in OVN but not in "
                        "Neutron, port_id=%s"), lrport_info['port'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.warning(_LW("Deleting the port %s from OVN NB DB"),
                                lrport_info['port'])
                    txn.add(
                        self.ovn_api.delete_lrouter_port(
                            utils.ovn_lrouter_port_name(lrport_info['port']),
                            utils.ovn_name(lrport_info['lrouter']),
                            if_exists=False))

            for sroute in update_sroutes_list:
                if sroute['add']:
                    LOG.warning(
                        _LW("Router %(id)s static routes %(route)s "
                            "found in Neutron but not in OVN"), {
                                'id': sroute['id'],
                                'route': sroute['add']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(_LW("Add static routes %s to OVN NB DB"),
                                    sroute['add'])
                        for route in sroute['add']:
                            txn.add(
                                self.ovn_api.add_static_route(
                                    utils.ovn_name(sroute['id']),
                                    ip_prefix=route['destination'],
                                    nexthop=route['nexthop']))
                if sroute['del']:
                    LOG.warning(
                        _LW("Router %(id)s static routes %(route)s "
                            "found in OVN but not in Neutron"), {
                                'id': sroute['id'],
                                'route': sroute['del']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(
                            _LW("Delete static routes %s from OVN "
                                "NB DB"), sroute['del'])
                        for route in sroute['del']:
                            txn.add(
                                self.ovn_api.delete_static_route(
                                    utils.ovn_name(sroute['id']),
                                    ip_prefix=route['destination'],
                                    nexthop=route['nexthop']))

            for fip in update_fips_list:
                if fip['del']:
                    LOG.warning(
                        _LW("Router %(id)s floating ips %(fip)s "
                            "found in OVN but not in Neutron"), {
                                'id': fip['id'],
                                'fip': fip['del']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(
                            _LW("Delete floating ips %s from OVN NB DB"),
                            fip['del'])
                        for ifip in fip['del']:
                            txn.add(
                                self.ovn_api.delete_nat(
                                    utils.ovn_gateway_name(fip['id']),
                                    logical_ip=ifip['fixed_ip_address'],
                                    external_ip=ifip['floating_ip_address'],
                                    type='dnat_and_snat'))
                if fip['add']:
                    LOG.warning(
                        _LW("Router %(id)s floating ips %(fip)s "
                            "found in Neutron but not in OVN"), {
                                'id': fip['id'],
                                'fip': fip['add']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(_LW("Add floating ips %s to OVN NB DB"),
                                    fip['add'])
                        for ifip in fip['add']:
                            txn.add(
                                self.ovn_api.add_nat(
                                    utils.ovn_gateway_name(fip['id']),
                                    logical_ip=ifip['fixed_ip_address'],
                                    external_ip=ifip['floating_ip_address'],
                                    type='dnat_and_snat'))

        LOG.debug('OVN-NB Sync routers and router ports finished')
示例#19
0
    def sync_routers_and_rports(self, ctx):
        """Sync Routers between neutron and NB.

        @param ctx: neutron_lib.context
        @type  ctx: object of type neutron_lib.context.Context
        @var   db_routers: List of Routers from neutron DB
        @var   db_router_ports: List of Router ports from neutron DB
        @var   lrouters: NB dictionary of logical routers and
               the corresponding logical router ports.
               vs list-of-acls
        @var   del_lrouters_list: List of Routers that need to be
               deleted from NB
        @var   del_lrouter_ports_list: List of Router ports that need to be
               deleted from NB
        @return: Nothing
        """
        if not config.is_ovn_l3():
            LOG.debug("OVN L3 mode is disabled, skipping "
                      "sync routers and router ports")
            return

        LOG.debug('OVN-NB Sync Routers and Router ports started @ %s' %
                  str(datetime.now()))

        db_routers = {}
        db_extends = {}
        db_router_ports = {}
        for router in self.l3_plugin.get_routers(ctx):
            db_routers[router['id']] = router
            db_extends[router['id']] = {}
            db_extends[router['id']]['routes'] = []
            db_extends[router['id']]['snats'] = []
            db_extends[router['id']]['fips'] = []
            if not router.get(l3.EXTERNAL_GW_INFO):
                continue
            r_ip, gw_ip = self.l3_plugin.get_external_router_and_gateway_ip(
                ctx, router)
            if gw_ip:
                db_extends[router['id']]['routes'].append({
                    'destination': '0.0.0.0/0',
                    'nexthop': gw_ip
                })
            if r_ip and utils.is_snat_enabled(router):
                networks = self.l3_plugin._get_v4_network_of_all_router_ports(
                    ctx, router['id'])
                for network in networks:
                    db_extends[router['id']]['snats'].append({
                        'logical_ip': network,
                        'external_ip': r_ip,
                        'type': 'snat'
                    })

        fips = self.l3_plugin.get_floatingips(
            ctx, {'router_id': list(db_routers.keys())})
        for fip in fips:
            db_extends[fip['router_id']]['fips'].append({
                'external_ip':
                fip['floating_ip_address'],
                'logical_ip':
                fip['fixed_ip_address'],
                'type':
                'dnat_and_snat'
            })
        interfaces = self.l3_plugin._get_sync_interfaces(
            ctx, db_routers.keys(), [
                constants.DEVICE_OWNER_ROUTER_INTF,
                constants.DEVICE_OWNER_ROUTER_GW
            ])
        for interface in interfaces:
            db_router_ports[interface['id']] = interface
            db_router_ports[interface['id']]['networks'] = sorted(
                self.l3_plugin.get_networks_for_lrouter_port(
                    ctx, interface['fixed_ips']))
        lrouters = self.ovn_api.get_all_logical_routers_with_rports()

        del_lrouters_list = []
        del_lrouter_ports_list = []
        update_sroutes_list = []
        update_lrport_list = []
        update_snats_list = []
        update_fips_list = []
        for lrouter in lrouters:
            if lrouter['name'] in db_routers:
                for lrport, lrport_nets in lrouter['ports'].items():
                    if lrport in db_router_ports:
                        db_lrport_nets = db_router_ports[lrport]['networks']
                        if db_lrport_nets != sorted(lrport_nets):
                            update_lrport_list.append(
                                (lrouter['name'], db_router_ports[lrport]))
                        del db_router_ports[lrport]
                    else:
                        del_lrouter_ports_list.append({
                            'port':
                            lrport,
                            'lrouter':
                            lrouter['name']
                        })
                if 'routes' in db_routers[lrouter['name']]:
                    db_routes = db_routers[lrouter['name']]['routes']
                else:
                    db_routes = []
                if 'routes' in db_extends[lrouter['name']]:
                    db_routes.extend(db_extends[lrouter['name']]['routes'])

                ovn_routes = lrouter['static_routes']
                add_routes, del_routes = helpers.diff_list_of_dict(
                    ovn_routes, db_routes)
                update_sroutes_list.append({
                    'id': lrouter['name'],
                    'add': add_routes,
                    'del': del_routes
                })
                ovn_fips = lrouter['dnat_and_snats']
                db_fips = db_extends[lrouter['name']]['fips']
                add_fips, del_fips = helpers.diff_list_of_dict(
                    ovn_fips, db_fips)
                update_fips_list.append({
                    'id': lrouter['name'],
                    'add': add_fips,
                    'del': del_fips
                })
                ovn_nats = lrouter['snats']
                db_snats = db_extends[lrouter['name']]['snats']
                add_snats, del_snats = helpers.diff_list_of_dict(
                    ovn_nats, db_snats)
                update_snats_list.append({
                    'id': lrouter['name'],
                    'add': add_snats,
                    'del': del_snats
                })
                del db_routers[lrouter['name']]
            else:
                del_lrouters_list.append(lrouter)

        for r_id, router in db_routers.items():
            LOG.warning(
                _LW("Router found in Neutron but not in "
                    "OVN DB, router id=%s"), router['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(_LW("Creating the router %s in OVN NB DB"),
                                router['id'])
                    self.l3_plugin.create_lrouter_in_ovn(router)
                    if 'routes' in router:
                        update_sroutes_list.append({
                            'id': router['id'],
                            'add': router['routes'],
                            'del': []
                        })
                    if 'routes' in db_extends[router['id']]:
                        update_sroutes_list.append({
                            'id':
                            router['id'],
                            'add':
                            db_extends[router['id']]['routes'],
                            'del': []
                        })
                    if 'snats' in db_extends[router['id']]:
                        update_snats_list.append({
                            'id':
                            router['id'],
                            'add':
                            db_extends[router['id']]['snats'],
                            'del': []
                        })
                    if 'fips' in db_extends[router['id']]:
                        update_fips_list.append({
                            'id':
                            router['id'],
                            'add':
                            db_extends[router['id']]['fips'],
                            'del': []
                        })
                except RuntimeError:
                    LOG.warning(
                        _LW("Create router in OVN NB failed for"
                            " router %s"), router['id'])

        for rp_id, rrport in db_router_ports.items():
            LOG.warning(
                _LW("Router Port found in Neutron but not in OVN "
                    "DB, router port_id=%s"), rrport['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(
                        _LW("Creating the router port %s in "
                            "OVN NB DB"), rrport['id'])
                    self.l3_plugin.create_lrouter_port_in_ovn(
                        ctx, rrport['device_id'], rrport)
                except RuntimeError:
                    LOG.warning(
                        _LW("Create router port in OVN "
                            "NB failed for"
                            " router port %s"), rrport['id'])

        for router_id, rport in update_lrport_list:
            LOG.warning(
                _LW("Router Port port_id=%s needs to be updated"
                    " for networks changed"), rport['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(
                        _LW("Updating networks on router port %s in "
                            "OVN NB DB"), rport['id'])
                    self.l3_plugin.update_lrouter_port_in_ovn(
                        ctx, router_id, rport, rport['networks'])
                except RuntimeError:
                    LOG.warning(
                        _LW("Update router port networks in OVN "
                            "NB failed for"
                            " router port %s"), rport['id'])

        with self.ovn_api.transaction(check_error=True) as txn:
            for lrouter in del_lrouters_list:
                LOG.warning(
                    _LW("Router found in OVN but not in "
                        "Neutron, router id=%s"), lrouter['name'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.warning(_LW("Deleting the router %s from OVN NB DB"),
                                lrouter['name'])
                    txn.add(
                        self.ovn_api.delete_lrouter(
                            utils.ovn_name(lrouter['name'])))

            for lrport_info in del_lrouter_ports_list:
                LOG.warning(
                    _LW("Router Port found in OVN but not in "
                        "Neutron, port_id=%s"), lrport_info['port'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.warning(_LW("Deleting the port %s from OVN NB DB"),
                                lrport_info['port'])
                    txn.add(
                        self.ovn_api.delete_lrouter_port(
                            utils.ovn_lrouter_port_name(lrport_info['port']),
                            utils.ovn_name(lrport_info['lrouter']),
                            if_exists=False))
            for sroute in update_sroutes_list:
                if sroute['add']:
                    LOG.warning(
                        _LW("Router %(id)s static routes %(route)s "
                            "found in Neutron but not in OVN"), {
                                'id': sroute['id'],
                                'route': sroute['add']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(_LW("Add static routes %s to OVN NB DB"),
                                    sroute['add'])
                        for route in sroute['add']:
                            txn.add(
                                self.ovn_api.add_static_route(
                                    utils.ovn_name(sroute['id']),
                                    ip_prefix=route['destination'],
                                    nexthop=route['nexthop']))
                if sroute['del']:
                    LOG.warning(
                        _LW("Router %(id)s static routes %(route)s "
                            "found in OVN but not in Neutron"), {
                                'id': sroute['id'],
                                'route': sroute['del']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(
                            _LW("Delete static routes %s from OVN "
                                "NB DB"), sroute['del'])
                        for route in sroute['del']:
                            txn.add(
                                self.ovn_api.delete_static_route(
                                    utils.ovn_name(sroute['id']),
                                    ip_prefix=route['destination'],
                                    nexthop=route['nexthop']))
            for fip in update_fips_list:
                if fip['del']:
                    LOG.warning(
                        _LW("Router %(id)s floating ips %(fip)s "
                            "found in OVN but not in Neutron"), {
                                'id': fip['id'],
                                'fip': fip['del']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(
                            _LW("Delete floating ips %s from OVN NB DB"),
                            fip['del'])
                        for nat in fip['del']:
                            txn.add(
                                self.ovn_api.delete_nat_rule_in_lrouter(
                                    utils.ovn_name(fip['id']),
                                    logical_ip=nat['logical_ip'],
                                    external_ip=nat['external_ip'],
                                    type='dnat_and_snat'))
                if fip['add']:
                    LOG.warning(
                        _LW("Router %(id)s floating ips %(fip)s "
                            "found in Neutron but not in OVN"), {
                                'id': fip['id'],
                                'fip': fip['add']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(_LW("Add floating ips %s to OVN NB DB"),
                                    fip['add'])
                        for nat in fip['add']:
                            txn.add(
                                self.ovn_api.add_nat_rule_in_lrouter(
                                    utils.ovn_name(fip['id']),
                                    logical_ip=nat['logical_ip'],
                                    external_ip=nat['external_ip'],
                                    type='dnat_and_snat'))
            for snat in update_snats_list:
                if snat['del']:
                    LOG.warning(
                        _LW("Router %(id)s snat %(snat)s "
                            "found in OVN but not in Neutron"), {
                                'id': snat['id'],
                                'snat': snat['del']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(_LW("Delete snats %s from OVN NB DB"),
                                    snat['del'])
                        for nat in snat['del']:
                            txn.add(
                                self.ovn_api.delete_nat_rule_in_lrouter(
                                    utils.ovn_name(snat['id']),
                                    logical_ip=nat['logical_ip'],
                                    external_ip=nat['external_ip'],
                                    type='snat'))
                if snat['add']:
                    LOG.warning(
                        _LW("Router %(id)s snat %(snat)s "
                            "found in Neutron but not in OVN"), {
                                'id': snat['id'],
                                'snat': snat['add']
                            })
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(_LW("Add snats %s to OVN NB DB"),
                                    snat['add'])
                        for nat in snat['add']:
                            txn.add(
                                self.ovn_api.add_nat_rule_in_lrouter(
                                    utils.ovn_name(snat['id']),
                                    logical_ip=nat['logical_ip'],
                                    external_ip=nat['external_ip'],
                                    type='snat'))
        LOG.debug('OVN-NB Sync routers and router ports finished %s' %
                  str(datetime.now()))
示例#20
0
    def sync_routers_and_rports(self, ctx):
        """Sync Routers between neutron and NB.

        @param ctx: neutron context
        @type  ctx: object of type neutron.context.Context
        @var   db_routers: List of Routers from neutron DB
        @var   db_router_ports: List of Router ports from neutron DB
        @var   lrouters: NB dictionary of logical routers and
               the corresponding logical router ports.
               vs list-of-acls
        @var   del_lrouters_list: List of Routers that need to be
               deleted from NB
        @var   del_lrouter_ports_list: List of Router ports that need to be
               deleted from NB
        @return: Nothing
        """
        if not config.is_ovn_l3():
            LOG.debug("OVN L3 mode is disabled, skipping "
                      "sync routers and router ports")
            return

        LOG.debug('OVN-NB Sync Routers and Router ports started')
        db_routers = {}
        db_router_ports = {}
        for router in self.l3_plugin.get_routers(ctx):
            db_routers[router['id']] = router

        interfaces = self.l3_plugin._get_sync_interfaces(ctx,
                                                         db_routers.keys())
        for interface in interfaces:
            db_router_ports[interface['id']] = interface
        lrouters = self.ovn_api.get_all_logical_routers_with_rports()
        del_lrouters_list = []
        del_lrouter_ports_list = []
        update_sroutes_list = []
        for lrouter in lrouters:
            if lrouter['name'] in db_routers:
                for lrport in lrouter['ports']:
                    if lrport in db_router_ports:
                        del db_router_ports[lrport]
                    else:
                        del_lrouter_ports_list.append(
                            {'port': lrport, 'lrouter': lrouter['name']})
                if 'routes' in db_routers[lrouter['name']]:
                    db_routes = db_routers[lrouter['name']]['routes']
                else:
                    db_routes = []
                ovn_routes = lrouter['static_routes']
                add_routes, del_routes = n_utils.diff_list_of_dict(
                    ovn_routes, db_routes)
                update_sroutes_list.append({'id': lrouter['name'],
                                            'add': add_routes,
                                            'del': del_routes})
                del db_routers[lrouter['name']]
            else:
                del_lrouters_list.append(lrouter)

        for r_id, router in db_routers.items():
            LOG.warning(_LW("Router found in Neutron but not in "
                            "OVN DB, router id=%s"), router['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(_LW("Creating the router %s in OVN NB DB"),
                                router['id'])
                    self.l3_plugin.create_lrouter_in_ovn(router)
                    if 'routes' in router:
                        update_sroutes_list.append(
                            {'id': router['id'], 'add': router['routes'],
                             'del': []})
                except RuntimeError:
                    LOG.warning(_LW("Create router in OVN NB failed for"
                                    " router %s"), router['id'])

        for rp_id, rrport in db_router_ports.items():
            LOG.warning(_LW("Router Port found in Neutron but not in OVN "
                            "DB, router port_id=%s"), rrport['id'])
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.warning(_LW("Creating the router port %s in "
                                    "OVN NB DB"), rrport['id'])
                    self.l3_plugin.create_lrouter_port_in_ovn(
                        ctx, rrport['device_id'], rrport)
                except RuntimeError:
                    LOG.warning(_LW("Create router port in OVN "
                                    "NB failed for"
                                    " router port %s"), rrport['id'])

        with self.ovn_api.transaction(check_error=True) as txn:
            for lrouter in del_lrouters_list:
                LOG.warning(_LW("Router found in OVN but not in "
                                "Neutron, router id=%s"), lrouter['name'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.warning(_LW("Deleting the router %s from OVN NB DB"),
                                lrouter['name'])
                    txn.add(self.ovn_api.delete_lrouter(
                            utils.ovn_name(lrouter['name'])))

            for lrport_info in del_lrouter_ports_list:
                LOG.warning(_LW("Router Port found in OVN but not in "
                                "Neutron, port_id=%s"), lrport_info['port'])
                if self.mode == SYNC_MODE_REPAIR:
                    LOG.warning(_LW("Deleting the port %s from OVN NB DB"),
                                lrport_info['port'])
                    txn.add(self.ovn_api.delete_lrouter_port(
                            utils.ovn_lrouter_port_name(lrport_info['port']),
                            utils.ovn_name(lrport_info['lrouter']),
                            if_exists=False))
            for sroute in update_sroutes_list:
                if sroute['add']:
                    LOG.warning("Router %s static routes %s found in "
                                "Neutron but not in OVN", sroute['id'],
                                sroute['add'])
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(_LW("Add static routes %s to OVN NB DB"),
                                    sroute['add'])
                        for route in sroute['add']:
                            txn.add(self.ovn_api.add_static_route(
                                utils.ovn_name(sroute['id']),
                                ip_prefix=route['destination'],
                                nexthop=route['nexthop']))
                if sroute['del']:
                    LOG.warning("Router %s static routes %s found in "
                                "OVN but not in Neutron", sroute['id'],
                                sroute['del'])
                    if self.mode == SYNC_MODE_REPAIR:
                        LOG.warning(_LW("Delete static routes %s from OVN "
                                        "NB DB"), sroute['del'])
                        for route in sroute['del']:
                            txn.add(self.ovn_api.delete_static_route(
                                utils.ovn_name(sroute['id']),
                                ip_prefix=route['destination'],
                                nexthop=route['nexthop']))
        LOG.debug('OVN-NB Sync routers and router ports finished')
示例#21
0
 def _setup_rpc(self):
     self.endpoints = [dhcp_rpc.DhcpRpcCallback(),
                       agents_db.AgentExtRpcCallback(),
                       metadata_rpc.MetadataRpcCallback()]
     if not config.is_ovn_l3():
         self.endpoints.append(l3_rpc.L3RpcCallback())