Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
 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
Ejemplo n.º 5
0
 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()
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
 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
Ejemplo n.º 9
0
 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
     }
Ejemplo n.º 10
0
    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