def _get_l3_admin_net(self, create=False): network = None context = self._get_admin_context() filters = self._get_l3_admin_net_query_filter() networks = self._plugin.get_networks(context, filters=filters) if len(networks) == 0 and create: try: network = self._create_l3_admin_net(context) self._create_l3_admin_subnet(context, network["id"]) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE("Error in creating L3 admin network.")) elif len(networks) == 1: network = networks[0] subnet_ids = network.get("subnets") net_id = network["id"] if not subnet_ids and create: try: self._create_l3_admin_subnet(context, net_id) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE("Error in creating l3 admin subnet.")) elif len(subnet_ids) == 1: self._validate_l3_admin_subnet(context, subnet_ids[0]) else: msg = _("Expected number of subnets in l3 admin network is " "1, found %d.") % len(subnet_ids) raise exc.L3AdminNetSubnetError(error_message=msg) else: msg = _("Expected number of l3 admin networks is 1, found " "%d.") % len(networks) raise exc.L3AdminNetError(error_message=msg) return network
def update_floatingip(self, context, id, floatingip): fip_db = self._get_floatingip(context, id) previous_fip = self._make_floatingip_dict(fip_db) previous_port_id = previous_fip.get('port_id') fip = super(OVNL3RouterPlugin, self).update_floatingip(context, id, floatingip) new_port_id = fip.get('port_id') fip_status = None if previous_port_id and ( previous_port_id != new_port_id or (previous_fip['fixed_ip_address'] != fip['fixed_ip_address'])): # 1. Floating IP dissociated # 2. Floating IP re-associated to a new port # 3. Floating IP re-associated to a new fixed_ip (same port) update_fip = {} update_fip['logical_ip'] = previous_fip['fixed_ip_address'] update_fip['external_ip'] = fip['floating_ip_address'] try: self._update_floating_ip_in_ovn(context, previous_fip['router_id'], update_fip, associate=False) fip_status = n_const.FLOATINGIP_STATUS_DOWN except Exception: with excutils.save_and_reraise_exception(): LOG.error( _LE('Unable to update floating ip in ' 'gateway router')) if new_port_id: update_fip = {} update_fip['fip_port_id'] = fip_db['floating_port_id'] update_fip['fip_net_id'] = fip['floating_network_id'] update_fip['logical_ip'] = fip['fixed_ip_address'] update_fip['external_ip'] = fip['floating_ip_address'] try: self._update_floating_ip_in_ovn(context, fip['router_id'], update_fip) fip_status = n_const.FLOATINGIP_STATUS_ACTIVE except Exception: with excutils.save_and_reraise_exception(): LOG.error( _LE('Unable to update floating ip in ' 'gateway router')) if fip_status: self.update_floatingip_status(context, id, fip_status) return fip
def _add_router_ext_gw(self, context, router): router_id = router['id'] lrouter_name = utils.ovn_name(router['id']) # 1. Add the external gateway router port. ext_gw_ip = self._get_external_gateway_ip(context, router) gw_port_id = router['gw_port_id'] port = self._plugin.get_port(context.elevated(), gw_port_id) try: self.create_lrouter_port_in_ovn(context.elevated(), router_id, port) except Exception: with excutils.save_and_reraise_exception(): self._delete_router_ext_gw(context, router_id, router) LOG.error( _LE('Unable to add external router port %(id)s to' 'lrouter %(name)s'), { 'id': port['id'], 'name': lrouter_name }) # 2. Add default route with nexthop as ext_gw_ip route = [{'destination': '0.0.0.0/0', 'nexthop': ext_gw_ip}] try: self._update_lrouter_routes(context, router_id, route, []) except Exception: with excutils.save_and_reraise_exception(): self._delete_router_ext_gw(context, router_id, router) LOG.error( _LE('Error updating routes %(route)s in lrouter ' '%(name)s'), { 'route': route, 'name': lrouter_name }) # 3. Add snat rules for tenant networks in lrouter if snat is enabled if utils.is_snat_enabled(router): try: networks = self._get_v4_network_of_all_router_ports( context, router_id) if networks: self._update_snat_for_networks(context, router, networks, enable_snat=True) except Exception: with excutils.save_and_reraise_exception(): self._delete_router_ext_gw(context, router_id, router) LOG.error(_LE('Error in updating SNAT for lrouter %s'), lrouter_name)
def create_floatingip(self, context, floatingip, initial_status=n_const.FLOATINGIP_STATUS_ACTIVE): fip = super(OVNL3RouterPlugin, self).create_floatingip( context, floatingip, initial_status=n_const.FLOATINGIP_STATUS_ACTIVE) router_id = fip.get('router_id') if router_id: update_fip = {} fip_db = self._get_floatingip(context, fip['id']) # Elevating the context here, to pass this test case # OVNL3ExtrarouteTests.test_floatingip_association_on_unowned_ # router router = self.get_router(context.elevated(), router_id) update_fip['fip_port_id'] = fip_db['floating_port_id'] update_fip['fip_net_id'] = fip['floating_network_id'] update_fip['logical_ip'] = fip['fixed_ip_address'] update_fip['external_ip'] = fip['floating_ip_address'] update_fip['gw_port_id'] = router['gw_port_id'] try: self._update_floating_ip_in_ovn(context, router_id, update_fip) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to create floating ip in gateway' 'router')) return fip
def _update_floating_ip_in_ovn(self, context, router_id, update, associate=True): fip_apis = {} fip_apis['nat'] = self._ovn.add_nat_rule_in_lrouter if \ associate else self._ovn.delete_nat_rule_in_lrouter fip_apis['garp'] = self._ovn.add_nat_ip_to_lrport_peer_options if \ associate else self._ovn.delete_nat_ip_from_lrport_peer_options gw_lrouter_name = utils.ovn_gateway_router_name(router_id) try: with self._ovn.transaction(check_error=True) as txn: if associate: # TODO(chandrav): Since the floating ip port is not # bound to any chassis, packets destined to floating ip # will be dropped. To overcome this, delete the floating # ip port. Proper fix for this would be to redirect packets # destined to floating ip to the router port. This would # require changes in ovn-northd. txn.add(self._ovn.delete_lswitch_port( update['fip_port_id'], utils.ovn_name(update['fip_net_id']))) txn.add(fip_apis['nat'](gw_lrouter_name, type='dnat_and_snat', logical_ip=update['logical_ip'], external_ip=update['external_ip'])) txn.add(fip_apis['garp'](update['gw_port_id'], nat_ip=update['external_ip'])) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to update NAT rule in gateway router'))
def create_floatingip(self, context, floatingip, initial_status=n_const.FLOATINGIP_STATUS_DOWN): fip = super(OVNL3RouterPlugin, self).create_floatingip(context, floatingip, initial_status) router_id = fip.get('router_id') if router_id: update_fip = {} fip_db = self._get_floatingip(context, fip['id']) # Elevating the context here, to pass this test case # OVNL3ExtrarouteTests.test_floatingip_association_on_unowned_ # router router = self.get_router(context.elevated(), router_id) update_fip['fip_port_id'] = fip_db['floating_port_id'] update_fip['fip_net_id'] = fip['floating_network_id'] update_fip['logical_ip'] = fip['fixed_ip_address'] update_fip['external_ip'] = fip['floating_ip_address'] update_fip['gw_port_id'] = router['gw_port_id'] try: self._update_floating_ip_in_ovn(context, router_id, update_fip) self.update_floatingip_status(context, fip['id'], n_const.FLOATINGIP_STATUS_ACTIVE) except Exception: with excutils.save_and_reraise_exception(): LOG.error( _LE('Unable to create floating ip in gateway' 'router')) return fip
def create_floatingip(self, context, floatingip, initial_status=n_const.FLOATINGIP_STATUS_DOWN): fip = super(OVNL3RouterPlugin, self).create_floatingip(context, floatingip, initial_status) router_id = fip.get('router_id') if router_id: update_fip = {} fip_db = self._get_floatingip(context, fip['id']) update_fip['fip_port_id'] = fip_db['floating_port_id'] update_fip['fip_net_id'] = fip['floating_network_id'] update_fip['logical_ip'] = fip['fixed_ip_address'] update_fip['external_ip'] = fip['floating_ip_address'] try: self._update_floating_ip_in_ovn(context, router_id, update_fip) self.update_floatingip_status(context, fip['id'], n_const.FLOATINGIP_STATUS_ACTIVE) except Exception: with excutils.save_and_reraise_exception(): LOG.error( _LE('Unable to create floating ip in gateway' 'router')) return fip
def create_router(self, context, router): gw_info, router = self._create_router(context, router) try: self.create_lrouter_in_ovn(router) except Exception: LOG.exception(_LE('Unable to create lrouter for %s'), router['id']) super(OVNL3RouterPlugin, self).delete_router(context, router['id']) raise n_exc.ServiceUnavailable() try: if gw_info: self._update_router_gw_info(context, router['id'], gw_info) except Exception: LOG.exception(_LE('Fail to set gateway for router %s'), router['id']) return router
def update_floatingip(self, context, id, floatingip): fip_db = self._get_floatingip(context, id) previous_fip = self._make_floatingip_dict(fip_db) previous_router_id = previous_fip.get('router_id') fip = super(OVNL3RouterPlugin, self).update_floatingip(context, id, floatingip) new_router_id = fip['router_id'] if previous_router_id: update_fip = {} router = self.get_router(context.elevated(), previous_router_id) update_fip['logical_ip'] = previous_fip['fixed_ip_address'] update_fip['external_ip'] = fip['floating_ip_address'] update_fip['gw_port_id'] = router['gw_port_id'] try: self._update_floating_ip_in_ovn(context, previous_router_id, update_fip, associate=False) self.update_floatingip_status(context, id, n_const.FLOATINGIP_STATUS_DOWN) except Exception: with excutils.save_and_reraise_exception(): LOG.error( _LE('Unable to update floating ip in ' 'gateway router')) if new_router_id: router = self.get_router(context.elevated(), new_router_id) update_fip = {} update_fip['fip_port_id'] = fip_db['floating_port_id'] update_fip['fip_net_id'] = fip['floating_network_id'] update_fip['logical_ip'] = fip['fixed_ip_address'] update_fip['external_ip'] = fip['floating_ip_address'] update_fip['gw_port_id'] = router['gw_port_id'] try: self._update_floating_ip_in_ovn(context, new_router_id, update_fip) self.update_floatingip_status(context, id, n_const.FLOATINGIP_STATUS_ACTIVE) except Exception: with excutils.save_and_reraise_exception(): LOG.error( _LE('Unable to update floating ip in ' 'gateway router')) return fip
def add_router_interface(self, context, router_id, interface_info): router_interface_info = \ super(OVNL3RouterPlugin, self).add_router_interface( context, router_id, interface_info) port = self._plugin.get_port(context, router_interface_info['port_id']) multi_prefix = False if (len(router_interface_info['subnet_ids']) == 1 and len(port['fixed_ips']) > 1): # NOTE(lizk) It's adding a subnet onto an already existing router # interface port, try to update lrouter port 'networks' column. self.update_lrouter_port_in_ovn(context, router_id, port) multi_prefix = True else: self.create_lrouter_port_in_ovn(context, router_id, port) router = self.get_router(context, router_id) if not router.get(l3.EXTERNAL_GW_INFO): return router_interface_info cidr = None for fixed_ip in port['fixed_ips']: subnet = self._plugin.get_subnet(context, fixed_ip['subnet_id']) if multi_prefix: if 'subnet_id' in interface_info: if subnet['id'] is not interface_info['subnet_id']: continue if subnet['ip_version'] == 4: cidr = subnet['cidr'] if not cidr: return router_interface_info try: transit_net_ports = self._get_transit_network_ports() nexthop = transit_net_ports['dtsp']['ip'] gw_lrouter_name = utils.ovn_gateway_router_name(router_id) if self._is_snat_enabled(router): self._update_snat_and_static_routes_for_networks( context, router, networks=[cidr], nexthop=nexthop, enable_snat=True, update_static_routes=True) else: route = {'destination': cidr, 'nexthop': nexthop} self._update_lrouter_routes( context, router_id, add=[route], remove=[], lrouter_name=gw_lrouter_name) except Exception: with excutils.save_and_reraise_exception(): self._ovn.delete_lrouter_port( utils.ovn_lrouter_port_name(port['id']), utils.ovn_name(router_id)).execute(check_error=True) super(OVNL3RouterPlugin, self).remove_router_interface( context, router_id, router_interface_info) LOG.error(_LE('Error updating snat for subnet %(subnet)s in ' 'router %(router)s'), {'subnet': router_interface_info['subnet_id'], 'router': router_id}) return router_interface_info
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_nb_sync.SYNC_MODE_LOG, ovn_nb_sync.SYNC_MODE_REPAIR]: LOG.error(_LE('Invalid sync mode : ["%s"]. Should be "log" or ' '"repair"'), mode) return # we dont want the service plugins to be loaded. conf.service_plugins = [] ovn_plugin = manager.NeutronManager.get_plugin() try: ovn_plugin._ovn = impl_idl_ovn.OvsdbOvnIdl(ovn_plugin) except RuntimeError: LOG.error(_LE('Invalid --ovn-ovsdb_connection parameter provided.')) return synchronizer = ovn_nb_sync.OvnNbSynchronizer( ovn_plugin, ovn_plugin._ovn, mode) ctx = context.get_admin_context() LOG.info(_LI('Syncing the networks and ports with mode : %s'), mode) try: synchronizer.sync_networks_and_ports(ctx) except Exception: LOG.exception(_LE("Error syncing the networks and ports. Check the " "--database-connection value again")) return LOG.info(_LI('Sync completed'))
def create_router(self, context, router): router = super(OVNL3RouterPlugin, self).create_router(context, router) try: self.create_lrouter_in_ovn(router) except Exception: LOG.exception(_LE('Unable to create lrouter for %s'), router['id']) super(OVNL3RouterPlugin, self).delete_router(context, router['id']) raise n_exc.ServiceUnavailable() return router
def delete_network(self, context, network_id): with context.session.begin(subtransactions=True): super(OVNPlugin, self).delete_network(context, network_id) try: self._ovn.delete_lswitch( utils.ovn_name(network_id), if_exists=True).execute( check_error=True) except Exception: LOG.exception(_LE('Unable to delete lswitch for %s'), network_id)
def update_floatingip(self, context, id, floatingip): fip_db = self._get_floatingip(context, id) previous_fip = self._make_floatingip_dict(fip_db) previous_router_id = previous_fip.get('router_id') fip = super(OVNL3RouterPlugin, self).update_floatingip(context, id, floatingip) new_router_id = fip['router_id'] if previous_router_id: update_fip = {} router = self.get_router(context.elevated(), previous_router_id) update_fip['logical_ip'] = previous_fip['fixed_ip_address'] update_fip['external_ip'] = fip['floating_ip_address'] update_fip['gw_port_id'] = router['gw_port_id'] try: self._update_floating_ip_in_ovn(context, previous_router_id, update_fip, associate=False) self.update_floatingip_status(context, id, n_const.FLOATINGIP_STATUS_DOWN) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to update floating ip in ' 'gateway router')) if new_router_id: router = self.get_router(context.elevated(), new_router_id) update_fip = {} update_fip['fip_port_id'] = fip_db['floating_port_id'] update_fip['fip_net_id'] = fip['floating_network_id'] update_fip['logical_ip'] = fip['fixed_ip_address'] update_fip['external_ip'] = fip['floating_ip_address'] update_fip['gw_port_id'] = router['gw_port_id'] try: self._update_floating_ip_in_ovn(context, new_router_id, update_fip) self.update_floatingip_status(context, id, n_const.FLOATINGIP_STATUS_ACTIVE) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to update floating ip in ' 'gateway router')) return fip
def add_router_interface(self, context, router_id, interface_info): router_interface_info = \ super(OVNL3RouterPlugin, self).add_router_interface( context, router_id, interface_info) port = self._plugin.get_port(context, router_interface_info['port_id']) multi_prefix = False if (len(router_interface_info['subnet_ids']) == 1 and len(port['fixed_ips']) > 1): # NOTE(lizk) It's adding a subnet onto an already existing router # interface port, try to update lrouter port 'networks' column. self.update_lrouter_port_in_ovn(context, router_id, port) multi_prefix = True else: self.create_lrouter_port_in_ovn(context, router_id, port) router = self.get_router(context, router_id) if not router.get(l3.EXTERNAL_GW_INFO): return router_interface_info cidr = None for fixed_ip in port['fixed_ips']: subnet = self._plugin.get_subnet(context, fixed_ip['subnet_id']) if multi_prefix: if 'subnet_id' in interface_info: if subnet['id'] is not interface_info['subnet_id']: continue if subnet['ip_version'] == 4: cidr = subnet['cidr'] if not cidr: return router_interface_info try: if utils.is_snat_enabled(router): self._update_snat_for_networks(context, router, networks=[cidr], enable_snat=True) except Exception: with excutils.save_and_reraise_exception(): self._ovn.delete_lrouter_port( utils.ovn_lrouter_port_name(port['id']), utils.ovn_name(router_id)).execute(check_error=True) super(OVNL3RouterPlugin, self).remove_router_interface(context, router_id, router_interface_info) LOG.error( _LE('Error updating snat for subnet %(subnet)s in ' 'router %(router)s'), { 'subnet': router_interface_info['subnet_id'], 'router': router_id }) return router_interface_info
def remove_router_interface(self, context, router_id, interface_info): router_interface_info = \ super(OVNL3RouterPlugin, self).remove_router_interface( context, router_id, interface_info) router = self.get_router(context, router_id) port_id = router_interface_info['port_id'] multi_prefix = False try: port = self._plugin.get_port(context, port_id) # The router interface port still exists, call ovn to update it. self.update_lrouter_port_in_ovn(context, router_id, port) multi_prefix = True except n_exc.PortNotFound: # The router interface port doesn't exist any more, call ovn to # delete it. self._ovn.delete_lrouter_port( utils.ovn_lrouter_port_name(port_id), utils.ovn_name(router_id), if_exists=False).execute(check_error=True) if not router.get(l3.EXTERNAL_GW_INFO): return router_interface_info try: cidr = None if multi_prefix: subnet = self._plugin.get_subnet(context, interface_info['subnet_id']) if subnet['ip_version'] == 4: cidr = subnet['cidr'] else: subnet_ids = router_interface_info.get('subnet_ids') for subnet_id in subnet_ids: subnet = self._plugin.get_subnet(context, subnet_id) if subnet['ip_version'] == 4: cidr = subnet['cidr'] break if not cidr: return router_interface_info if utils.is_snat_enabled(router): self._update_snat_for_networks(context, router, networks=[cidr], enable_snat=False) except Exception: with excutils.save_and_reraise_exception(): super(OVNL3RouterPlugin, self).add_router_interface(context, router_id, interface_info) LOG.error(_LE('Error is deleting snat')) return router_interface_info
def update_router(self, context, id, router): original_router = self.get_router(context, id) result = super(OVNL3RouterPlugin, self).update_router(context, id, router) update = {} added = [] removed = [] router_name = utils.ovn_name(id) if 'admin_state_up' in router['router']: enabled = router['router']['admin_state_up'] if enabled != original_router['admin_state_up']: update['enabled'] = enabled if 'name' in router['router']: if router['router']['name'] != original_router['name']: external_ids = { ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: router['router']['name'] } update['external_ids'] = external_ids """ Update static routes """ if 'routes' in router['router']: routes = router['router']['routes'] added, removed = n_utils.diff_list_of_dict( original_router['routes'], routes) if update or added or removed: try: with self._ovn.transaction(check_error=True) as txn: if update: txn.add(self._ovn.update_lrouter( router_name, **update)) for route in added: txn.add( self._ovn.add_static_route( router_name, ip_prefix=route['destination'], nexthop=route['nexthop'])) for route in removed: txn.add( self._ovn.delete_static_route( router_name, ip_prefix=route['destination'], nexthop=route['nexthop'])) except Exception: LOG.exception(_LE('Unable to update lrouter for %s'), id) super(OVNL3RouterPlugin, self).update_router(context, id, original_router) raise n_exc.ServiceUnavailable() return result
def create_router(self, context, router): router = super(OVNL3RouterPlugin, self).create_router( context, router) try: self.create_lrouter_in_ovn(router) except Exception: LOG.exception(_LE('Unable to create lrouter for %s'), router['id']) super(OVNL3RouterPlugin, self).delete_router(context, router['id']) raise n_exc.ServiceUnavailable() return router
def update_router(self, context, id, router): original_router = self.get_router(context, id) result = super(OVNL3RouterPlugin, self).update_router( context, id, router) update = {} added = [] removed = [] router_name = utils.ovn_name(id) if 'admin_state_up' in router['router']: enabled = router['router']['admin_state_up'] if enabled != original_router['admin_state_up']: update['enabled'] = enabled if 'name' in router['router']: if router['router']['name'] != original_router['name']: external_ids = {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: router['router']['name']} update['external_ids'] = external_ids """ Update static routes """ if 'routes' in router['router']: routes = router['router']['routes'] added, removed = n_utils.diff_list_of_dict( original_router['routes'], routes) if update or added or removed: try: with self._ovn.transaction(check_error=True) as txn: if update: txn.add(self._ovn.update_lrouter(router_name, **update)) for route in added: txn.add(self._ovn.add_static_route(router_name, ip_prefix=route['destination'], nexthop=route['nexthop'])) for route in removed: txn.add(self._ovn.delete_static_route(router_name, ip_prefix=route['destination'], nexthop=route['nexthop'])) except Exception: LOG.exception(_LE('Unable to update lrouter for %s'), id) super(OVNL3RouterPlugin, self).update_router(context, id, original_router) raise n_exc.ServiceUnavailable() return result
def create_router(self, context, router): router = super(OVNL3RouterPlugin, self).create_router(context, router) try: # Create distributed logical router self.create_lrouter_in_ovn(router) if router.get(l3.EXTERNAL_GW_INFO): self._add_router_ext_gw(context, router) except Exception: with excutils.save_and_reraise_exception(): # Delete the logical router LOG.error(_LE('Unable to create lrouter for %s'), router['id']) super(OVNL3RouterPlugin, self).delete_router(context, router['id']) return router
def delete_floatingip(self, context, id): original_fip = self.get_floatingip(context, id) router_id = original_fip.get('router_id') super(OVNL3RouterPlugin, self).delete_floatingip(context, id) if router_id and original_fip.get('fixed_ip_address'): update_fip = {} update_fip['logical_ip'] = original_fip['fixed_ip_address'] update_fip['external_ip'] = original_fip['floating_ip_address'] try: self._update_floating_ip_in_ovn(context, router_id, update_fip, associate=False) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Error in disassociating floatingip: %s'), id)
def notify_loop(self): while True: try: match, event, row, updates = self.notifications.get() if (not isinstance(match, row_event.RowEvent) and (match, event, row, updates) == OvnIdl.STOP_EVENT): self.notifications.task_done() break match.run(event, row, updates) if match.ONETIME: self.unwatch_event(match) self.notifications.task_done() except Exception: # If any unexpected exception happens we don't want the # notify_loop to exit. LOG.exception(_LE('Unexpected exception in notify_loop'))
def notify_loop(self): while True: try: match, event, row, updates = self.notifications.get() if (not isinstance(match, row_event.RowEvent) and (match, event, row, updates) == ( OvnDbNotifyHandler.STOP_EVENT)): self.notifications.task_done() break match.run(event, row, updates) if match.ONETIME: self.unwatch_event(match) self.notifications.task_done() except Exception: # If any unexpected exception happens we don't want the # notify_loop to exit. LOG.exception(_LE('Unexpected exception in notify_loop'))
def _update_floating_ip_in_ovn(self, context, router_id, update, associate=True): fip_apis = {} fip_apis['nat'] = self._ovn.add_nat_rule_in_lrouter if \ associate else self._ovn.delete_nat_rule_in_lrouter gw_lrouter_name = utils.ovn_name(router_id) try: with self._ovn.transaction(check_error=True) as txn: nat_rule_args = (gw_lrouter_name, ) if associate: # TODO(chandrav): Since the floating ip port is not # bound to any chassis, packets destined to floating ip # will be dropped. To overcome this, delete the floating # ip port. Proper fix for this would be to redirect packets # destined to floating ip to the router port. This would # require changes in ovn-northd. txn.add( self._ovn.delete_lswitch_port( update['fip_port_id'], utils.ovn_name(update['fip_net_id']))) # Get the list of nat rules and check if the external_ip # with type 'dnat_and_snat' already exists or not. # If exists, set the new value. # This happens when the port associated to a floating ip # is deleted before the disassociation. lrouter_nat_rules = self._ovn.get_lrouter_nat_rules( gw_lrouter_name) for nat_rule in lrouter_nat_rules: if nat_rule['external_ip'] == update['external_ip'] \ and nat_rule['type'] == 'dnat_and_snat': fip_apis['nat'] = self._ovn.set_nat_rule_in_lrouter nat_rule_args = (gw_lrouter_name, nat_rule['uuid']) break txn.add(fip_apis['nat'](*nat_rule_args, type='dnat_and_snat', logical_ip=update['logical_ip'], external_ip=update['external_ip'])) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to update NAT rule in gateway router'))
def create_network(self, context, network): net = network['network'] # obviously.. ext_ids = {} physnet = self._get_attribute(net, pnet.PHYSICAL_NETWORK) if physnet: # If this is a provider network, validate that it's a type we # support. (flat or vlan) nettype = self._get_attribute(net, pnet.NETWORK_TYPE) if nettype not in ('flat', 'vlan'): msg = _('%s network type is not supported with provider ' 'networks (only flat or vlan).') % nettype raise n_exc.InvalidInput(error_message=msg) # NOTE(russellb) This is the provider network case. We stash the # provider networks fields on OVN Logical Switch. This logical # switch isn't actually used for anything else because a special # switch is created for every port attached to the provider # network. The reason we stash them is because these fields are # not actually stored in the Neutron database anywhere. :-( # They are stored in an ML2 specific db table by the ML2 plugin, # but there's no common code and table for other plugins. Stashing # them here is the easy solution for now, but a common Neutron db # table and YAM (yet another mixin) would be better eventually. segid = self._get_attribute(net, pnet.SEGMENTATION_ID) ext_ids.update({ ovn_const.OVN_PHYSNET_EXT_ID_KEY: physnet, ovn_const.OVN_NETTYPE_EXT_ID_KEY: nettype, }) if segid: ext_ids.update({ ovn_const.OVN_SEGID_EXT_ID_KEY: str(segid), }) with context.session.begin(subtransactions=True): result = super(OVNPlugin, self).create_network(context, network) self._process_l3_create(context, result, net) try: return self.create_network_in_ovn(result, ext_ids) except Exception: LOG.exception(_LE('Unable to create lswitch for %s'), result['id']) self.delete_network(context, result['id']) raise n_exc.ServiceUnavailable()
def delete_floatingip(self, context, id): original_fip = self.get_floatingip(context, id) router_id = original_fip.get('router_id') super(OVNL3RouterPlugin, self).delete_floatingip(context, id) if router_id and original_fip.get('fixed_ip_address'): update_fip = {} router = self.get_router(context.elevated(), router_id) update_fip['logical_ip'] = original_fip['fixed_ip_address'] update_fip['external_ip'] = original_fip['floating_ip_address'] update_fip['gw_port_id'] = router['gw_port_id'] try: self._update_floating_ip_in_ovn(context, router_id, update_fip, associate=False) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Error in disassociating floatingip: %s'), id)
def get_l3_admin_net_ports(self, names, device_id, device_owner, create=False): ctx = self._get_admin_context() filters = self._get_l3_admin_net_ports_query_filter(device_id, device_owner) ports = self._plugin.get_ports(ctx, filters=filters) if len(ports) == 0 and create: try: network = self._get_l3_admin_net(create=True) net_id = network["id"] ports = self._create_l3_admin_net_ports(ctx, net_id, names, device_id, device_owner) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE("Error in creating l3 admin net ports %r."), names) elif len(ports) == len(names): self._validate_l3_admin_net_ports(ports, names) else: msg = _("Expected number of l3 admin net ports %(e)d, " "found %(f)d.") % {"e": len(names), "f": len(ports)} raise exc.L3AdminNetPortsError(error_message=msg) return ports
def _create_router_gw_port(self, context, router, network_id, ext_ips): # Port has no 'tenant-id', as it is hidden from user LOG.debug("Class OVNL3RouterPlugin:::") gw_port = self._core_plugin.create_port( context.elevated(), { 'port': { 'tenant_id': router['tenant_id'], 'network_id': network_id, 'mac_address': attributes.ATTR_NOT_SPECIFIED, 'fixed_ips': attributes.ATTR_NOT_SPECIFIED, 'device_id': router['id'], 'device_owner': l3_db.DEVICE_OWNER_ROUTER_GW, 'admin_state_up': True, 'name': 'Extnet_' + router['name'][0:18] } }) if not gw_port['fixed_ips']: self._core_plugin.delete_port(context.elevated(), gw_port['id'], l3_port_check=False) msg = (_('No IPs available for external network %s') % network_id) raise n_exc.BadRequest(resource='router', msg=msg) try: self.create_gw_router_port_in_ovn(context, router['id'], gw_port) except Exception: self._core_plugin.delete_port(context.elevated(), gw_port['id'], l3_port_check=False) self.delete_gw_router_port_in_ovn(router['id'], gw_port['id']) LOG.exception(_LE('Fail to update gateway info for router %s'), router['id']) raise n_exc.ServiceUnavailable() with context.session.begin(subtransactions=True): router.gw_port = self._core_plugin._get_port( context.elevated(), gw_port['id']) router_port = l3_db.RouterPort( router_id=router.id, port_id=gw_port['id'], port_type=l3_db.DEVICE_OWNER_ROUTER_GW) context.session.add(router) context.session.add(router_port)
def _validate_l3_admin_subnet(self, context, subnet_id): subnet = None try: subnet = self._plugin.get_subnet(context, subnet_id) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("L3 admin subnet not found")) if subnet.get("cidr") != self._cidr: msg = _("Subnet CIDR %(a)s does not match configured value " "%(e)s.") % { "a": subnet.get("cidr"), "e": self._cidr, } raise exc.L3AdminNetSubnetError(error_message=msg) if subnet.get("name") != ovn_const.OVN_L3_ADMIN_NET_SUBNET_NAME: msg = _("Subnet name %(a)s does not match expected name " "%(e)s.") % { "a": subnet.get("name"), "e": ovn_const.OVN_L3_ADMIN_NET_SUBNET_NAME, } raise exc.L3AdminNetSubnetError(error_message=msg)
def _add_router_ext_gw(self, context, router): # TODO(chandrav): Add sync support, bug #1629076 to track this. transit_net_ports = self._get_transit_network_ports(create=True) router_id = router['id'] gw_lrouter_name = utils.ovn_gateway_router_name(router['id']) cleanup = [] # 1. Create gateway router try: self.create_lrouter_in_ovn(router, is_gateway_router=True) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to create gateway router %s'), gw_lrouter_name) cleanup.append('gw_router') # 2. Add the external gateway router port to gateway router. ext_gw_ip = self._get_external_gateway_ip(context, router) gw_port_id = router['gw_port_id'] port = self._plugin.get_port(context.elevated(), gw_port_id) try: self.create_lrouter_port_in_ovn(context.elevated(), router_id, port, is_lrouter_gateway_router=True) except Exception: with excutils.save_and_reraise_exception(): self._delete_router_ext_gw(context, router_id, router, transit_net_ports, cleanup) LOG.error(_LE('Unable to add external router port %(id)s to' 'gateway_router %(name)s'), {'id': port['id'], 'name': gw_lrouter_name}) cleanup.append('ext_gw_port') # 3. Add default route in gateway router with nexthop as ext_gw_ip route = [{'destination': '0.0.0.0/0', 'nexthop': ext_gw_ip}] try: self._update_lrouter_routes(context, router_id, route, [], gw_lrouter_name) except Exception: with excutils.save_and_reraise_exception(): self._delete_router_ext_gw(context, router_id, router, transit_net_ports, cleanup) LOG.error(_LE('Error updating routes %(route)s in lrouter ' '%(name)s'), {'route': route, 'name': gw_lrouter_name}) cleanup.append('ext_gw_ip_nexthop') # 4. Join the logical router and gateway router try: self._join_lrouter_and_gw_lrouter(router, transit_net_ports) except Exception: with excutils.save_and_reraise_exception(): self._delete_router_ext_gw(context, router_id, router, transit_net_ports, cleanup) LOG.error(_LE('Error in connecting lrouter and gateway router ' 'for router %s'), router_id) cleanup.append('join') # 5. Check if tenant router ports are already configured. # If snat is enabled, add snat rules and static routes for tenant # networks in gateway router # If snat is disabled, add only static routes for tenant networks in # gateway router (For traffic destined to floating ips) # Static routes are added with a nexthop of gtsp port ip in logical # router. try: networks = self._get_v4_network_of_all_router_ports(context, router_id) if not networks: return nexthop = transit_net_ports['dtsp']['ip'] if self._is_snat_enabled(router): self._update_snat_and_static_routes_for_networks( context, router, networks, nexthop, enable_snat=True, update_static_routes=True) else: routes = [] for network in networks: routes.append({'destination': network, 'nexthop': nexthop}) self._update_lrouter_routes( context, router_id, routes, remove=[], lrouter_name=gw_lrouter_name) except Exception: with excutils.save_and_reraise_exception(): self._delete_router_ext_gw(context, router_id, router, transit_net_ports, cleanup) LOG.error(_LE('Error in updating SNAT for router %s'), router_id)
def update_router(self, context, id, router): original_router = self.get_router(context, id) result = super(OVNL3RouterPlugin, self).update_router(context, id, router) gateway_new = result.get(l3.EXTERNAL_GW_INFO) gateway_old = original_router.get(l3.EXTERNAL_GW_INFO) revert_router = {'router': original_router} try: if gateway_new and not gateway_old: # Route gateway is set self._add_router_ext_gw(context, result) elif gateway_old and not gateway_new: # router gateway is removed self._delete_router_ext_gw(context, id, original_router) elif gateway_new and gateway_old: # Check if external gateway has changed, if yes, delete the old # gateway and add the new gateway if (gateway_old['network_id'] != gateway_new['network_id'] or set([ str(fixed_ip) for fixed_ip in gateway_old['external_fixed_ips'] ]) != set([ str(fixed_ip) for fixed_ip in gateway_new['external_fixed_ips'] ])): self._delete_router_ext_gw(context, id, original_router) self._add_router_ext_gw(context, result) else: # Check if snat has been enabled/disabled and update old_snat_state = gateway_old.get('enable_snat', True) new_snat_state = gateway_new.get('enable_snat', True) if old_snat_state != new_snat_state: networks = self._get_v4_network_of_all_router_ports( context, id) self._update_snat_for_networks( context, result, networks, enable_snat=new_snat_state) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to update lrouter for %s'), id) super(OVNL3RouterPlugin, self).update_router(context, id, revert_router) # Check for change in admin_state_up update = {} router_name = utils.ovn_name(id) if 'admin_state_up' in router['router']: enabled = router['router']['admin_state_up'] if enabled != original_router['admin_state_up']: update['enabled'] = enabled # Check for change in name if 'name' in router['router']: if router['router']['name'] != original_router['name']: external_ids = { ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: router['router']['name'] } update['external_ids'] = external_ids if update: try: self._ovn.update_lrouter(router_name, **update).execute(check_error=True) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to update lrouter for %s'), id) super(OVNL3RouterPlugin, self).update_router(context, id, revert_router) # Check for route updates added = [] removed = [] if 'routes' in router['router']: routes = router['router']['routes'] added, removed = helpers.diff_list_of_dict( original_router['routes'], routes) if added or removed: try: self._update_lrouter_routes(context, id, added, removed) except Exception: with excutils.save_and_reraise_exception(): LOG.error( _LE('Unable to update static routes in lrouter ' '%s'), id) super(OVNL3RouterPlugin, self).update_router(context, id, revert_router) return result
def update_router(self, context, id, router): original_router = self.get_router(context, id) result = super(OVNL3RouterPlugin, self).update_router(context, id, router) gateway_new = result.get(l3.EXTERNAL_GW_INFO) gateway_old = original_router.get(l3.EXTERNAL_GW_INFO) try: if gateway_new and not gateway_old: # Route gateway is set self._add_router_ext_gw(context, result) elif gateway_old and not gateway_new: # router gateway is removed self._delete_router_ext_gw(context, id, original_router) elif gateway_new and gateway_old: # Check if external gateway has changed, if yes, delete the old # gateway and add the new gateway if gateway_old['network_id'] != gateway_new['network_id']: self._delete_router_ext_gw(context, id, original_router) self._add_router_ext_gw(context, result) # Check if snat has been enabled/disabled and update old_snat_state = gateway_old.get('enable_snat', 'True') new_snat_state = gateway_new.get('enable_snat', 'True') if old_snat_state != new_snat_state: networks = self._get_v4_network_of_all_router_ports( context, id) self._update_snat_and_static_routes_for_networks( context, result, networks, nexthop=None, enable_snat=new_snat_state, update_static_routes=False) except Exception: with excutils.save_and_reraise_exception(): revert_router = {} LOG.error(_LE('Unable to update lrouter for %s'), id) revert_router['router'] = original_router super(OVNL3RouterPlugin, self).update_router(context, id, revert_router) # Check for change in admin_state_up update = {} router_name = utils.ovn_name(id) if 'admin_state_up' in router['router']: enabled = router['router']['admin_state_up'] if enabled != original_router['admin_state_up']: update['enabled'] = enabled # Check for change in name if 'name' in router['router']: if router['router']['name'] != original_router['name']: external_ids = {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: router['router']['name']} update['external_ids'] = external_ids if update: try: self._ovn.update_lrouter(router_name, **update).execute( check_error=True) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to update lrouter for %s'), id) router['router'] = original_router super(OVNL3RouterPlugin, self).update_router(context, id, router) # Check for route updates added = [] removed = [] if 'routes' in router['router']: routes = router['router']['routes'] added, removed = helpers.diff_list_of_dict( original_router['routes'], routes) if added or removed: try: self._update_lrouter_routes(context, id, added, removed) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE('Unable to update static routes in lrouter ' '%s'), id) router['router'] = original_router super(OVNL3RouterPlugin, self).update_router(context, id, router) return result
def remove_router_interface(self, context, router_id, interface_info): router_interface_info = \ super(OVNL3RouterPlugin, self).remove_router_interface( context, router_id, interface_info) router = self.get_router(context, router_id) port_id = router_interface_info['port_id'] multi_prefix = False try: port = self._plugin.get_port(context, port_id) # The router interface port still exists, call ovn to update it. self.update_lrouter_port_in_ovn(context, router_id, port) multi_prefix = True except n_exc.PortNotFound: # The router interface port doesn't exist any more, call ovn to # delete it. self._ovn.delete_lrouter_port(utils.ovn_lrouter_port_name(port_id), utils.ovn_name(router_id), if_exists=False ).execute(check_error=True) if not router.get(l3.EXTERNAL_GW_INFO): return router_interface_info try: cidr = None if multi_prefix: subnet = self._plugin.get_subnet(context, interface_info['subnet_id']) if subnet['ip_version'] == 4: cidr = subnet['cidr'] else: subnet_ids = router_interface_info.get('subnet_ids') for subnet_id in subnet_ids: subnet = self._plugin.get_subnet(context, subnet_id) if subnet['ip_version'] == 4: cidr = subnet['cidr'] break if not cidr: return router_interface_info router_name = utils.ovn_gateway_router_name(router_id) transit_net_ports = self._get_transit_network_ports() nexthop = transit_net_ports['dtsp']['ip'] if self._is_snat_enabled(router): self._update_snat_and_static_routes_for_networks( context, router, networks=[cidr], nexthop=nexthop, enable_snat=False, update_static_routes=True) else: route = {'destination': cidr, 'nexthop': nexthop} self._update_lrouter_routes( context, router_id, add=[route], remove=[], lrouter_name=router_name) except Exception: with excutils.save_and_reraise_exception(): super(OVNL3RouterPlugin, self).add_router_interface( context, router_id, interface_info) LOG.error(_LE('Error is deleting snat')) return router_interface_info
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'))
def _start_ovsdb_server_and_idls(self): self.temp_dir = self.useFixture(fixtures.TempDir()).path # Start 2 ovsdb-servers one each for OVN NB DB and OVN SB DB # ovsdb-server with OVN SB DB can be used to test the chassis up/down # events. self.ovsdb_server_mgr = self.useFixture( process.OvsdbServer(self.temp_dir, self.OVS_INSTALL_SHARE_PATH, ovn_nb_db=True, ovn_sb_db=True)) cfg.CONF.set_override( 'ovn_nb_connection', self.ovsdb_server_mgr.get_ovsdb_connection_path(), 'ovn') cfg.CONF.set_override( 'ovn_sb_connection', self.ovsdb_server_mgr.get_ovsdb_connection_path(db_type='sb'), 'ovn') num_attempts = 0 # 5 seconds should be more than enough for the transaction to complete # for the test cases. # This also fixes the bug #1607639. cfg.CONF.set_override( 'ovsdb_connection_timeout', 5, 'ovn') # Created monitor IDL connection to the OVN NB DB. # This monitor IDL connection can be used to # - Verify that the ML2 OVN driver has written to the OVN NB DB # as expected. # - Create and delete resources in OVN NB DB outside of the # ML2 OVN driver scope to test scenarios like ovn_nb_sync. while num_attempts < 3: try: self.monitor_nb_idl_con = connection.Connection( self.ovsdb_server_mgr.get_ovsdb_connection_path(), 60, 'OVN_Northbound') self.monitor_nb_idl_con.start() self.monitor_nb_db_idl = self.monitor_nb_idl_con.idl break except Exception: LOG.exception(_LE("Error connecting to the OVN_Northbound DB")) num_attempts += 1 time.sleep(1) num_attempts = 0 # Create monitor IDL connection to the OVN SB DB. # This monitor IDL connection can be used to # - Create chassis rows # - Update chassis columns etc. while num_attempts < 3: try: self.monitor_sb_idl_con = connection.Connection( self.ovsdb_server_mgr.get_ovsdb_connection_path( db_type='sb'), 60, 'OVN_Southbound') self.monitor_sb_idl_con.start() self.monitor_sb_db_idl = self.monitor_sb_idl_con.idl break except Exception: LOG.exception(_LE("Error connecting to the OVN_Southbound DB")) num_attempts += 1 time.sleep(1) trigger = mock.MagicMock() if self.ovn_worker: trigger.im_class = ovsdb_monitor.OvnWorker cfg.CONF.set_override('neutron_sync_mode', 'off', 'ovn') trigger.im_class.__name__ = 'trigger' # mech_driver.post_fork_initialize creates the IDL connections self.mech_driver.post_fork_initialize(mock.ANY, mock.ANY, trigger)
def _start_ovsdb_server_and_idls(self): self.temp_dir = self.useFixture(fixtures.TempDir()).path # Start 2 ovsdb-servers one each for OVN NB DB and OVN SB DB # ovsdb-server with OVN SB DB can be used to test the chassis up/down # events. self.ovsdb_server_mgr = self.useFixture( process.OvsdbServer(self.temp_dir, self.OVS_INSTALL_SHARE_PATH, ovn_nb_db=True, ovn_sb_db=True)) cfg.CONF.set_override( 'ovn_nb_connection', self.ovsdb_server_mgr.get_ovsdb_connection_path(), 'ovn') cfg.CONF.set_override( 'ovn_sb_connection', self.ovsdb_server_mgr.get_ovsdb_connection_path(db_type='sb'), 'ovn') num_attempts = 0 # 5 seconds should be more than enough for the transaction to complete # for the test cases. # This also fixes the bug #1607639. cfg.CONF.set_override('ovsdb_connection_timeout', 5, 'ovn') # Created monitor IDL connection to the OVN NB DB. # This monitor IDL connection can be used to # - Verify that the ML2 OVN driver has written to the OVN NB DB # as expected. # - Create and delete resources in OVN NB DB outside of the # ML2 OVN driver scope to test scenarios like ovn_nb_sync. while num_attempts < 3: try: self.monitor_nb_idl_con = connection.Connection( self.ovsdb_server_mgr.get_ovsdb_connection_path(), 60, 'OVN_Northbound') self.monitor_nb_idl_con.start() self.monitor_nb_db_idl = self.monitor_nb_idl_con.idl break except Exception: LOG.exception(_LE("Error connecting to the OVN_Northbound DB")) num_attempts += 1 time.sleep(1) num_attempts = 0 while num_attempts < 3: try: self.monitor_sb_idl_con = connection.Connection( self.ovsdb_server_mgr.get_ovsdb_connection_path( db_type='sb'), 60, 'OVN_Southbound') self.monitor_sb_idl_con.start() self.monitor_sb_db_idl = self.monitor_sb_idl_con.idl break except Exception: LOG.exception(_LE("Error connecting to the OVN_Southbound DB")) num_attempts += 1 time.sleep(1) trigger = mock.MagicMock() if self.ovn_worker: trigger.im_class = ovsdb_monitor.OvnWorker cfg.CONF.set_override('neutron_sync_mode', 'off', 'ovn') # mech_driver.post_fork_initialize creates the IDL connections self.mech_driver.post_fork_initialize(mock.ANY, mock.ANY, trigger)
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'))
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_nb_sync.SYNC_MODE_LOG, ovn_nb_sync.SYNC_MODE_REPAIR]: LOG.error( _LE('Invalid sync mode : ["%s"]. Should be "log" or ' '"repair"'), mode) return # we dont want the service plugins to be loaded. conf.service_plugins = [] ovn_plugin = manager.NeutronManager.get_plugin() try: ovn_plugin._ovn = impl_idl_ovn.OvsdbOvnIdl(ovn_plugin) except RuntimeError: LOG.error(_LE('Invalid --ovn-ovsdb_connection parameter provided.')) return synchronizer = ovn_nb_sync.OvnNbSynchronizer(ovn_plugin, ovn_plugin._ovn, mode) ctx = context.get_admin_context() LOG.info(_LI('Syncing the networks and ports with mode : %s'), mode) try: synchronizer.sync_networks_and_ports(ctx) except Exception: LOG.exception( _LE("Error syncing the networks and ports. Check the " "--database-connection value 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'))