diff --git a/api/src/com/cloud/api/commands/AssignVMCmd.java b/api/src/com/cloud/api/commands/AssignVMCmd.java index 51b06cd3e2e..2cc58b56fdb 100644 --- a/api/src/com/cloud/api/commands/AssignVMCmd.java +++ b/api/src/com/cloud/api/commands/AssignVMCmd.java @@ -52,17 +52,20 @@ public class AssignVMCmd extends BaseCmd { @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the vm ID of the user VM to be moved") private Long virtualMachineId; - @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for the vpn user. Must be used with domainId.") + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, required=true, description="an optional account for the vpn user. Must be used with domainId.") private String accountName; - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId for the vpn user. If the account parameter is used, domainId must also be used.") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, required=true, description="an optional domainId for the vpn user. If the account parameter is used, domainId must also be used.") private Long domainId; //Network information @IdentityMapper(entityTableName="networks") - @Parameter(name=ApiConstants.NETWORK_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, description="list of network ids that will be part of VM network after move") + @Parameter(name=ApiConstants.NETWORK_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, description="list of network ids that will be part of VM network after move in advanced network setting.") private List networkIds; + @IdentityMapper(entityTableName="security_group") + @Parameter(name=ApiConstants.SECURITY_GROUP_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, description="comma separated list of security groups id that going to be applied to the virtual machine. Should be passed only when vm is moved in a zone with Basic Network support.") + private List securityGroupIdList; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -84,6 +87,11 @@ public class AssignVMCmd extends BaseCmd { return networkIds; } + public List getSecurityGroupIdList() { + return securityGroupIdList; + } + + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 06183faec45..c001c7d20bd 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3361,6 +3361,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager throw new InvalidParameterValueException("The new account owner " + cmd.getAccountName() + " is disabled."); } + // make sure the accounts are under same domain + if (oldAccount.getDomainId() != newAccount.getDomainId()){ + throw new InvalidParameterValueException("The account should be under smae domain for moving VM between two accounts. Old owner domain =" + oldAccount.getDomainId() + + " New owner domain=" + newAccount.getDomainId()); + } + // don't allow to move the vm if there are existing PF/LB/Static Nat rules, existing Security groups or vm is assigned to static Nat ip IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(cmd.getVmId()); if (ip != null){ @@ -3441,8 +3447,67 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager // OS 3: update the network List networkIdList = cmd.getNetworkIds(); + List securityGroupIdList = cmd.getSecurityGroupIdList(); + if (zone.getNetworkType() == NetworkType.Basic) { + //cleanup the old security groups + _securityGroupMgr.removeInstanceFromGroups(cmd.getVmId()); //security groups will be recreated for the new account, when the VM is started + List networkList = new ArrayList(); + + // Get default guest network in Basic zone + Network defaultNetwork = _networkMgr.getExclusiveGuestNetwork(zone.getId()); + + if (defaultNetwork == null) { + throw new InvalidParameterValueException("Unable to find a default network to start a vm"); + } else { + networkList.add(_networkDao.findById(defaultNetwork.getId())); + } + + boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware); + + if (securityGroupIdList != null && isVmWare) { + throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor"); + } else if (!isVmWare && _networkMgr.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkMgr.canAddDefaultSecurityGroup()) { + if (securityGroupIdList == null) { + securityGroupIdList = new ArrayList(); + } + SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(newAccount.getId()); + if (defaultGroup != null) { + //check if security group id list already contains Default security group, and if not - add it + boolean defaultGroupPresent = false; + for (Long securityGroupId : securityGroupIdList) { + if (securityGroupId.longValue() == defaultGroup.getId()) { + defaultGroupPresent = true; + break; + } + } + + if (!defaultGroupPresent) { + securityGroupIdList.add(defaultGroup.getId()); + } + + } else { + //create default security group for the account + if (s_logger.isDebugEnabled()) { + s_logger.debug("Couldn't find default security group for the account " + newAccount + " so creating a new one"); + } + defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION, newAccount.getDomainId(), newAccount.getId(), newAccount.getAccountName()); + securityGroupIdList.add(defaultGroup.getId()); + } + } + + + List> networks = new ArrayList>(); + NicProfile profile = new NicProfile(); + profile.setDefaultNic(true); + networks.add(new Pair(networkList.get(0), profile)); + + VMInstanceVO vmi = _itMgr.findByIdAndType(vm.getType(), vm.getId()); + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi); + _networkMgr.allocate(vmProfile, networks); + + _securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList); } else { if (zone.isSecurityGroupEnabled()) { throw new InvalidParameterValueException("not yet tested for SecurityGroupEnabled advanced networks.");