コード例 #1
0
    def _create_port_for_vip(self, context, vip_db, subnet_id, ip_address):
        # resolve subnet and create port
        subnet = self._core_plugin.get_subnet(context, subnet_id)
        fixed_ip = {'subnet_id': subnet['id']}
        if ip_address and ip_address != n_constants.ATTR_NOT_SPECIFIED:
            fixed_ip['ip_address'] = ip_address
            if subnet.get('gateway_ip') == ip_address:
                raise n_exc.IpAddressInUse(net_id=subnet['network_id'],
                                           ip_address=ip_address)

        port_data = {
            'tenant_id': vip_db.tenant_id,
            'name': 'vip-' + vip_db.id,
            'network_id': subnet['network_id'],
            'mac_address': n_constants.ATTR_NOT_SPECIFIED,
            'admin_state_up': False,
            'device_id': '',
            'device_owner': n_constants.DEVICE_OWNER_LOADBALANCER,
            'fixed_ips': [fixed_ip]
        }

        port = self._core_plugin.create_port(context, {'port': port_data})
        vip_db.port_id = port['id']
        # explicitly sync session with db
        context.session.flush()
コード例 #2
0
 def _calculate_ipv6_eui64_addr(self, context, subnet, mac_addr):
     prefix = subnet['cidr']
     network_id = subnet['network_id']
     ip_address = netutils.get_ipv6_addr_by_EUI64(prefix, mac_addr).format()
     if not self._check_unique_ip(context, network_id, subnet['id'],
                                  ip_address):
         raise n_exc.IpAddressInUse(net_id=network_id,
                                    ip_address=ip_address)
     return ip_address
コード例 #3
0
    def _allocate_from_subnet(self,
                              context,
                              net_id,
                              subnet,
                              port_id,
                              reuse_after,
                              ip_address=None,
                              **kwargs):

        LOG.info("Creating a new address in subnet {0} - [{1}]".format(
            subnet["_cidr"],
            utils.pretty_kwargs(network_id=net_id,
                                subnet=subnet,
                                port_id=port_id,
                                ip_address=ip_address)))

        if subnet and subnet["ip_policy"]:
            ip_policy_cidrs = subnet["ip_policy"].get_cidrs_ip_set()
        else:
            ip_policy_cidrs = netaddr.IPSet([])

        next_ip = ip_address
        if not next_ip:
            if subnet["next_auto_assign_ip"] != -1:
                next_ip = netaddr.IPAddress(subnet["next_auto_assign_ip"] - 1)
            else:
                next_ip = netaddr.IPAddress(subnet["last_ip"])
            if subnet["ip_version"] == 4:
                next_ip = next_ip.ipv4()

        LOG.info("Next IP is {0}".format(str(next_ip)))
        if ip_policy_cidrs and next_ip in ip_policy_cidrs and not ip_address:
            LOG.info("Next IP {0} violates policy".format(str(next_ip)))
            raise q_exc.IPAddressPolicyRetryableFailure(ip_addr=next_ip,
                                                        net_id=net_id)
        try:
            with context.session.begin():
                address = db_api.ip_address_create(
                    context,
                    address=next_ip,
                    subnet_id=subnet["id"],
                    deallocated=0,
                    version=subnet["ip_version"],
                    network_id=net_id,
                    port_id=port_id,
                    address_type=kwargs.get('address_type', ip_types.FIXED))
                address["deallocated"] = 0
                # alexm: instead of notifying billing from here we notify from
                # allocate_ip_address() when it's clear that the IP
                # allocation was successful
        except db_exception.DBDuplicateEntry:
            raise n_exc.IpAddressInUse(ip_address=next_ip, net_id=net_id)
        except db_exception.DBError:
            raise q_exc.IPAddressRetryableFailure(ip_addr=next_ip,
                                                  net_id=net_id)

        return address
コード例 #4
0
    def _allocate_from_subnet(self,
                              context,
                              net_id,
                              subnet,
                              port_id,
                              reuse_after,
                              ip_address=None,
                              **kwargs):

        LOG.info("Creating a new address in subnet {0} - [{1}]".format(
            subnet["_cidr"],
            utils.pretty_kwargs(network_id=net_id,
                                subnet=subnet,
                                port_id=port_id,
                                ip_address=ip_address)))

        ip_policy_cidrs = models.IPPolicy.get_ip_policy_cidrs(subnet)
        next_ip = ip_address
        if not next_ip:
            if subnet["next_auto_assign_ip"] != -1:
                next_ip = netaddr.IPAddress(subnet["next_auto_assign_ip"] - 1)
            else:
                next_ip = netaddr.IPAddress(subnet["last_ip"])
            if subnet["ip_version"] == 4:
                next_ip = next_ip.ipv4()

        LOG.info("Next IP is {0}".format(str(next_ip)))
        if ip_policy_cidrs and next_ip in ip_policy_cidrs and not ip_address:
            LOG.info("Next IP {0} violates policy".format(str(next_ip)))
            raise q_exc.IPAddressPolicyRetryableFailure(ip_addr=next_ip,
                                                        net_id=net_id)
        try:
            with context.session.begin():
                address = db_api.ip_address_create(
                    context,
                    address=next_ip,
                    subnet_id=subnet["id"],
                    deallocated=0,
                    version=subnet["ip_version"],
                    network_id=net_id,
                    port_id=port_id,
                    address_type=kwargs.get('address_type', ip_types.FIXED))
                address["deallocated"] = 0
        except Exception:
            # NOTE(mdietz): Our version of sqlalchemy incorrectly raises None
            #               here when there's an IP conflict
            if ip_address:
                raise n_exc.IpAddressInUse(ip_address=next_ip, net_id=net_id)
            raise q_exc.IPAddressRetryableFailure(ip_addr=next_ip,
                                                  net_id=net_id)

        return address
コード例 #5
0
    def _test_fixed_ips_for_port(self, context, network_id, fixed_ips,
                                 device_owner, subnets):
        """Test fixed IPs for port.

        Check that configured subnets are valid prior to allocating any
        IPs. Include the subnet_id in the result if only an IP address is
        configured.

        :raises: InvalidInput, IpAddressInUse, InvalidIpForNetwork,
                 InvalidIpForSubnet
        """
        fixed_ip_set = []
        for fixed in fixed_ips:
            subnet = self._get_subnet_for_fixed_ip(context, fixed, subnets)

            is_auto_addr_subnet = ipv6_utils.is_auto_address_subnet(subnet)
            if ('ip_address' in fixed
                    and subnet['cidr'] != n_const.PROVISIONAL_IPV6_PD_PREFIX):
                # Ensure that the IP's are unique
                if not IpamNonPluggableBackend._check_unique_ip(
                        context, network_id, subnet['id'],
                        fixed['ip_address']):
                    raise n_exc.IpAddressInUse(net_id=network_id,
                                               ip_address=fixed['ip_address'])

                if (is_auto_addr_subnet and device_owner
                        not in constants.ROUTER_INTERFACE_OWNERS):
                    msg = (_("IPv6 address %(address)s can not be directly "
                             "assigned to a port on subnet %(id)s since the "
                             "subnet is configured for automatic addresses") %
                           {
                               'address': fixed['ip_address'],
                               'id': subnet['id']
                           })
                    raise n_exc.InvalidInput(error_message=msg)
                fixed_ip_set.append({
                    'subnet_id': subnet['id'],
                    'ip_address': fixed['ip_address']
                })
            else:
                # A scan for auto-address subnets on the network is done
                # separately so that all such subnets (not just those
                # listed explicitly here by subnet ID) are associated
                # with the port.
                if (device_owner in constants.ROUTER_INTERFACE_OWNERS_SNAT
                        or not is_auto_addr_subnet):
                    fixed_ip_set.append({'subnet_id': subnet['id']})

        self._validate_max_ips_per_port(fixed_ip_set, device_owner)
        return fixed_ip_set