def select_subnet(self, context, net_id, ip_address, segment_id, subnet_ids=None, **filters): subnets = db_api.subnet_find_allocation_counts( context, net_id, segment_id=segment_id, scope=db_api.ALL, subnet_id=subnet_ids, **filters) for subnet, ips_in_subnet in subnets: ipnet = netaddr.IPNetwork(subnet["cidr"]) if ip_address and ip_address not in ipnet: if subnet_ids is not None: raise q_exc.IPAddressNotInSubnet( ip_addr=ip_address, subnet_id=subnet["id"]) continue ip_policy = None if not ip_address: # Policies don't prevent explicit assignment, so we only # need to check if we're allocating a new IP ip_policy = subnet.get("ip_policy") policy_size = ip_policy["size"] if ip_policy else 0 if ipnet.size > (ips_in_subnet + policy_size - 1): if not ip_address: ip = subnet["next_auto_assign_ip"] # If ip is somehow -1 in here don't touch it anymore if ip != -1: ip += 1 # and even then if it is outside the valid range set it to # -1 to be safe if ip < subnet["first_ip"] or ip > subnet["last_ip"]: ip = -1 db_api.subnet_update(context, subnet, next_auto_assign_ip=ip) return subnet
def _choose_available_subnet(self, context, net_id, version=None, ip_address=None): filters = {} if version: filters["version"] = version subnets = db_api.subnet_find_allocation_counts(context, net_id, scope=db_api.ALL, **filters) for subnet, ips_in_subnet in subnets: ipnet = netaddr.IPNetwork(subnet["cidr"]) if ip_address and ip_address not in ipnet: continue ip_policy_rules = None if not ip_address: ip_policy_rules = self.get_ip_policy_rule_set(subnet) policy_size = ip_policy_rules.size if ip_policy_rules else 0 if ipnet.size > (ips_in_subnet + policy_size): return subnet raise exceptions.IpAddressGenerationFailure(net_id=net_id)
def test_get_subnet_do_not_use_not_returned(self): network = dict(name="public", tenant_id="fake", network_plugin="BASE") subnet = dict(id=1, ip_version=4, next_auto_assign_ip=2, cidr="0.0.0.0/24", first_ip=0, last_ip=255, ip_policy=None, tenant_id="fake") with self._stubs(network, subnet) as (net, sub1, sub2): subnets = db_api.subnet_find_allocation_counts(self.context, net["id"]).all() self.assertEqual(len(subnets), 1) self.assertEqual(subnets[0][0]["id"], "1")
def select_subnet(self, context, net_id, ip_address, **filters): subnets = db_api.subnet_find_allocation_counts(context, net_id, scope=db_api.ALL, **filters) for subnet, ips_in_subnet in subnets: ipnet = netaddr.IPNetwork(subnet["cidr"]) if ip_address and ip_address not in ipnet: continue ip_policy_rules = None if not ip_address: ip_policy_rules = models.IPPolicy.get_ip_policy_rule_set( subnet) policy_size = ip_policy_rules.size if ip_policy_rules else 0 if ipnet.size > (ips_in_subnet + policy_size): return subnet
def select_subnet(self, context, net_id, ip_address, segment_id, subnet_ids=None, **filters): subnets = db_api.subnet_find_allocation_counts(context, net_id, segment_id=segment_id, scope=db_api.ALL, subnet_id=subnet_ids, **filters) for subnet, ips_in_subnet in subnets: ipnet = netaddr.IPNetwork(subnet["cidr"]) if ip_address: na_ip = netaddr.IPAddress(ip_address) if ipnet.version == 4 and na_ip.version != 4: na_ip = na_ip.ipv4() if na_ip not in ipnet: if subnet_ids is not None: raise q_exc.IPAddressNotInSubnet( ip_addr=ip_address, subnet_id=subnet["id"]) continue ip_policy = None if not ip_address: # Policies don't prevent explicit assignment, so we only # need to check if we're allocating a new IP ip_policy = subnet.get("ip_policy") policy_size = ip_policy["size"] if ip_policy else 0 if ipnet.size > (ips_in_subnet + policy_size - 1): if not ip_address: ip = subnet["next_auto_assign_ip"] # If ip is somehow -1 in here don't touch it anymore if ip != -1: ip += 1 # and even then if it is outside the valid range set it to # -1 to be safe if ip < subnet["first_ip"] or ip > subnet["last_ip"]: ip = -1 db_api.subnet_update(context, subnet, next_auto_assign_ip=ip) return subnet
def _choose_available_subnet(self, context, net_id, version=None, ip_address=None): filters = {} if version: filters["version"] = version subnets = db_api.subnet_find_allocation_counts(context, net_id, scope=db_api.ALL, **filters) for subnet, ips_in_subnet in subnets: ipnet = netaddr.IPNetwork(subnet["cidr"]) if ip_address and ip_address not in ipnet: continue # TODO(mdietz): IP allocation hack, remove +3 later if ipnet.size > (ips_in_subnet + 3): return subnet raise exceptions.IpAddressGenerationFailure(net_id=net_id)