use of com.cloud.exception.InsufficientAddressCapacityException in project cloudstack by apache.
the class IpAddressManagerImpl method associateIPToGuestNetwork.
@DB
@Override
public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException {
Account caller = CallContext.current().getCallingAccount();
Account owner = null;
IPAddressVO ipToAssoc = _ipAddressDao.findById(ipId);
if (ipToAssoc != null) {
Network network = _networksDao.findById(networkId);
if (network == null) {
throw new InvalidParameterValueException("Invalid network id is given");
}
DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
if (zone.getNetworkType() == NetworkType.Advanced) {
if (network.getGuestType() == Network.GuestType.Shared) {
if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
_accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.UseEntry, false, network);
} else {
throw new InvalidParameterValueException("IP can be associated with guest network of 'shared' type only if " + "network services Source Nat, Static Nat, Port Forwarding, Load balancing, firewall are enabled in the network");
}
}
} else {
_accountMgr.checkAccess(caller, null, true, ipToAssoc);
}
owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId());
} else {
s_logger.debug("Unable to find ip address by id: " + ipId);
return null;
}
if (ipToAssoc.getAssociatedWithNetworkId() != null) {
s_logger.debug("IP " + ipToAssoc + " is already associated with network id" + networkId);
return ipToAssoc;
}
Network network = _networksDao.findById(networkId);
if (network != null) {
_accountMgr.checkAccess(owner, AccessType.UseEntry, false, network);
} else {
s_logger.debug("Unable to find ip address by id: " + ipId);
return null;
}
DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
// allow associating IP addresses to guest network only
if (network.getTrafficType() != TrafficType.Guest) {
throw new InvalidParameterValueException("Ip address can be associated to the network with trafficType " + TrafficType.Guest);
}
// - and it belongs to the system
if (network.getAccountId() != owner.getId()) {
if (zone.getNetworkType() != NetworkType.Basic && !(zone.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Shared)) {
throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
}
}
if (zone.getNetworkType() == NetworkType.Advanced) {
// In Advance zone allow to do IP assoc only for Isolated networks with source nat service enabled
if (network.getGuestType() == GuestType.Isolated && !(_networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat))) {
if (releaseOnFailure && ipToAssoc != null) {
s_logger.warn("Failed to associate ip address, so unassigning ip from the database " + ipToAssoc);
_ipAddressDao.unassignIpAddress(ipToAssoc.getId());
}
throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + " ip address can be associated only to the network of guest type " + GuestType.Isolated + " with the " + Service.SourceNat.getName() + " enabled");
}
// In Advance zone allow to do IP assoc only for shared networks with source nat/static nat/lb/pf services enabled
if (network.getGuestType() == GuestType.Shared && !isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
if (releaseOnFailure && ipToAssoc != null) {
s_logger.warn("Failed to associate ip address, so unassigning ip from the database " + ipToAssoc);
_ipAddressDao.unassignIpAddress(ipToAssoc.getId());
}
throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + " ip address can be associated with network of guest type " + GuestType.Shared + "only if at " + "least one of the services " + Service.SourceNat.getName() + "/" + Service.StaticNat.getName() + "/" + Service.Lb.getName() + "/" + Service.PortForwarding.getName() + " is enabled");
}
}
boolean isSourceNat = isSourceNatAvailableForNetwork(owner, ipToAssoc, network);
s_logger.debug("Associating ip " + ipToAssoc + " to network " + network);
IPAddressVO ip = _ipAddressDao.findById(ipId);
// update ip address with networkId
ip.setAssociatedWithNetworkId(networkId);
ip.setSourceNat(isSourceNat);
_ipAddressDao.update(ipId, ip);
boolean success = false;
try {
success = applyIpAssociations(network, false);
if (success) {
s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " to network " + network);
} else {
s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " to network " + network);
}
return ip;
} finally {
if (!success && releaseOnFailure) {
if (ip != null) {
try {
s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip);
_ipAddressDao.markAsUnavailable(ip.getId());
if (!applyIpAssociations(network, true)) {
// if fail to apply ip associations again, unassign ip address without updating resource
// count and generating usage event as there is no need to keep it in the db
_ipAddressDao.unassignIpAddress(ip.getId());
}
} catch (Exception e) {
s_logger.warn("Unable to disassociate ip address for recovery", e);
}
}
}
}
}
use of com.cloud.exception.InsufficientAddressCapacityException in project cloudstack by apache.
the class IpAddressManagerImpl method listAvailablePublicIps.
@Override
public List<IPAddressVO> listAvailablePublicIps(final long dcId, final Long podId, final List<Long> vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId, final boolean sourceNat, final boolean assign, final boolean allocate, final String requestedIp, final String requestedGateway, final boolean isSystem, final Long vpcId, final Boolean displayIp, final boolean forSystemVms, final boolean lockOneRow) throws InsufficientAddressCapacityException {
return Transaction.execute(new TransactionCallbackWithException<List<IPAddressVO>, InsufficientAddressCapacityException>() {
@Override
public List<IPAddressVO> doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
StringBuilder errorMessage = new StringBuilder("Unable to get ip address in ");
boolean fetchFromDedicatedRange = false;
List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
DataCenter zone = _entityMgr.findById(DataCenter.class, dcId);
SearchCriteria<IPAddressVO> sc = null;
if (podId != null) {
sc = AssignIpAddressFromPodVlanSearch.create();
sc.setJoinParameters("podVlanMapSB", "podId", podId);
errorMessage.append(" pod id=" + podId);
} else {
sc = AssignIpAddressSearch.create();
errorMessage.append(" zone id=" + dcId);
}
// If owner has dedicated Public IP ranges, fetch IP from the dedicated range
// Otherwise fetch IP from the system pool
Network network = _networksDao.findById(guestNetworkId);
// Checking if network is null in the case of system VM's. At the time of allocation of IP address to systemVm, no network is present.
if (network == null || !(network.getGuestType() == GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
for (AccountVlanMapVO map : maps) {
if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
dedicatedVlanDbIds.add(map.getVlanDbId());
}
}
List<DomainVlanMapVO> domainMaps = _domainVlanMapDao.listDomainVlanMapsByDomain(owner.getDomainId());
for (DomainVlanMapVO map : domainMaps) {
if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
dedicatedVlanDbIds.add(map.getVlanDbId());
}
List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId()))
nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
}
if (vlanUse == VlanType.VirtualNetwork) {
if (!dedicatedVlanDbIds.isEmpty()) {
fetchFromDedicatedRange = true;
sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray()));
} else if (!nonDedicatedVlanDbIds.isEmpty()) {
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
} else {
if (podId != null) {
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
throw ex;
}
s_logger.warn(errorMessage.toString());
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
throw ex;
}
}
sc.setParameters("dc", dcId);
// for direct network take ip addresses only from the vlans belonging to the network
if (vlanUse == VlanType.DirectAttached) {
sc.setJoinParameters("vlan", "networkId", guestNetworkId);
errorMessage.append(", network id=" + guestNetworkId);
}
if (requestedGateway != null) {
sc.setJoinParameters("vlan", "vlanGateway", requestedGateway);
errorMessage.append(", requested gateway=" + requestedGateway);
}
sc.setJoinParameters("vlan", "type", vlanUse);
String routerIpAddress = null;
if (network != null) {
NetworkDetailVO routerIpDetail = _networkDetailsDao.findDetail(network.getId(), ApiConstants.ROUTER_IP);
routerIpAddress = routerIpDetail != null ? routerIpDetail.getValue() : null;
}
if (requestedIp != null) {
sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
errorMessage.append(": requested ip " + requestedIp + " is not available");
} else if (routerIpAddress != null) {
sc.addAnd("address", Op.NEQ, routerIpAddress);
}
boolean ascOrder = !forSystemVms;
Filter filter = new Filter(IPAddressVO.class, "forSystemVms", ascOrder, 0l, 1l);
if (SystemVmPublicIpReservationModeStrictness.value()) {
sc.setParameters("forSystemVms", forSystemVms);
}
filter.addOrderBy(IPAddressVO.class, "vlanId", true);
List<IPAddressVO> addrs;
if (lockOneRow) {
addrs = _ipAddressDao.lockRows(sc, filter, true);
} else {
addrs = new ArrayList<>(_ipAddressDao.search(sc, null));
}
// If all the dedicated IPs of the owner are in use fetch an IP from the system pool
if ((!lockOneRow || (lockOneRow && addrs.size() == 0)) && fetchFromDedicatedRange && vlanUse == VlanType.VirtualNetwork) {
// Verify if account is allowed to acquire IPs from the system
boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId());
if (useSystemIps && !nonDedicatedVlanDbIds.isEmpty()) {
fetchFromDedicatedRange = false;
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
if (lockOneRow) {
addrs = _ipAddressDao.lockRows(sc, filter, true);
} else {
addrs.addAll(_ipAddressDao.search(sc, null));
}
}
}
if (lockOneRow && addrs.size() == 0) {
if (podId != null) {
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
// for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object.
ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
throw ex;
}
s_logger.warn(errorMessage.toString());
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
throw ex;
}
if (lockOneRow) {
assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
}
if (assign) {
assignAndAllocateIpAddressEntry(owner, vlanUse, guestNetworkId, sourceNat, allocate, isSystem, vpcId, displayIp, fetchFromDedicatedRange, addrs);
}
return addrs;
}
});
}
use of com.cloud.exception.InsufficientAddressCapacityException in project cloudstack by apache.
the class IpAddressManagerImpl method allocateIp.
@DB
@Override
public IpAddress allocateIp(final Account ipOwner, final boolean isSystem, Account caller, long callerUserId, final DataCenter zone, final Boolean displayIp, final String ipaddress) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException {
final VlanType vlanType = VlanType.VirtualNetwork;
final boolean assign = false;
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
// zone is of type DataCenter. See DataCenterVO.java.
PermissionDeniedException ex = new PermissionDeniedException(generateErrorMessageForOperationOnDisabledZone("allocate IP addresses", zone));
ex.addProxyObject(zone.getUuid(), "zoneId");
throw ex;
}
PublicIp ip = null;
Account accountToLock = null;
try {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
}
accountToLock = _accountDao.acquireInLockTable(ipOwner.getId());
if (accountToLock == null) {
s_logger.warn("Unable to lock account: " + ipOwner.getId());
throw new ConcurrentOperationException("Unable to acquire account lock");
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Associate IP address lock acquired");
}
ip = Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {
@Override
public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, ipaddress, null, isSystem, null, displayIp, false);
if (ip == null) {
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone.getId());
ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid());
throw ex;
}
CallContext.current().setEventDetails("Ip Id: " + ip.getId());
Ip ipAddress = ip.getAddress();
s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId());
return ip;
}
});
} finally {
if (accountToLock != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Releasing lock account " + ipOwner);
}
_accountDao.releaseFromLockTable(ipOwner.getId());
s_logger.debug("Associate IP address lock released");
}
}
return ip;
}
use of com.cloud.exception.InsufficientAddressCapacityException in project cloudstack by apache.
the class UserVmManagerImpl method updateNicIpForVirtualMachine.
@Override
public UserVm updateNicIpForVirtualMachine(UpdateVmNicIpCmd cmd) {
Long nicId = cmd.getNicId();
String ipaddr = cmd.getIpaddress();
Account caller = CallContext.current().getCallingAccount();
// check whether the nic belongs to user vm.
NicVO nicVO = _nicDao.findById(nicId);
if (nicVO == null) {
throw new InvalidParameterValueException("There is no nic for the " + nicId);
}
if (nicVO.getVmType() != VirtualMachine.Type.User) {
throw new InvalidParameterValueException("The nic is not belongs to user vm");
}
UserVm vm = _vmDao.findById(nicVO.getInstanceId());
if (vm == null) {
throw new InvalidParameterValueException("There is no vm with the nic");
}
Network network = _networkDao.findById(nicVO.getNetworkId());
if (network == null) {
throw new InvalidParameterValueException("There is no network with the nic");
}
// Don't allow to update vm nic ip if network is not in Implemented/Setup/Allocated state
if (!(network.getState() == Network.State.Allocated || network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup)) {
throw new InvalidParameterValueException("Network is not in the right state to update vm nic ip. Correct states are: " + Network.State.Allocated + ", " + Network.State.Implemented + ", " + Network.State.Setup);
}
NetworkOfferingVO offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
if (offering == null) {
throw new InvalidParameterValueException("There is no network offering with the network");
}
if (!_networkModel.listNetworkOfferingServices(offering.getId()).isEmpty() && vm.getState() != State.Stopped) {
InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Stopped, unable to update the vm nic having the specified id");
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
// verify permissions
_accountMgr.checkAccess(caller, null, true, vm);
Account ipOwner = _accountDao.findByIdIncludingRemoved(vm.getAccountId());
// verify ip address
s_logger.debug("Calling the ip allocation ...");
DataCenter dc = _dcDao.findById(network.getDataCenterId());
if (dc == null) {
throw new InvalidParameterValueException("There is no dc with the nic");
}
if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) {
try {
ipaddr = _ipAddrMgr.allocateGuestIP(network, ipaddr);
} catch (InsufficientAddressCapacityException e) {
throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, for insufficient address capacity");
}
if (ipaddr == null) {
throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, please choose another ip");
}
if (nicVO.getIPv4Address() != null) {
updatePublicIpDnatVmIp(vm.getId(), network.getId(), nicVO.getIPv4Address(), ipaddr);
updateLoadBalancerRulesVmIp(vm.getId(), network.getId(), nicVO.getIPv4Address(), ipaddr);
updatePortForwardingRulesVmIp(vm.getId(), network.getId(), nicVO.getIPv4Address(), ipaddr);
}
} else if (dc.getNetworkType() == NetworkType.Basic || network.getGuestType() == Network.GuestType.Shared) {
// handle the basic networks here
// for basic zone, need to provide the podId to ensure proper ip alloation
Long podId = null;
if (dc.getNetworkType() == NetworkType.Basic) {
podId = vm.getPodIdToDeployIn();
if (podId == null) {
throw new InvalidParameterValueException("vm pod id is null in Basic zone; can't decide the range for ip allocation");
}
}
try {
ipaddr = _ipAddrMgr.allocatePublicIpForGuestNic(network, podId, ipOwner, ipaddr);
if (ipaddr == null) {
throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, please choose another ip");
}
final IPAddressVO newIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), ipaddr);
final Vlan vlan = _vlanDao.findById(newIp.getVlanId());
nicVO.setIPv4Gateway(vlan.getVlanGateway());
nicVO.setIPv4Netmask(vlan.getVlanNetmask());
final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nicVO.getNetworkId(), nicVO.getIPv4Address());
if (ip != null) {
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
_ipAddrMgr.markIpAsUnavailable(ip.getId());
_ipAddressDao.unassignIpAddress(ip.getId());
}
});
}
} catch (InsufficientAddressCapacityException e) {
s_logger.error("Allocating ip to guest nic " + nicVO.getUuid() + " failed, for insufficient address capacity");
return null;
}
} else {
throw new InvalidParameterValueException("UpdateVmNicIpCmd is not supported in L2 network");
}
s_logger.debug("Updating IPv4 address of NIC " + nicVO + " to " + ipaddr + "/" + nicVO.getIPv4Netmask() + " with gateway " + nicVO.getIPv4Gateway());
nicVO.setIPv4Address(ipaddr);
_nicDao.persist(nicVO);
return vm;
}
use of com.cloud.exception.InsufficientAddressCapacityException in project cosmic by MissionCriticalCloud.
the class AddIpToVmNicTest method testCreateFailure.
@Test
public void testCreateFailure() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
final NetworkService networkService = Mockito.mock(NetworkService.class);
final AddIpToVmNicCmd ipTonicCmd = Mockito.mock(AddIpToVmNicCmd.class);
Mockito.when(networkService.allocateSecondaryGuestIP(Matchers.anyLong(), Matchers.anyString())).thenReturn(null);
ipTonicCmd._networkService = networkService;
try {
ipTonicCmd.execute();
} catch (final InsufficientAddressCapacityException e) {
throw new InvalidParameterValueException("Allocating guest ip for nic failed");
}
}
Aggregations