def create_floatingip( self, context, floatingip, initial_status=l3_db.l3_constants.FLOATINGIP_STATUS_ACTIVE): fip = floatingip['floatingip'] tenant_id = self._get_tenant_id_for_create(context, fip) fip_id = l3_db.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 l3_db.n_exc.BadRequest(resource='floatingip', msg=msg) with context.session.begin(subtransactions=True): # 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, 'mac_address': l3_db.attributes.ATTR_NOT_SPECIFIED, 'fixed_ips': l3_db.attributes.ATTR_NOT_SPECIFIED, 'admin_state_up': True, 'device_id': fip_id, 'device_owner': l3_db.DEVICE_OWNER_FLOATINGIP, 'status': l3_db.l3_constants.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']}] external_port = self._core_plugin.create_port(context.elevated(), {'port': port}) # Ensure IP addresses are allocated on external port if not external_port['fixed_ips']: raise l3_db.n_exc.ExternalIpAddressExhausted(net_id=f_net_id) floating_fixed_ip = external_port['fixed_ips'][0] floating_ip_address = floating_fixed_ip['ip_address'] floatingip_db = l3_db.FloatingIP( id=fip_id, tenant_id=tenant_id, status=initial_status, floating_network_id=fip['floating_network_id'], floating_ip_address=floating_ip_address, floating_port_id=external_port['id']) fip['tenant_id'] = tenant_id # Update association with internal port # and define external IP address self._update_fip_assoc(context, fip, floatingip_db, external_port) context.session.add(floatingip_db) return self._make_floatingip_dict(floatingip_db)
def test__check_and_get_fip_assoc_with_extra_association_no_change(self): fip = {'extra_key': 'value'} context = mock.MagicMock() floatingip_db = l3_db.FloatingIP( id='fake_fip_id', floating_network_id='fake_floating_network_id', floating_ip_address='8.8.8.8', fixed_port_id='fake_fixed_port_id', floating_port_id='fake_floating_port_id') with mock.patch.object(l3_db.L3_NAT_dbonly_mixin, '_get_assoc_data', return_value=('1', '2', '3')) as mock_get_assoc_data: self.db._check_and_get_fip_assoc(context, fip, floatingip_db) context.session.query.assert_not_called() mock_get_assoc_data.assert_called_once_with( mock.ANY, fip, floatingip_db)
def setUp(self): super(TestL3GwModeMixin, self).setUp() plugin = __name__ + '.' + TestDbIntPlugin.__name__ self.setup_coreplugin(plugin) self.target_object = TestDbIntPlugin() # Patch the context ctx_patcher = mock.patch('neutron.context', autospec=True) mock_context = ctx_patcher.start() self.addCleanup(db_api.clear_db) self.context = mock_context.get_admin_context() # This ensure also calls to elevated work in unit tests self.context.elevated.return_value = self.context self.context.session = db_api.get_session() # Create sample data for tests self.ext_net_id = _uuid() self.int_net_id = _uuid() self.int_sub_id = _uuid() self.tenant_id = 'the_tenant' self.network = models_v2.Network(id=self.ext_net_id, tenant_id=self.tenant_id, admin_state_up=True, status=constants.NET_STATUS_ACTIVE) self.net_ext = external_net_db.ExternalNetwork( network_id=self.ext_net_id) self.context.session.add(self.network) # The following is to avoid complains from sqlite on # foreign key violations self.context.session.flush() self.context.session.add(self.net_ext) self.router = l3_db.Router(id=_uuid(), name=None, tenant_id=self.tenant_id, admin_state_up=True, status=constants.NET_STATUS_ACTIVE, enable_snat=True, gw_port_id=None) self.context.session.add(self.router) self.context.session.flush() self.router_gw_port = models_v2.Port( id=FAKE_GW_PORT_ID, tenant_id=self.tenant_id, device_id=self.router.id, device_owner=l3_db.DEVICE_OWNER_ROUTER_GW, admin_state_up=True, status=constants.PORT_STATUS_ACTIVE, mac_address=FAKE_GW_PORT_MAC, network_id=self.ext_net_id) self.router.gw_port_id = self.router_gw_port.id self.context.session.add(self.router) self.context.session.add(self.router_gw_port) self.context.session.flush() self.fip_ext_port = models_v2.Port( id=FAKE_FIP_EXT_PORT_ID, tenant_id=self.tenant_id, admin_state_up=True, device_id=self.router.id, device_owner=l3_db.DEVICE_OWNER_FLOATINGIP, status=constants.PORT_STATUS_ACTIVE, mac_address=FAKE_FIP_EXT_PORT_MAC, network_id=self.ext_net_id) self.context.session.add(self.fip_ext_port) self.context.session.flush() self.int_net = models_v2.Network(id=self.int_net_id, tenant_id=self.tenant_id, admin_state_up=True, status=constants.NET_STATUS_ACTIVE) self.int_sub = models_v2.Subnet(id=self.int_sub_id, tenant_id=self.tenant_id, ip_version=4, cidr='3.3.3.0/24', gateway_ip='3.3.3.1', network_id=self.int_net_id) self.router_port = models_v2.Port( id=FAKE_ROUTER_PORT_ID, tenant_id=self.tenant_id, admin_state_up=True, device_id=self.router.id, device_owner=l3_db.DEVICE_OWNER_ROUTER_INTF, status=constants.PORT_STATUS_ACTIVE, mac_address=FAKE_ROUTER_PORT_MAC, network_id=self.int_net_id) self.router_port_ip_info = models_v2.IPAllocation( port_id=self.router_port.id, network_id=self.int_net.id, subnet_id=self.int_sub_id, ip_address='3.3.3.1') self.context.session.add(self.int_net) self.context.session.add(self.int_sub) self.context.session.add(self.router_port) self.context.session.add(self.router_port_ip_info) self.context.session.flush() self.fip_int_port = models_v2.Port(id=FAKE_FIP_INT_PORT_ID, tenant_id=self.tenant_id, admin_state_up=True, device_id='something', device_owner='compute:nova', status=constants.PORT_STATUS_ACTIVE, mac_address=FAKE_FIP_INT_PORT_MAC, network_id=self.int_net_id) self.fip_int_ip_info = models_v2.IPAllocation( port_id=self.fip_int_port.id, network_id=self.int_net.id, subnet_id=self.int_sub_id, ip_address='3.3.3.3') self.fip = l3_db.FloatingIP(id=_uuid(), floating_ip_address='1.1.1.2', floating_network_id=self.ext_net_id, floating_port_id=FAKE_FIP_EXT_PORT_ID, fixed_port_id=None, fixed_ip_address=None, router_id=None) self.context.session.add(self.fip_int_port) self.context.session.add(self.fip_int_ip_info) self.context.session.add(self.fip) self.context.session.flush() self.fip_request = { 'port_id': FAKE_FIP_INT_PORT_ID, 'tenant_id': self.tenant_id }
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