def _store_ip_allocation(context, ip_address, network_id, subnet_id, port_id): LOG.debug( "Allocated IP %(ip_address)s " "(%(network_id)s/%(subnet_id)s/%(port_id)s)", { 'ip_address': ip_address, 'network_id': network_id, 'subnet_id': subnet_id, 'port_id': port_id }) allocated = port_obj.IPAllocation(context, network_id=network_id, port_id=port_id, ip_address=ip_address, subnet_id=subnet_id) # NOTE(lujinluo): Add IPAllocations obj to the port fixed_ips # in Port OVO integration, i.e. the same way we did in # Ib32509d974c8654131112234bcf19d6eae8f7cca allocated.create() # NOTE(kevinbenton): We add this to the session info so the sqlalchemy # object isn't immediately garbage collected. Otherwise when the # fixed_ips relationship is referenced a new persistent object will be # added to the session that will interfere with retry operations. # See bug 1556178 for details. context.session.info.setdefault('allocated_ips', []).append(allocated)
def test_get_ports_allocated_by_subnet_id(self): network_id = self._create_test_network_id() segment_id = self._create_test_segment_id(network_id) subnet_id = self._create_test_subnet_id(network_id) self.update_obj_fields( {'network_id': network_id, 'fixed_ips': {'subnet_id': subnet_id, 'network_id': network_id}, 'device_owner': 'not_a_router', 'binding_levels': {'segment_id': segment_id}}, db_objs=[self.db_objs[0]]) objs = [] for idx in range(3): objs.append(self._make_object(self.obj_fields[idx])) objs[idx].create() ipa = ports.IPAllocation(self.context, port_id=objs[0].id, subnet_id=subnet_id, network_id=network_id, ip_address=netaddr.IPAddress('10.0.0.1')) ipa.create() ports_alloc = ports.Port.get_ports_allocated_by_subnet_id(self.context, subnet_id) self.assertEqual(1, len(ports_alloc)) self.assertEqual(objs[0].id, ports_alloc[0].id)
def add_auto_addrs_on_network_ports(self, context, subnet, ipam_subnet): """For an auto-address subnet, add addrs for ports on the net.""" # TODO(ataraday): switched for writer when flush_on_subtransaction # will be available for neutron with context.session.begin(subtransactions=True): network_id = subnet['network_id'] port_qry = context.session.query(models_v2.Port) ports = port_qry.filter( and_( models_v2.Port.network_id == network_id, models_v2.Port.device_owner != constants.DEVICE_OWNER_DHCP, ~models_v2.Port.device_owner.in_( constants.ROUTER_INTERFACE_OWNERS_SNAT))) updated_ports = [] ipam_driver = driver.Pool.get_instance(None, context) factory = ipam_driver.get_address_request_factory() for port in ports: ip = { 'subnet_id': subnet['id'], 'subnet_cidr': subnet['cidr'], 'eui64_address': True, 'mac': port['mac_address'] } ip_request = factory.get_request(context, port, ip) try: ip_address = ipam_subnet.allocate(ip_request) allocated = port_obj.IPAllocation(context, network_id=network_id, port_id=port['id'], ip_address=ip_address, subnet_id=subnet['id']) # Do the insertion of each IP allocation entry within # the context of a nested transaction, so that the entry # is rolled back independently of other entries whenever # the corresponding port has been deleted; since OVO # already opens a nested transaction, we don't need to do # it explicitly here. allocated.create() updated_ports.append(port['id']) except db_exc.DBReferenceError: LOG.debug( "Port %s was deleted while updating it with an " "IPv6 auto-address. Ignoring.", port['id']) LOG.debug("Reverting IP allocation for %s", ip_address) # Do not fail if reverting allocation was unsuccessful try: ipam_subnet.deallocate(ip_address) except Exception: LOG.debug("Reverting IP allocation failed for %s", ip_address) except ipam_exc.IpAddressAlreadyAllocated: LOG.debug( "Port %s got IPv6 auto-address in a concurrent " "create or update port request. Ignoring.", port['id']) return updated_ports
def _make_port_ovo(self, ip, **kwargs): attrs = {'id': uuidutils.generate_uuid(), 'network_id': uuidutils.generate_uuid(), 'security_group_ids': set(), 'device_owner': 'compute:None', 'allowed_address_pairs': []} attrs['fixed_ips'] = [ports.IPAllocation( port_id=attrs['id'], subnet_id=uuidutils.generate_uuid(), network_id=attrs['network_id'], ip_address=ip)] attrs.update(**kwargs) p = ports.Port(self.ctx, **attrs) self.rcache.record_resource_update(self.ctx, 'Port', p) return p
def _store_ip_allocation(context, ip_address, network_id, subnet_id, port_id): LOG.debug("Allocated IP %(ip_address)s " "(%(network_id)s/%(subnet_id)s/%(port_id)s)", {'ip_address': ip_address, 'network_id': network_id, 'subnet_id': subnet_id, 'port_id': port_id}) allocated = port_obj.IPAllocation( context, network_id=network_id, port_id=port_id, ip_address=ip_address, subnet_id=subnet_id) # NOTE(lujinluo): Add IPAllocations obj to the port fixed_ips # in Port OVO integration, i.e. the same way we did in # Ib32509d974c8654131112234bcf19d6eae8f7cca allocated.create()
def _store_ip_allocation(context, ip_address, network_id, subnet_id, port_id): from neutron.objects import ports as port_obj from oslo_log import log as logging LOG = logging.getLogger(__name__) LOG.debug( "Allocated IP %(ip_address)s " "(%(network_id)s/%(subnet_id)s/%(port_id)s)", { 'ip_address': ip_address, 'network_id': network_id, 'subnet_id': subnet_id, 'port_id': port_id }) allocated = port_obj.IPAllocation(context, network_id=network_id, port_id=port_id, ip_address=ip_address, subnet_id=subnet_id) allocated.create()
def _create_port(context, device_id, ip_address): network_id = 'd339eb89-3b7c-4a29-8c02-83ed329ea6d5' subnet_id = '1f9206e1-0872-4bc1-a600-3efed860ee64' fixed_ips = { 'subnet_id': subnet_id, 'network_id': network_id, 'ip_address': ip_address} ip_allocation = ports.IPAllocation(context, **fixed_ips) port_attrs = { 'network_id': network_id, 'fixed_ips': [ip_allocation] } attrs = {'project_id': 'fake', 'admin_state_up': True, 'status': 'ACTIVE', 'device_id': device_id, 'device_owner': 'compute:nova', 'mac_address': tools.get_random_EUI()} attrs.update(**port_attrs) port = ports.Port(context, **attrs) return port
def add_auto_addrs_on_network_ports(self, context, subnet, ipam_subnet): """For an auto-address subnet, add addrs for ports on the net.""" # TODO(kevinbenton): remove after bug/1666493 is resolved if subnet['id'] != ipam_subnet.subnet_manager.neutron_id: raise RuntimeError( "Subnet manager doesn't match subnet. %s != %s" % (subnet['id'], ipam_subnet.subnet_manager.neutron_id)) # TODO(ataraday): switched for writer when flush_on_subtransaction # will be available for neutron with context.session.begin(subtransactions=True): network_id = subnet['network_id'] port_qry = context.session.query(models_v2.Port) ports = port_qry.filter( and_( models_v2.Port.network_id == network_id, ~models_v2.Port.device_owner.in_( constants.ROUTER_INTERFACE_OWNERS_SNAT))) updated_ports = [] ipam_driver = driver.Pool.get_instance(None, context) factory = ipam_driver.get_address_request_factory() for port in ports: ip = { 'subnet_id': subnet['id'], 'subnet_cidr': subnet['cidr'], 'eui64_address': True, 'mac': port['mac_address'] } ip_request = factory.get_request(context, port, ip) # TODO(kevinbenton): remove after bug/1666493 is resolved LOG.debug( "Requesting with IP request: %s port: %s ip: %s " "for subnet %s and ipam_subnet %s", ip_request, port, ip, subnet, ipam_subnet) try: ip_address = ipam_subnet.allocate(ip_request) allocated = port_obj.IPAllocation(context, network_id=network_id, port_id=port['id'], ip_address=ip_address, subnet_id=subnet['id']) # Do the insertion of each IP allocation entry within # the context of a nested transaction, so that the entry # is rolled back independently of other entries whenever # the corresponding port has been deleted. with db_api.context_manager.writer.using(context): allocated.create() updated_ports.append(port['id']) except db_exc.DBReferenceError: LOG.debug( "Port %s was deleted while updating it with an " "IPv6 auto-address. Ignoring.", port['id']) LOG.debug("Reverting IP allocation for %s", ip_address) # Do not fail if reverting allocation was unsuccessful try: ipam_subnet.deallocate(ip_address) except Exception: LOG.debug("Reverting IP allocation failed for %s", ip_address) except ipam_exc.IpAddressAlreadyAllocated: LOG.debug( "Port %s got IPv6 auto-address in a concurrent " "create or update port request. Ignoring.", port['id']) return updated_ports
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_lib.context', autospec=True) mock_context = ctx_patcher.start() 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_writer_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 = net_obj.Network(self.context, id=self.ext_net_id, project_id=self.tenant_id, admin_state_up=True, status=constants.NET_STATUS_ACTIVE) self.net_ext = net_obj.ExternalNetwork(self.context, network_id=self.ext_net_id) self.network.create() self.net_ext.create() self.router = l3_models.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 = port_obj.Port( self.context, id=FAKE_GW_PORT_ID, project_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=netaddr.EUI(FAKE_GW_PORT_MAC), network_id=self.ext_net_id) self.router_gw_port.create() self.router.gw_port_id = self.router_gw_port.id self.context.session.add(self.router) self.context.session.flush() self.fip_ext_port = port_obj.Port( self.context, id=FAKE_FIP_EXT_PORT_ID, project_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=netaddr.EUI(FAKE_FIP_EXT_PORT_MAC), network_id=self.ext_net_id) self.fip_ext_port.create() self.context.session.flush() self.int_net = net_obj.Network(self.context, id=self.int_net_id, project_id=self.tenant_id, admin_state_up=True, status=constants.NET_STATUS_ACTIVE) self.int_sub = subnet_obj.Subnet( self.context, id=self.int_sub_id, project_id=self.tenant_id, ip_version=4, cidr=utils.AuthenticIPNetwork('3.3.3.0/24'), gateway_ip=netaddr.IPAddress('3.3.3.1'), network_id=self.int_net_id) self.router_port = port_obj.Port( self.context, id=FAKE_ROUTER_PORT_ID, project_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=netaddr.EUI(FAKE_ROUTER_PORT_MAC), network_id=self.int_net_id) self.router_port_ip_info = port_obj.IPAllocation( self.context, 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.int_net.create() self.int_sub.create() self.router_port.create() self.router_port_ip_info.create() self.context.session.flush() self.fip_int_port = port_obj.Port( self.context, id=FAKE_FIP_INT_PORT_ID, project_id=self.tenant_id, admin_state_up=True, device_id='something', device_owner=constants.DEVICE_OWNER_COMPUTE_PREFIX + 'nova', status=constants.PORT_STATUS_ACTIVE, mac_address=netaddr.EUI(FAKE_FIP_INT_PORT_MAC), network_id=self.int_net_id) self.fip_int_ip_info = port_obj.IPAllocation( self.context, 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_models.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.fip_int_port.create() self.fip_int_ip_info.create() self.context.session.add(self.fip) self.context.session.flush() self.context.session.expire_all() self.fip_request = { 'port_id': FAKE_FIP_INT_PORT_ID, 'tenant_id': self.tenant_id }
def add_auto_addrs_on_network_ports(self, context, subnet, ipam_subnet): """For an auto-address subnet, add addrs for ports on the net.""" # TODO(ataraday): switched for writer when flush_on_subtransaction # will be available for neutron with context.session.begin(subtransactions=True): network_id = subnet['network_id'] ports = port_obj.Port.get_objects( context, network_id=network_id, device_owner=obj_utils.NotIn( constants.ROUTER_INTERFACE_OWNERS_SNAT)) updated_ports = [] ipam_driver = driver.Pool.get_instance(None, context) factory = ipam_driver.get_address_request_factory() for port in ports: # Find candidate subnets based on host_id and existing # fixed_ips. This will filter subnets on other segments. Only # allocate if this subnet is a valid candidate. p = self._make_port_dict(port) fixed_configured = (p['fixed_ips'] is not constants.ATTR_NOT_SPECIFIED) subnet_candidates = obj_subnet.Subnet.find_candidate_subnets( context, network_id, p.get(portbindings.HOST_ID), p.get('device_owner'), fixed_configured, p.get('fixed_ips')) if subnet['id'] not in [s['id'] for s in subnet_candidates]: continue ip = { 'subnet_id': subnet['id'], 'subnet_cidr': subnet['cidr'], 'eui64_address': True, 'mac': port.mac_address } ip_request = factory.get_request(context, port, ip) try: ip_address = ipam_subnet.allocate(ip_request) allocated = port_obj.IPAllocation(context, network_id=network_id, port_id=port.id, ip_address=ip_address, subnet_id=subnet['id']) # Do the insertion of each IP allocation entry within # the context of a nested transaction, so that the entry # is rolled back independently of other entries whenever # the corresponding port has been deleted; since OVO # already opens a nested transaction, we don't need to do # it explicitly here. allocated.create() updated_ports.append(port.id) except db_exc.DBReferenceError: LOG.debug( "Port %s was deleted while updating it with an " "IPv6 auto-address. Ignoring.", port.id) LOG.debug("Reverting IP allocation for %s", ip_address) # Do not fail if reverting allocation was unsuccessful try: ipam_subnet.deallocate(ip_address) except Exception: LOG.debug("Reverting IP allocation failed for %s", ip_address) except ipam_exc.IpAddressAlreadyAllocated: LOG.debug( "Port %s got IPv6 auto-address in a concurrent " "create or update port request. Ignoring.", port.id) return updated_ports