def test__provision_tenant_private_network_handles_subnet_errors(self): network_id = uuidutils.generate_uuid() self.mixin._core_plugin.create_network.return_value = ( {'id': network_id}) self.mixin._core_plugin.create_subnet.side_effect = ( c_exc.SubnetAllocationError(reason='disaster')) with mock.patch.object(self.mixin, "_get_supported_subnetpools") as f,\ mock.patch.object(self.mixin, "_cleanup") as g: f.return_value = ( [{'ip_version': 4, "id": uuidutils.generate_uuid()}]) self.assertRaises(exceptions.AutoAllocationFailure, self.mixin._provision_tenant_private_network, self.ctx, 'foo_tenant') g.assert_called_once_with(self.ctx, network_id)
def _allocate_specific_subnet(self, request): with self._context.session.begin(subtransactions=True): self._check_subnetpool_tenant_quota(request.tenant_id, request.prefixlen) cidr = request.subnet_cidr available = self._get_available_prefix_list() matched = netaddr.all_matching_cidrs(cidr, available) if len(matched) is 1 and matched[0].prefixlen <= cidr.prefixlen: return IpamSubnet(request.tenant_id, request.subnet_id, cidr, gateway_ip=request.gateway_ip, allocation_pools=request.allocation_pools) msg = _("Cannot allocate requested subnet from the available " "set of prefixes") raise n_exc.SubnetAllocationError(reason=msg)
def allocate_subnet(self, request): max_prefixlen = int(self._subnetpool['max_prefixlen']) min_prefixlen = int(self._subnetpool['min_prefixlen']) if request.prefixlen > max_prefixlen: raise n_exc.MaxPrefixSubnetAllocationError( prefixlen=request.prefixlen, max_prefixlen=max_prefixlen) if request.prefixlen < min_prefixlen: raise n_exc.MinPrefixSubnetAllocationError( prefixlen=request.prefixlen, min_prefixlen=min_prefixlen) if isinstance(request, ipam_req.AnySubnetRequest): return self._allocate_any_subnet(request) elif isinstance(request, ipam_req.SpecificSubnetRequest): return self._allocate_specific_subnet(request) else: msg = _("Unsupported request type") raise n_exc.SubnetAllocationError(reason=msg)
def _allocate_any_subnet(self, session, request): with session.begin(subtransactions=True): self._lock_subnetpool(session) self._check_subnetpool_tenant_quota(session, request.tenant_id, request.prefixlen) prefix_pool = self._get_available_prefix_list(session) for prefix in prefix_pool: if request.prefixlen >= prefix.prefixlen: subnet = prefix.subnet(request.prefixlen).next() gateway_ip = request.gateway_ip if not gateway_ip: gateway_ip = subnet.network + 1 return IpamSubnet(request.tenant_id, request.subnet_id, subnet.cidr, gateway_ip=gateway_ip, allocation_pools=None) msg = _("Insufficient prefix space to allocate subnet size /%s") raise n_exc.SubnetAllocationError(reason=msg % str(request.prefixlen))
def _allocate_any_subnet(self, request): with db_api.context_manager.writer.using(self._context): self._lock_subnetpool() self._check_subnetpool_tenant_quota(request.tenant_id, request.prefixlen) prefix_pool = self._get_available_prefix_list() for prefix in prefix_pool: if request.prefixlen >= prefix.prefixlen: subnet = next(prefix.subnet(request.prefixlen)) gateway_ip = request.gateway_ip if not gateway_ip: gateway_ip = subnet.network + 1 pools = ipam_utils.generate_pools(subnet.cidr, gateway_ip) return IpamSubnet(request.tenant_id, request.subnet_id, subnet.cidr, gateway_ip=gateway_ip, allocation_pools=pools) msg = _("Insufficient prefix space to allocate subnet size /%s") raise n_exc.SubnetAllocationError(reason=msg % str(request.prefixlen))