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 = mock.Mock() with mock.patch.object(excutils, 'save_and_reraise_exception'): with mock.patch.object(utils, 'LOG'): with utils.delete_port_on_error(core_plugin, 'ctx', '1'): raise Exception() core_plugin.delete_port.assert_called_once_with( 'ctx', '1', 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 create_local_ip(self, context, local_ip): """Create a Local IP.""" fields = local_ip['local_ip'] local_port_id = fields.get('local_port_id') local_ip_address = fields.get('local_ip_address') network_id = fields.get('network_id') new_local_port = False if validators.is_attr_set(local_port_id): local_port = port_obj.Port.get_object(context, id=local_port_id) if not local_port: msg = _("Port %s not found") % local_port_id raise lib_exc.BadRequest(resource='local_ip', msg=msg) local_ip_address = self._get_local_ip_address( local_port, local_ip_address) elif validators.is_attr_set(network_id): local_port = self._create_local_port(context, network_id, local_ip_address) local_port_id = local_port['id'] local_ip_address = local_port['fixed_ips'][0]['ip_address'] new_local_port = True else: raise lip_exc.LocalIPPortOrNetworkRequired() if new_local_port: ctx_mgr = plugin_utils.delete_port_on_error( self._core_plugin, context.elevated(), local_port_id) else: ctx_mgr = contextlib.suppress() with ctx_mgr, db_api.CONTEXT_WRITER.using(context): args = { 'id': uuidutils.generate_uuid(), 'name': fields['name'], 'description': fields['description'], 'project_id': fields['project_id'], 'local_port_id': local_port_id, 'network_id': local_port['network_id'], 'local_ip_address': local_ip_address, 'ip_mode': fields['ip_mode'] } lip = lip_obj.LocalIP(context, **args) lip.create() if new_local_port: self._core_plugin.update_port( context.elevated(), local_port_id, {'port': { 'device_id': lip.id, 'project_id': lip.project_id }}) return self._make_local_ip_dict(lip)
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': '' } # Both subnet_id and floating_ip_address are accepted, if # floating_ip_address is not in the subnet, # InvalidIpForSubnet exception will be raised. fixed_ip = {} if fip['subnet_id']: fixed_ip['subnet_id'] = fip['subnet_id'] if fip['floating_ip_address']: fixed_ip['ip_address'] = fip['floating_ip_address'] if fixed_ip: port['fixed_ips'] = [fixed_ip] # 'status' in port dict could not be updated by default, use # check_allow_post to stop the verification of system # TODO(boden): rehome create_port into neutron-lib external_port = plugin_utils.create_port(self._core_plugin, context.elevated(), {'port': port}, check_allow_post=False) with plugin_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_obj = obj_reg.new_instance( 'FloatingIP', context, id=fip_id, project_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_obj) floatingip_obj.create() floatingip_dict = self._make_floatingip_dict( floatingip_obj, process_extensions=False) if self._is_dns_integration_supported: dns_data = self._process_dns_floatingip_create_precommit( context, floatingip_dict, fip) # NOTE(yamamoto): MidoNet doesn't have Floating IP QoS # if self._is_fip_qos_supported: # self._process_extra_fip_qos_create(context, fip_id, fip) floatingip_obj = obj_reg.load_class('FloatingIP').get_object( context, id=floatingip_obj.id) floatingip_db = floatingip_obj.db_obj registry.notify(resources.FLOATING_IP, events.PRECOMMIT_CREATE, self, context=context, floatingip=fip, floatingip_id=fip_id, floatingip_db=floatingip_db) 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) # TODO(lujinluo): Change floatingip_db to floatingip_obj once all # codes are migrated to use Floating IP OVO object. resource_extend.apply_funcs(l3_apidef.FLOATINGIPS, floatingip_dict, floatingip_db) return floatingip_dict