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()
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
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
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
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