use of com.cloud.legacymodel.exceptions.PermissionDeniedException in project cosmic by MissionCriticalCloud.
the class UserVmManagerImpl method upgradeRunningVirtualMachine.
private boolean upgradeRunningVirtualMachine(final Long vmId, final Long newServiceOfferingId, final Map<String, String> customParameters) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
final Account caller = CallContext.current().getCallingAccount();
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
if (vmInstance.getHypervisorType() != HypervisorType.XenServer) {
s_logger.info("Scaling the VM dynamically is not supported for VMs running on Hypervisor " + vmInstance.getHypervisorType());
throw new InvalidParameterValueException("Scaling the VM dynamically is not supported for VMs running on Hypervisor " + vmInstance.getHypervisorType());
}
_accountMgr.checkAccess(caller, null, true, vmInstance);
// Check if its a scale "up"
ServiceOfferingVO newServiceOffering = _offeringDao.findById(newServiceOfferingId);
// Check that the specified service offering ID is valid
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
final ServiceOffering currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
final int newCpu = newServiceOffering.getCpu();
final int newMemory = newServiceOffering.getRamSize();
final int currentCpu = currentServiceOffering.getCpu();
final int currentMemory = currentServiceOffering.getRamSize();
final int memoryDiff = newMemory - currentMemory;
final int cpuDiff = newCpu - currentCpu;
// Don't allow to scale when (Any of the new values less than current values) OR (All current and new values are same)
if (newMemory < currentMemory || newCpu < currentCpu || newMemory == currentMemory && newCpu == currentCpu) {
throw new InvalidParameterValueException("Only scaling up the vm is supported, new service offering(cpu=" + newCpu + ",memory=," + newMemory + ")" + " should have at least one value(cpu/ram) greater than old value and no resource value less than older(cpu=" + currentCpu + ",memory=," + currentMemory + ")");
}
// Check resource limits
if (newCpu > currentCpu) {
_resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, newCpu - currentCpu);
}
if (newMemory > currentMemory) {
_resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, newMemory - currentMemory);
}
// Dynamically upgrade the running vms
boolean success = false;
if (vmInstance.getState().equals(State.Running)) {
int retry = _scaleRetry;
final ExcludeList excludes = new ExcludeList();
// Check zone wide flag
final boolean enableDynamicallyScaleVm = EnableDynamicallyScaleVm.valueIn(vmInstance.getDataCenterId());
if (!enableDynamicallyScaleVm) {
throw new PermissionDeniedException("Dynamically scaling virtual machines is disabled for this zone, please contact your admin");
}
// Check vm flag
if (!vmInstance.isDynamicallyScalable()) {
throw new CloudRuntimeException("Unable to Scale the vm: " + vmInstance.getUuid() + " as vm does not have tools to support dynamic scaling");
}
// Check disable threshold for cluster is not crossed
final HostVO host = _hostDao.findById(vmInstance.getHostId());
if (_capacityMgr.checkIfClusterCrossesThreshold(host.getClusterId(), cpuDiff, memoryDiff)) {
throw new CloudRuntimeException("Unable to scale vm: " + vmInstance.getUuid() + " due to insufficient resources");
}
while (retry-- != 0) {
// It's != so that it can match -1.
try {
boolean existingHostHasCapacity = false;
// Increment CPU and Memory count accordingly.
if (newCpu > currentCpu) {
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
}
if (memoryDiff > 0) {
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
}
// #1 Check existing host has capacity
if (!excludes.shouldAvoid(ApiDBUtils.findHostById(vmInstance.getHostId()))) {
existingHostHasCapacity = _capacityMgr.checkIfHostHasCpuCapability(vmInstance.getHostId(), newCpu) && _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), cpuDiff, memoryDiff * 1024L * 1024L, false, _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_CPU), _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_MEMORY), false);
excludes.addHost(vmInstance.getHostId());
}
// #2 migrate the vm if host doesn't have capacity or is in avoid set
if (!existingHostHasCapacity) {
_itMgr.findHostAndMigrate(vmInstance.getUuid(), newServiceOfferingId, excludes);
}
// #3 scale the vm now
_itMgr.upgradeVmDb(vmId, newServiceOfferingId);
vmInstance = _vmInstanceDao.findById(vmId);
_itMgr.reConfigureVm(vmInstance.getUuid(), currentServiceOffering, existingHostHasCapacity);
success = true;
return success;
} catch (final InsufficientCapacityException e) {
s_logger.warn("Received exception while scaling ", e);
} catch (final ResourceUnavailableException e) {
s_logger.warn("Received exception while scaling ", e);
} catch (final ConcurrentOperationException e) {
s_logger.warn("Received exception while scaling ", e);
} catch (final Exception e) {
s_logger.warn("Received exception while scaling ", e);
} finally {
if (!success) {
// rollback
_itMgr.upgradeVmDb(vmId, currentServiceOffering.getId());
// Decrement CPU and Memory count accordingly.
if (newCpu > currentCpu) {
_resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
}
if (memoryDiff > 0) {
_resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
}
}
}
}
}
return success;
}
use of com.cloud.legacymodel.exceptions.PermissionDeniedException in project cosmic by MissionCriticalCloud.
the class UserVmManagerImpl method stopVirtualMachine.
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_STOP, eventDescription = "stopping Vm", async = true)
public UserVm stopVirtualMachine(final long vmId, final boolean forced) throws ConcurrentOperationException {
// Input validation
final Account caller = CallContext.current().getCallingAccount();
final Long userId = CallContext.current().getCallingUserId();
// if account is removed, return error
if (caller != null && caller.getRemoved() != null) {
throw new PermissionDeniedException("The account " + caller.getUuid() + " is removed");
}
final UserVmVO vm = _vmDao.findById(vmId);
if (vm == null) {
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
}
_userDao.findById(userId);
final boolean status;
try {
final VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
if (forced || vm.getState() == State.Paused) {
status = vmEntity.stopForced(Long.toString(userId));
} else {
status = vmEntity.stop(Long.toString(userId));
}
if (status) {
return _vmDao.findById(vmId);
} else {
return null;
}
} catch (final ResourceUnavailableException e) {
throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e);
} catch (final CloudException e) {
throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e);
}
}
use of com.cloud.legacymodel.exceptions.PermissionDeniedException in project cosmic by MissionCriticalCloud.
the class UserVmManagerImpl method restoreVMInternal.
public UserVm restoreVMInternal(final Account caller, UserVmVO vm, final Long newTemplateId) throws InsufficientCapacityException, ResourceUnavailableException {
final Long userId = caller.getId();
final Account owner = _accountDao.findById(vm.getAccountId());
_userDao.findById(userId);
final long vmId = vm.getId();
boolean needRestart = false;
// Input validation
if (owner == null) {
throw new InvalidParameterValueException("The owner of " + vm + " does not exist: " + vm.getAccountId());
}
if (owner.getState() == Account.State.disabled) {
throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId());
}
if (vm.getState() != VirtualMachine.State.Running && vm.getState() != VirtualMachine.State.Stopped) {
throw new CloudRuntimeException("Vm " + vm.getUuid() + " currently in " + vm.getState() + " state, restore vm can only execute when VM in Running or Stopped");
}
if (vm.getState() == VirtualMachine.State.Running) {
needRestart = true;
}
final List<VolumeVO> rootVols = _volsDao.findByInstanceAndType(vmId, VolumeType.ROOT);
if (rootVols.isEmpty()) {
final InvalidParameterValueException ex = new InvalidParameterValueException("Can not find root volume for VM " + vm.getUuid());
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
if (rootVols.size() > 1) {
final InvalidParameterValueException ex = new InvalidParameterValueException("There are " + rootVols.size() + " root volumes for VM " + vm.getUuid());
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
final VolumeVO root = rootVols.get(0);
if (!Volume.State.Allocated.equals(root.getState()) || newTemplateId != null) {
Long templateId = root.getTemplateId();
boolean isISO = false;
if (templateId == null) {
// Assuming that for a vm deployed using ISO, template ID is set to NULL
isISO = true;
templateId = vm.getIsoId();
}
// If target VM has associated VM snapshots then don't allow restore of VM
final List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
if (vmSnapshots.size() > 0) {
throw new InvalidParameterValueException("Unable to restore VM, please remove VM snapshots before restoring VM");
}
final VMTemplateVO template;
// newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly
if (newTemplateId != null) {
template = _templateDao.findById(newTemplateId);
_accountMgr.checkAccess(caller, null, true, template);
if (isISO) {
if (!template.getFormat().equals(ImageFormat.ISO)) {
throw new InvalidParameterValueException("Invalid ISO id provided to restore the VM ");
}
} else {
if (template.getFormat().equals(ImageFormat.ISO)) {
throw new InvalidParameterValueException("Invalid template id provided to restore the VM ");
}
}
} else {
if (isISO && templateId == null) {
throw new CloudRuntimeException("Cannot restore the VM since there is no ISO attached to VM");
}
template = _templateDao.findById(templateId);
if (template == null) {
final InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find template/ISO for specified volumeid and vmId");
ex.addProxyObject(vm.getUuid(), "vmId");
ex.addProxyObject(root.getUuid(), "volumeId");
throw ex;
}
}
final TemplateDataStoreVO tmplStore = _templateStoreDao.findByTemplateZoneReady(template.getId(), vm.getDataCenterId());
if (tmplStore == null) {
throw new InvalidParameterValueException("Cannot restore the vm as the template " + template.getUuid() + " isn't available in the zone");
}
if (needRestart) {
try {
_itMgr.stop(vm.getUuid());
} catch (final ResourceUnavailableException e) {
s_logger.debug("Stop vm " + vm.getUuid() + " failed", e);
final CloudRuntimeException ex = new CloudRuntimeException("Stop vm failed for specified vmId");
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
}
/* If new template/ISO is provided allocate a new volume from new template/ISO otherwise allocate new volume from original template/ISO */
final Volume newVol;
if (newTemplateId != null) {
if (isISO) {
newVol = volumeMgr.allocateDuplicateVolume(root, null);
vm.setIsoId(newTemplateId);
vm.setGuestOSId(template.getGuestOSId());
vm.setTemplateId(newTemplateId);
_vmDao.update(vmId, vm);
} else {
newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
vm.setGuestOSId(template.getGuestOSId());
vm.setTemplateId(newTemplateId);
_vmDao.update(vmId, vm);
}
} else {
newVol = volumeMgr.allocateDuplicateVolume(root, null);
}
// 1. Save usage event and update resource count for user vm volumes
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.volume, newVol.isDisplay());
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.primary_storage, newVol.isDisplay(), new Long(newVol.getSize()));
handleManagedStorage(vm, root);
_volsDao.attachVolume(newVol.getId(), vmId, newVol.getDeviceId(), newVol.getDiskController());
// Detach, destroy and create the usage event for the old root volume.
_volsDao.detachVolume(root.getId());
volumeMgr.destroyVolume(root);
Map<VirtualMachineProfile.Param, Object> params = null;
String password = null;
if (template.getEnablePassword()) {
password = _mgr.generateRandomPassword();
final boolean result = resetVMPasswordInternal(vmId, password);
if (result) {
vm.setPassword(password);
_vmDao.loadDetails(vm);
// update the password in vm_details table too
// Check if an SSH key pair was selected for the instance and if so
// use it to encrypt & save the vm password
encryptAndStorePassword(vm, password);
} else {
throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine ");
}
}
if (needRestart) {
try {
if (vm.getDetail("password") != null) {
params = new HashMap<>();
params.put(VirtualMachineProfile.Param.VmPassword, password);
}
_itMgr.start(vm.getUuid(), params);
vm = _vmDao.findById(vmId);
if (template.getEnablePassword()) {
// this value is not being sent to the backend; need only for api
// display purposes
vm.setPassword(password);
if (vm.isUpdateParameters()) {
vm.setUpdateParameters(false);
_vmDao.loadDetails(vm);
if (vm.getDetail("password") != null) {
_vmDetailsDao.remove(_vmDetailsDao.findDetail(vm.getId(), "password").getId());
}
_vmDao.update(vm.getId(), vm);
}
}
} catch (final Exception e) {
s_logger.debug("Unable to start VM " + vm.getUuid(), e);
final CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM with specified id" + e.getMessage());
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
}
}
s_logger.debug("Restore VM " + vmId + " done successfully");
return vm;
}
use of com.cloud.legacymodel.exceptions.PermissionDeniedException in project cosmic by MissionCriticalCloud.
the class UserVmManagerImpl method expungeVm.
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_EXPUNGE, eventDescription = "expunging Vm", async = true)
public UserVm expungeVm(final long vmId) throws ResourceUnavailableException, ConcurrentOperationException {
final Account caller = CallContext.current().getCallingAccount();
final Long userId = caller.getId();
// Verify input parameters
final UserVmVO vm = _vmDao.findById(vmId);
if (vm == null) {
final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a virtual machine with specified vmId");
ex.addProxyObject(String.valueOf(vmId), "vmId");
throw ex;
}
if (vm.getRemoved() != null) {
s_logger.trace("Vm id=" + vmId + " is already expunged");
return vm;
}
if (!(vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getState() == State.Error)) {
final CloudRuntimeException ex = new CloudRuntimeException("Please destroy vm with specified vmId before expunge");
ex.addProxyObject(String.valueOf(vmId), "vmId");
throw ex;
}
// When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller.
if (!_accountMgr.isAdmin(userId) && !AllowUserExpungeRecoverVm.valueIn(userId)) {
throw new PermissionDeniedException("Expunging a vm can only be done by an Admin. Or when the allow.user.expunge.recover.vm key is set.");
}
final boolean status;
status = expunge(vm, userId, caller);
if (status) {
return _vmDao.findByIdIncludingRemoved(vmId);
} else {
final CloudRuntimeException ex = new CloudRuntimeException("Failed to expunge vm with specified vmId");
ex.addProxyObject(String.valueOf(vmId), "vmId");
throw ex;
}
}
use of com.cloud.legacymodel.exceptions.PermissionDeniedException in project cosmic by MissionCriticalCloud.
the class UserVmManagerImpl method vmStorageMigration.
@Override
public VirtualMachine vmStorageMigration(final Long vmId, final StoragePool destPool) {
// access check - only root admin can migrate VM
final Account caller = CallContext.current().getCallingAccount();
if (!_accountMgr.isRootAdmin(caller.getId())) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
}
throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
}
final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
if (vm == null) {
throw new InvalidParameterValueException("Unable to find the VM by id=" + vmId);
}
if (vm.getState() != State.Stopped) {
final InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Stopped, unable to migrate the vm having the specified id");
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
if (vm.getType() != VirtualMachineType.User) {
throw new InvalidParameterValueException("can only do storage migration on user vm");
}
final List<VolumeVO> vols = _volsDao.findByInstance(vm.getId());
if (vols.size() > 1) {
throw new InvalidParameterValueException("Data disks attached to the vm, can not migrate. Need to dettach data disks at first");
}
// Check that Vm does not have VM Snapshots
if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
throw new InvalidParameterValueException("VM's disk cannot be migrated, please remove all the VM Snapshots for this VM");
}
HypervisorType destHypervisorType = destPool.getHypervisor();
if (destHypervisorType == null) {
destHypervisorType = _clusterDao.findById(destPool.getClusterId()).getHypervisorType();
}
if (vm.getHypervisorType() != destHypervisorType) {
throw new InvalidParameterValueException("hypervisor is not compatible: dest: " + destHypervisorType.toString() + ", vm: " + vm.getHypervisorType().toString());
}
_itMgr.storageMigration(vm.getUuid(), destPool);
return _vmDao.findById(vm.getId());
}
Aggregations