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 test_delete_port_on_error_no_delete(self): core_plugin, context = mock.Mock(), mock.Mock() with testtools.ExpectedException(ValueError): with utils.delete_port_on_error(core_plugin, context, 1) as cm: cm.delete_on_error = False raise ValueError() self.assertFalse(core_plugin.delete_port.called)
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 test_delete_port_on_error(self): core_plugin, context = mock.Mock(), mock.Mock() port_id = "pid" with testtools.ExpectedException(ValueError): with utils.delete_port_on_error(core_plugin, context, port_id): raise ValueError() core_plugin.delete_port.assert_called_once_with(context, port_id, l3_port_check=False)
def test_delete_port_on_error(self): core_plugin, context = mock.Mock(), mock.Mock() port_id = 'pid' with testtools.ExpectedException(ValueError): with utils.delete_port_on_error(core_plugin, context, port_id): raise ValueError() core_plugin.delete_port.assert_called_once_with(context, port_id, l3_port_check=False)
def test_delete_port_on_error_port_does_not_exist(self): core_plugin, context = mock.Mock(), mock.Mock() port_id = 'pid' core_plugin.delete_port.side_effect = exceptions.PortNotFound( port_id=port_id) with testtools.ExpectedException(exceptions.PortNotFound): with utils.delete_port_on_error(core_plugin, context, port_id): raise exceptions.PortNotFound(port_id=port_id) core_plugin.delete_port.assert_called_once_with(context, port_id, l3_port_check=False)
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) device_owner = self._get_device_owner(context, router) # This should be True unless adding an IPv6 prefix to an existing port new_port = True cleanup_port = False if add_by_port: port, subnets = self._add_interface_by_port( context, router, interface_info['port_id'], device_owner) elif add_by_sub: port, subnets, new_port = self._add_interface_by_subnet( context, router, interface_info['subnet_id'], device_owner) cleanup_port = new_port subnet = subnets[0] if new_port: with p_utils.delete_port_on_error(self._core_plugin, context, port['id']) as delmgr: if router.extra_attributes.distributed and router.gw_port: admin_context = context.elevated() self._add_csnat_router_interface_port( admin_context, router, port['network_id'], port['fixed_ips'][-1]['subnet_id']) delmgr.delete_on_error = cleanup_port with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort(port_id=port['id'], router_id=router.id, port_type=device_owner) context.session.add(router_port) # NOTE: For IPv6 additional subnets added to the same # network we need to update the CSNAT port with respective # IPv6 subnet elif subnet and port: fixed_ip = {'subnet_id': subnet['id']} if subnet['ip_version'] == 6: # Add new prefix to an existing ipv6 csnat port with the # same network id if one exists cs_port = ( self._find_v6_router_port_by_network_and_device_owner( router, subnet['network_id'], const.DEVICE_OWNER_ROUTER_SNAT)) if cs_port: fixed_ips = list(cs_port['port']['fixed_ips']) fixed_ips.append(fixed_ip) updated_port = self._core_plugin.update_port( context.elevated(), cs_port['port_id'], {'port': { 'fixed_ips': fixed_ips }}) LOG.debug("CSNAT port updated for IPv6 subnet: " "%s", updated_port) router_interface_info = self._make_router_interface_info( router_id, port['tenant_id'], port['id'], port['network_id'], subnet['id'], [subnet['id']]) self.notify_router_interface_action(context, router_interface_info, 'add') if router.gw_port: gw_network_id = router.gw_port.network_id gw_ips = [x['ip_address'] for x in router.gw_port.fixed_ips] registry.notify(resources.ROUTER_INTERFACE, events.AFTER_CREATE, self, context=context, network_id=gw_network_id, gateway_ips=gw_ips, cidrs=[x['cidr'] for x in subnets], port_id=port['id'], router_id=router_id, port=port, interface_info=interface_info) return router_interface_info
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) device_owner = self._get_device_owner(context, router) # This should be True unless adding an IPv6 prefix to an existing port new_port = True cleanup_port = False if add_by_port: port, subnets = self._add_interface_by_port( context, router, interface_info['port_id'], device_owner) elif add_by_sub: port, subnets, new_port = self._add_interface_by_subnet( context, router, interface_info['subnet_id'], device_owner) cleanup_port = new_port subnet = subnets[0] if new_port: with p_utils.delete_port_on_error(self._core_plugin, context, port['id']) as delmgr: if router.extra_attributes.distributed and router.gw_port: admin_context = context.elevated() self._add_csnat_router_interface_port( admin_context, router, port['network_id'], port['fixed_ips'][-1]['subnet_id']) delmgr.delete_on_error = cleanup_port with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort( port_id=port['id'], router_id=router.id, port_type=device_owner ) context.session.add(router_port) # NOTE: For IPv6 additional subnets added to the same # network we need to update the CSNAT port with respective # IPv6 subnet elif subnet and port: fixed_ip = {'subnet_id': subnet['id']} if subnet['ip_version'] == 6: # Add new prefix to an existing ipv6 csnat port with the # same network id if one exists cs_port = ( self._find_v6_router_port_by_network_and_device_owner( router, subnet['network_id'], const.DEVICE_OWNER_ROUTER_SNAT)) if cs_port: fixed_ips = list(cs_port['port']['fixed_ips']) fixed_ips.append(fixed_ip) updated_port = self._core_plugin.update_port( context.elevated(), cs_port['port_id'], {'port': {'fixed_ips': fixed_ips}}) LOG.debug("CSNAT port updated for IPv6 subnet: " "%s", updated_port) router_interface_info = self._make_router_interface_info( router_id, port['tenant_id'], port['id'], port['network_id'], subnet['id'], [subnet['id']]) self.notify_router_interface_action( context, router_interface_info, 'add') if router.gw_port: gw_network_id = router.gw_port.network_id gw_ips = [x['ip_address'] for x in router.gw_port.fixed_ips] registry.notify(resources.ROUTER_INTERFACE, events.AFTER_CREATE, self, context=context, network_id=gw_network_id, gateway_ips=gw_ips, cidrs=[x['cidr'] for x in subnets], port_id=port['id'], router_id=router_id, port=port, interface_info=interface_info) return router_interface_info
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