mirror of https://github.com/apache/cloudstack.git
bug 8962: moving vm from one account to other
This commit is contained in:
parent
8a4e060dc9
commit
8e4ec4ce09
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.api.commands;
|
||||
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.BaseAsyncCmd;
|
||||
import com.cloud.api.BaseCmd;
|
||||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.response.UserVmResponse;
|
||||
import com.cloud.api.response.ZoneResponse;
|
||||
import com.cloud.async.AsyncJob;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.uservm.UserVm;
|
||||
|
||||
@Implementation(description="Move a user VM to another user under same domain.", responseObject=UserVmResponse.class)
|
||||
public class MoveUserVMCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(MoveUserVMCmd.class.getName());
|
||||
|
||||
private static final String s_name = "moveuservmresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.HOST_ID, type=CommandType.LONG, description="the host ID of the system VM to be moved")
|
||||
private Long hostId;
|
||||
|
||||
@Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.LONG, description="the accopunt id of the new owner account")
|
||||
private Long accountId;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getHostId() {
|
||||
return hostId;
|
||||
}
|
||||
|
||||
public Long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
try {
|
||||
UserVm userVm = _userVmService.moveVMToUser(this);
|
||||
if (userVm == null){
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to move vm");
|
||||
}
|
||||
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", userVm).get(0);
|
||||
response.setResponseName(DeployVMCmd.getResultObjectName());
|
||||
this.setResponseObject(response);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to move vm " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
UserVm vm = _responseGenerator.findUserVmById(getHostId());
|
||||
if (vm != null) {
|
||||
return vm.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "moving user vm: " + getHostId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_MOVE;
|
||||
}
|
||||
}
|
||||
|
|
@ -28,8 +28,9 @@ public class EventTypes {
|
|||
public static final String EVENT_VM_UPDATE = "VM.UPDATE";
|
||||
public static final String EVENT_VM_UPGRADE = "VM.UPGRADE";
|
||||
public static final String EVENT_VM_RESETPASSWORD = "VM.RESETPASSWORD";
|
||||
public static final String EVENT_VM_MIGRATE = "VM.MIGRATE";
|
||||
|
||||
public static final String EVENT_VM_MIGRATE = "VM.MIGRATE";
|
||||
public static final String EVENT_VM_MOVE = "VM.MOVE";
|
||||
|
||||
// Domain Router
|
||||
public static final String EVENT_ROUTER_CREATE = "ROUTER.CREATE";
|
||||
public static final String EVENT_ROUTER_DESTROY = "ROUTER.DESTROY";
|
||||
|
|
|
|||
|
|
@ -36,5 +36,7 @@ public interface UserVm extends VirtualMachine, ControlledEntity {
|
|||
void setUserData(String userData);
|
||||
|
||||
String getDetail(String name);
|
||||
|
||||
void setAccountId(long accountId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import com.cloud.api.commands.DeployVMCmd;
|
|||
import com.cloud.api.commands.DestroyVMCmd;
|
||||
import com.cloud.api.commands.DetachVolumeCmd;
|
||||
import com.cloud.api.commands.ListVMsCmd;
|
||||
import com.cloud.api.commands.MoveUserVMCmd;
|
||||
import com.cloud.api.commands.RebootVMCmd;
|
||||
import com.cloud.api.commands.RecoverVMCmd;
|
||||
import com.cloud.api.commands.ResetVMPasswordCmd;
|
||||
|
|
@ -369,4 +370,6 @@ public interface UserVmService {
|
|||
* if the VM to be migrated is not in Running state
|
||||
*/
|
||||
UserVm migrateVirtualMachine(UserVm vm, Host destinationHost) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
|
||||
|
||||
UserVm moveVMToUser(MoveUserVMCmd moveUserVMCmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ recoverVirtualMachine=com.cloud.api.commands.RecoverVMCmd;7
|
|||
listVirtualMachines=com.cloud.api.commands.ListVMsCmd;15
|
||||
getVMPassword=com.cloud.api.commands.GetVMPasswordCmd;15
|
||||
migrateVirtualMachine=com.cloud.api.commands.MigrateVMCmd;1
|
||||
moveVirtualMachine=com.cloud.api.commands.MoveUserVMCmd;15
|
||||
|
||||
#### snapshot commands
|
||||
createSnapshot=com.cloud.api.commands.CreateSnapshotCmd;15
|
||||
|
|
|
|||
|
|
@ -139,5 +139,9 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
|
|||
public void setDetails(Map<String, String> details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId){
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ import com.cloud.api.commands.DeployVMCmd;
|
|||
import com.cloud.api.commands.DestroyVMCmd;
|
||||
import com.cloud.api.commands.DetachVolumeCmd;
|
||||
import com.cloud.api.commands.ListVMsCmd;
|
||||
import com.cloud.api.commands.MoveUserVMCmd;
|
||||
import com.cloud.api.commands.RebootVMCmd;
|
||||
import com.cloud.api.commands.RecoverVMCmd;
|
||||
import com.cloud.api.commands.ResetVMPasswordCmd;
|
||||
|
|
@ -3200,5 +3201,46 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
UserVmVO migratedVm = _itMgr.migrate((UserVmVO) vm, srcHostId, dest);
|
||||
return migratedVm;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_MOVE, eventDescription = "move VM to another user", async = false)
|
||||
public UserVm moveVMToUser(MoveUserVMCmd cmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
|
||||
//verify the two users
|
||||
Account oldOwner = UserContext.current().getCaller();
|
||||
Account newOwner = _accountService.getAccount(cmd.getAccountId());
|
||||
if (newOwner == null) {
|
||||
throw new InvalidParameterValueException("Unable to find account " + newOwner + " in domain " + oldOwner.getDomainId());
|
||||
}
|
||||
//get the VM
|
||||
UserVmVO vm = _vmDao.findById(cmd.getHostId());
|
||||
// update the owner
|
||||
vm.setAccountId(newOwner.getAccountId());
|
||||
|
||||
DomainVO domain = _domainDao.findById(oldOwner.getDomainId());
|
||||
// check that caller can operate with domain
|
||||
_accountMgr.checkAccess(oldOwner, domain);
|
||||
// check that vm owner can create vm in the domain
|
||||
_accountMgr.checkAccess(newOwner, domain);
|
||||
|
||||
// check if account/domain is with in resource limits to create a new vm
|
||||
if (_accountMgr.resourceLimitExceeded(newOwner, ResourceType.user_vm)) {
|
||||
ResourceAllocationException rae = new ResourceAllocationException("Maximum number of virtual machines for account: " + newOwner.getAccountName() + " has been exceeded.");
|
||||
rae.setResourceType("vm");
|
||||
throw rae;
|
||||
}
|
||||
|
||||
this.stopVirtualMachine(cmd.getHostId(), true);
|
||||
|
||||
//update ownership
|
||||
vm.setAccountId(newOwner.getId());
|
||||
|
||||
_vmDao.persist(vm);
|
||||
|
||||
this.startVirtualMachine(cmd.getHostId());
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue