def handle(self, context): current_ctx = context.current sfc_port_data = prepare_port_data(current_ctx, name='sfc') normal_port_data = prepare_port_data(current_ctx, name='normal') sfc_port = neutron_utils.create_port(self._core_plugin, context._plugin_context, {'port': sfc_port_data}) LOG.info("Creating P4 port completed. ID= " + sfc_port['id']) normal_port = neutron_utils.create_port(self._core_plugin, context._plugin_context, {'port': normal_port_data}) LOG.info("Creating P4 port completed. ID= " + normal_port['id']) program = current_ctx['program'] with neutron_utils.delete_port_on_error(self._core_plugin, context._plugin_context, normal_port['id']): with neutron_utils.delete_port_on_error(self._core_plugin, context._plugin_context, sfc_port['id']): ports_data = self._prepare_port_data(sfc_port, normal_port) self.rpc_client.ask_agent_to_install_data_plane_module( self.rpc_ctx, network_id=normal_port_data['network_id'], ports=ports_data, program=program)
def create_or_delete_dhcp_port(self, subnet_context): port_id = self.get_dhcp_port_if_exists(subnet_context) plugin = subnet_context._plugin if not port_id and subnet_context.current['enable_dhcp']: LOG.debug("Creating ODL DHCP port for subnet %s of network %s", subnet_context.current['id'], subnet_context.current['network_id']) port = self._make_dhcp_port_dict(subnet_context) p_utils.create_port(plugin, subnet_context._plugin_context, port) if port_id and not subnet_context.current['enable_dhcp']: self._delete_port(plugin, subnet_context._plugin_context, port_id)
def _port_action(self, plugin, context, port, action): """Perform port operations taking care of concurrency issues.""" try: if action == 'create_port': return p_utils.create_port(plugin, context, port) elif action == 'update_port': return plugin.update_port(context, port['id'], port) else: msg = _('Unrecognized action') raise exceptions.Invalid(message=msg) except (db_exc.DBError, exceptions.NetworkNotFound, exceptions.SubnetNotFound, exceptions.IpAddressGenerationFailure) as e: with excutils.save_and_reraise_exception(reraise=False) as ctxt: if isinstance(e, exceptions.IpAddressGenerationFailure): # Check if the subnet still exists and if it does not, # this is the reason why the ip address generation failed. # In any other unlikely event re-raise try: subnet_id = port['port']['fixed_ips'][0]['subnet_id'] plugin.get_subnet(context, subnet_id) except exceptions.SubnetNotFound: pass else: ctxt.reraise = True net_id = port['port']['network_id'] LOG.warning(_LW("Action %(action)s for network %(net_id)s " "could not complete successfully: %(reason)s"), {"action": action, "net_id": net_id, 'reason': e})
def _add_csnat_router_interface_port( self, context, router, network_id, subnet_id, do_pop=True): """Add SNAT interface to the specified router and subnet.""" port_data = {'tenant_id': '', 'network_id': network_id, 'fixed_ips': [{'subnet_id': subnet_id}], 'device_id': router.id, 'device_owner': const.DEVICE_OWNER_ROUTER_SNAT, 'admin_state_up': True, 'name': ''} snat_port = p_utils.create_port(self._core_plugin, context, {'port': port_data}) if not snat_port: msg = _("Unable to create the SNAT Interface Port") raise n_exc.BadRequest(resource='router', msg=msg) with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort( port_id=snat_port['id'], router_id=router.id, port_type=const.DEVICE_OWNER_ROUTER_SNAT ) context.session.add(router_port) if do_pop: return self._populate_mtu_and_subnets_for_ports(context, [snat_port]) return snat_port
def _add_csnat_router_interface_port(self, context, router, network_id, subnet_id, do_pop=True): """Add SNAT interface to the specified router and subnet.""" port_data = { 'tenant_id': '', 'network_id': network_id, 'fixed_ips': [{ 'subnet_id': subnet_id }], 'device_id': router.id, 'device_owner': l3_const.DEVICE_OWNER_ROUTER_SNAT, 'admin_state_up': True, 'name': '' } snat_port = p_utils.create_port(self._core_plugin, context, {'port': port_data}) if not snat_port: msg = _("Unable to create the SNAT Interface Port") raise n_exc.BadRequest(resource='router', msg=msg) with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort( port_id=snat_port['id'], router_id=router.id, port_type=l3_const.DEVICE_OWNER_ROUTER_SNAT) context.session.add(router_port) if do_pop: return self._populate_subnets_for_ports(context, [snat_port]) return snat_port
def _port_action(self, plugin, context, port, action): """Perform port operations taking care of concurrency issues.""" try: if action == 'create_port': return p_utils.create_port(plugin, context, port) elif action == 'update_port': return plugin.update_port(context, port['id'], port) else: msg = _('Unrecognized action') raise n_exc.Invalid(message=msg) except (db_exc.DBError, n_exc.NetworkNotFound, n_exc.SubnetNotFound, n_exc.IpAddressGenerationFailure) as e: with excutils.save_and_reraise_exception(reraise=False) as ctxt: if isinstance(e, n_exc.IpAddressGenerationFailure): # Check if the subnet still exists and if it does not, # this is the reason why the ip address generation failed. # In any other unlikely event re-raise try: subnet_id = port['port']['fixed_ips'][0]['subnet_id'] plugin.get_subnet(context, subnet_id) except n_exc.SubnetNotFound: pass else: ctxt.reraise = True net_id = port['port']['network_id'] LOG.warn( _LW("Action %(action)s for network %(net_id)s " "could not complete successfully: %(reason)s"), { "action": action, "net_id": net_id, 'reason': e })
def create_fip_agent_gw_port_if_not_exists( self, context, network_id, host): """Function to return the FIP Agent GW port. This function will create a FIP Agent GW port if required. If the port already exists, it will return the existing port and will not create a new one. """ l3_agent_db = self._get_agent_by_type_and_host( context, l3_const.AGENT_TYPE_L3, host) if l3_agent_db: LOG.debug("Agent ID exists: %s", l3_agent_db['id']) f_port = self._get_agent_gw_ports_exist_for_network( context, network_id, host, l3_agent_db['id']) if not f_port: LOG.info(_LI('Agent Gateway port does not exist,' ' so create one: %s'), f_port) port_data = {'tenant_id': '', 'network_id': network_id, 'device_id': l3_agent_db['id'], 'device_owner': l3_const.DEVICE_OWNER_AGENT_GW, 'binding:host_id': host, 'admin_state_up': True, 'name': ''} agent_port = p_utils.create_port(self._core_plugin, context, {'port': port_data}) if agent_port: self._populate_subnets_for_ports(context, [agent_port]) return agent_port msg = _("Unable to create the Agent Gateway Port") raise n_exc.BadRequest(resource='router', msg=msg) else: self._populate_subnets_for_ports(context, [f_port]) return f_port
def create_fip_agent_gw_port_if_not_exists( self, context, network_id, host): """Function to return the FIP Agent GW port. This function will create a FIP Agent GW port if required. If the port already exists, it will return the existing port and will not create a new one. """ l3_agent_db = self._get_agent_by_type_and_host( context, l3_const.AGENT_TYPE_L3, host) if l3_agent_db: LOG.debug("Agent ID exists: %s", l3_agent_db['id']) f_port = self._get_agent_gw_ports_exist_for_network( context, network_id, host, l3_agent_db['id']) if not f_port: LOG.info(_LI('Agent Gateway port does not exist,' ' so create one: %s'), f_port) port_data = {'tenant_id': '', 'network_id': network_id, 'device_id': l3_agent_db['id'], 'device_owner': l3_const.DEVICE_OWNER_AGENT_GW, 'binding:host_id': host, 'admin_state_up': True, 'name': ''} agent_port = p_utils.create_port(self._core_plugin, context, {'port': port_data}) if agent_port: self._populate_subnets_for_ports(context, [agent_port]) return agent_port msg = _("Unable to create the Agent Gateway Port") raise n_exc.BadRequest(resource='router', msg=msg) else: self._populate_subnets_for_ports(context, [f_port]) return f_port
def add_ha_port(self, context, router_id, network_id, tenant_id): # NOTE(kevinbenton): we have to block any ongoing transactions because # our exception handling will try to delete the port using the normal # core plugin API. If this function is called inside of a transaction # the exception will mangle the state, cause the delete call to fail, # and end up relying on the DB rollback to remove the port instead of # proper delete_port call. if context.session.is_active: raise RuntimeError(_('add_ha_port cannot be called inside of a ' 'transaction.')) args = {'tenant_id': '', 'network_id': network_id, 'admin_state_up': True, 'device_id': router_id, 'device_owner': constants.DEVICE_OWNER_ROUTER_HA_INTF, 'name': constants.HA_PORT_NAME % tenant_id} port = p_utils.create_port(self._core_plugin, context, {'port': args}) try: return self._create_ha_port_binding(context, port['id'], router_id) except Exception: with excutils.save_and_reraise_exception(): self._core_plugin.delete_port(context, port['id'], l3_port_check=False)
def _add_csnat_router_interface_port( self, context, router, network_id, subnet_id, do_pop=True): """Add SNAT interface to the specified router and subnet.""" port_data = {'tenant_id': '', 'network_id': network_id, 'fixed_ips': [{'subnet_id': subnet_id}], 'device_id': router.id, 'device_owner': const.DEVICE_OWNER_ROUTER_SNAT, 'admin_state_up': True, 'name': ''} snat_port = p_utils.create_port(self._core_plugin, context, {'port': port_data}) if not snat_port: msg = _("Unable to create the SNAT Interface Port") raise n_exc.BadRequest(resource='router', msg=msg) with p_utils.delete_port_on_error( self.l3plugin._core_plugin, context.elevated(), snat_port['id']): l3_obj.RouterPort( context, port_id=snat_port['id'], router_id=router.id, port_type=const.DEVICE_OWNER_ROUTER_SNAT ).create() if do_pop: return self.l3plugin._populate_mtu_and_subnets_for_ports( context, [snat_port]) return snat_port
def add_ha_port(self, context, router_id, network_id, tenant_id): # NOTE(kevinbenton): we have to block any ongoing transactions because # our exception handling will try to delete the port using the normal # core plugin API. If this function is called inside of a transaction # the exception will mangle the state, cause the delete call to fail, # and end up relying on the DB rollback to remove the port instead of # proper delete_port call. if context.session.is_active: raise RuntimeError( _('add_ha_port cannot be called inside of a ' 'transaction.')) args = { 'tenant_id': '', 'network_id': network_id, 'admin_state_up': True, 'device_id': router_id, 'device_owner': constants.DEVICE_OWNER_ROUTER_HA_INTF, 'name': constants.HA_PORT_NAME % tenant_id } port = p_utils.create_port(self._core_plugin, context, {'port': args}) try: return self._create_ha_port_binding(context, port['id'], router_id) except Exception: with excutils.save_and_reraise_exception(): self._core_plugin.delete_port(context, port['id'], l3_port_check=False)
def add_ha_port(self, context, router_id, network_id, tenant_id): args = {'tenant_id': '', 'network_id': network_id, 'admin_state_up': True, 'device_id': router_id, 'device_owner': constants.DEVICE_OWNER_ROUTER_HA_INTF, 'name': constants.HA_PORT_NAME % tenant_id} port = p_utils.create_port(self._core_plugin, context, {'port': args}) try: return self._create_ha_port_binding(context, port['id'], router_id) except Exception: with excutils.save_and_reraise_exception(): self._core_plugin.delete_port(context, port['id'], l3_port_check=False)
def add_ha_port(self, context, router_id, network_id, tenant_id): args = {'tenant_id': '', 'network_id': network_id, 'admin_state_up': True, 'device_id': router_id, 'device_owner': constants.DEVICE_OWNER_ROUTER_HA_INTF, 'name': constants.HA_PORT_NAME % tenant_id} port = p_utils.create_port(self._core_plugin, context, {'port': args}) try: return self._create_ha_port_binding(context, port['id'], router_id) except Exception: with excutils.save_and_reraise_exception(): self._core_plugin.delete_port(context, port['id'], l3_port_check=False)
def add_ha_port(self, context, router_id, network_id, tenant_id): args = { "tenant_id": "", "network_id": network_id, "admin_state_up": True, "device_id": router_id, "device_owner": constants.DEVICE_OWNER_ROUTER_HA_INTF, "name": constants.HA_PORT_NAME % tenant_id, } port = p_utils.create_port(self._core_plugin, context, {"port": args}) try: return self._create_ha_port_binding(context, port["id"], router_id) except Exception: with excutils.save_and_reraise_exception(): self._core_plugin.delete_port(context, port["id"], l3_port_check=False)
def _create_floatingip(self, context, floatingip, initial_status=n_const.FLOATINGIP_STATUS_ACTIVE): fip = floatingip['floatingip'] fip_id = uuidutils.generate_uuid() f_net_id = fip['floating_network_id'] if not self._core_plugin._network_is_external(context, f_net_id): msg = _("Network %s is not a valid external network") % f_net_id raise n_exc.BadRequest(resource='floatingip', msg=msg) self._validate_network_for_floatingip(context, f_net_id) # This external port is never exposed to the tenant. # it is used purely for internal system and admin use when # managing floating IPs. port = {'tenant_id': '', # tenant intentionally not set 'network_id': f_net_id, 'admin_state_up': True, 'device_id': 'PENDING', 'device_owner': DEVICE_OWNER_FLOATINGIP, 'status': n_const.PORT_STATUS_NOTAPPLICABLE, 'name': ''} if fip.get('floating_ip_address'): port['fixed_ips'] = [ {'ip_address': fip['floating_ip_address']}] if fip.get('subnet_id'): port['fixed_ips'] = [ {'subnet_id': fip['subnet_id']}] # 'status' in port dict could not be updated by default, use # check_allow_post to stop the verification of system external_port = p_utils.create_port(self._core_plugin, context.elevated(), {'port': port}, check_allow_post=False) with p_utils.delete_port_on_error(self._core_plugin, context.elevated(), external_port['id']),\ context.session.begin(subtransactions=True): external_ips = self._port_fixed_ips_for_floatingip(external_port) if not external_ips: raise n_exc.ExternalIpAddressExhausted(net_id=f_net_id) floating_fixed_ip = external_ips[0] floating_ip_address = floating_fixed_ip['ip_address'] floatingip_db = l3_db.FloatingIP( id=fip_id, tenant_id=fip['tenant_id'], status=initial_status, floating_network_id=fip['floating_network_id'], floating_ip_address=floating_ip_address, floating_port_id=external_port['id'], description=fip.get('description')) # Update association with internal port # and define external IP address assoc_result = self._update_fip_assoc(context, fip, floatingip_db, external_port) context.session.add(floatingip_db) floatingip_dict = self._make_floatingip_dict( floatingip_db, process_extensions=False) if self._is_dns_integration_supported: dns_data = self._process_dns_floatingip_create_precommit( context, floatingip_dict, fip) self._core_plugin.update_port(context.elevated(), external_port['id'], {'port': {'device_id': fip_id}}) registry.notify(resources.FLOATING_IP, events.AFTER_UPDATE, self._update_fip_assoc, **assoc_result) if self._is_dns_integration_supported: self._process_dns_floatingip_create_postcommit(context, floatingip_dict, dns_data) self._apply_dict_extend_functions(l3.FLOATINGIPS, floatingip_dict, floatingip_db) return floatingip_dict