示例#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 != attributes.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': attributes.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 = ipv6_utils.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)))

        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 exceptions.IpAddressInUse(ip_address=next_ip,
                                                net_id=net_id)
            raise q_exc.IPAddressRetryableFailure(ip_addr=next_ip,
                                                  net_id=net_id)

        return address
示例#4
0
    def _test_fixed_ips_for_port(self, context, network_id, fixed_ips,
                                 device_owner):
        """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, network_id)

            is_auto_addr_subnet = ipv6_utils.is_auto_address_subnet(subnet)
            if ('ip_address' in fixed and
                    subnet['cidr'] != constants.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 ipv6_utils.is_ipv6_pd_enabled(subnet)
                        or not is_auto_addr_subnet):
                    fixed_ip_set.append({'subnet_id': subnet['id']})

        self._validate_max_ips_per_port(fixed_ip_set)
        return fixed_ip_set
示例#5
0
文件: ipam.py 项目: thomasem/quark
    def _allocate_from_subnet(self,
                              context,
                              net_id,
                              subnet,
                              port_id,
                              reuse_after,
                              ip_address=None,
                              **kwargs):
        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()

        if (ip_policy_cidrs is not None and next_ip in ip_policy_cidrs):
            if not ip_address:
                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)
                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 exceptions.IpAddressInUse(ip_address=next_ip,
                                                net_id=net_id)
            raise q_exc.IPAddressRetryableFailure(ip_addr=next_ip,
                                                  net_id=net_id)

        return address
示例#6
0
    def _test_fixed_ips_for_port(self, context, network_id, fixed_ips,
                                 device_owner):
        """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:
            found = False
            if 'subnet_id' not in fixed:
                if 'ip_address' not in fixed:
                    msg = _('IP allocation requires subnet_id or ip_address')
                    raise n_exc.InvalidInput(error_message=msg)

                filter = {'network_id': [network_id]}
                subnets = self._get_subnets(context, filters=filter)
                for subnet in subnets:
                    if ipam_utils.check_subnet_ip(subnet['cidr'],
                                                  fixed['ip_address']):
                        found = True
                        subnet_id = subnet['id']
                        break
                if not found:
                    raise n_exc.InvalidIpForNetwork(
                        ip_address=fixed['ip_address'])
            else:
                subnet = self._get_subnet(context, fixed['subnet_id'])
                if subnet['network_id'] != network_id:
                    msg = (_("Failed to create port on network %(network_id)s"
                             ", because fixed_ips included invalid subnet "
                             "%(subnet_id)s") %
                           {'network_id': network_id,
                            'subnet_id': fixed['subnet_id']})
                    raise n_exc.InvalidInput(error_message=msg)
                subnet_id = subnet['id']

            is_auto_addr_subnet = ipv6_utils.is_auto_address_subnet(subnet)
            if 'ip_address' in fixed:
                # 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'])

                # Ensure that the IP is valid on the subnet
                if (not found and
                    not ipam_utils.check_subnet_ip(subnet['cidr'],
                                                   fixed['ip_address'])):
                    raise n_exc.InvalidIpForSubnet(
                        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 or
                    device_owner == constants.DEVICE_OWNER_ROUTER_SNAT or
                    not is_auto_addr_subnet):
                    fixed_ip_set.append({'subnet_id': subnet_id})

        if len(fixed_ip_set) > cfg.CONF.max_fixed_ips_per_port:
            msg = _('Exceeded maximim amount of fixed ips per port')
            raise n_exc.InvalidInput(error_message=msg)
        return fixed_ip_set