mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-7985: (1) allow migrate vm from/to project; (2) UI change for selecting account/project/network
This commit is contained in:
parent
0db4471be0
commit
a1d2fba1d2
|
|
@ -29,6 +29,7 @@ import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
|||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
|
||||
|
|
@ -58,12 +59,15 @@ public class AssignVMCmd extends BaseCmd {
|
|||
description = "id of the VM to be moved")
|
||||
private Long virtualMachineId;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "account name of the new VM owner.")
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account name of the new VM owner.")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, required = true, description = "domain id of the new VM owner.")
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain id of the new VM owner.")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "an optional project for the new VM owner.")
|
||||
private Long projectId;
|
||||
|
||||
//Network information
|
||||
@Parameter(name = ApiConstants.NETWORK_IDS,
|
||||
type = CommandType.LIST,
|
||||
|
|
@ -98,6 +102,10 @@ public class AssignVMCmd extends BaseCmd {
|
|||
return domainId;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public List<Long> getNetworkIds() {
|
||||
return networkIds;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
@Param(description = "the account name of the project's owner")
|
||||
private String ownerName;
|
||||
|
||||
@SerializedName("projectaccountname")
|
||||
@Param(description="the project account name of the project")
|
||||
private String projectAccountName;
|
||||
|
||||
@SerializedName(ApiConstants.STATE)
|
||||
@Param(description = "the state of the project")
|
||||
private String state;
|
||||
|
|
@ -228,6 +232,10 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
ownerName = owner;
|
||||
}
|
||||
|
||||
public void setProjectAccountName(String projectAccountName) {
|
||||
this.projectAccountName = projectAccountName;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ public class ProjectJoinDaoImpl extends GenericDaoBase<ProjectJoinVO, Long> impl
|
|||
Account account = _accountDao.findByIdIncludingRemoved(proj.getProjectAccountId());
|
||||
AccountJoinVO accountJn = ApiDBUtils.newAccountView(account);
|
||||
_accountJoinDao.setResourceLimits(accountJn, false, response);
|
||||
response.setProjectAccountName(accountJn.getAccountName());
|
||||
|
||||
response.setObjectName("project");
|
||||
return response;
|
||||
|
|
|
|||
|
|
@ -5048,14 +5048,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
if (oldAccount == null) {
|
||||
throw new InvalidParameterValueException("Invalid account for VM " + vm.getAccountId() + " in domain.");
|
||||
}
|
||||
// don't allow to move the vm from the project
|
||||
if (oldAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Specified Vm id belongs to the project and can't be moved");
|
||||
ex.addProxyObject(vm.getUuid(), "vmId");
|
||||
throw ex;
|
||||
}
|
||||
final Account newAccount = _accountService.getActiveAccountByName(cmd.getAccountName(), cmd.getDomainId());
|
||||
if (newAccount == null || newAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||
final Account newAccount = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
|
||||
if (newAccount == null) {
|
||||
throw new InvalidParameterValueException("Invalid accountid=" + cmd.getAccountName() + " in domain " + cmd.getDomainId());
|
||||
}
|
||||
|
||||
|
|
@ -5356,7 +5350,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
s_logger.debug("AssignVM: Advance virtual, adding networks no " + networks.size() + " to " + vm.getInstanceName());
|
||||
} // END IF NON SEC GRP ENABLED
|
||||
} // END IF ADVANCED
|
||||
s_logger.info("AssignVM: vm " + vm.getInstanceName() + " now belongs to account " + cmd.getAccountName());
|
||||
s_logger.info("AssignVM: vm " + vm.getInstanceName() + " now belongs to account " + newAccount.getAccountName());
|
||||
return vm;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -690,7 +690,7 @@ public class UserVmManagerTest {
|
|||
|
||||
when(_accountService.getActiveAccountById(anyLong())).thenReturn(oldAccount);
|
||||
|
||||
when(_accountService.getActiveAccountByName(anyString(), anyLong())).thenReturn(newAccount);
|
||||
when(_accountMgr.finalizeOwner(any(Account.class), anyString(), anyLong(), anyLong())).thenReturn(newAccount);
|
||||
|
||||
doThrow(new PermissionDeniedException("Access check failed")).when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class),
|
||||
any(ControlledEntity.class));
|
||||
|
|
|
|||
|
|
@ -1905,7 +1905,32 @@
|
|||
label: 'label.assign.instance.another',
|
||||
createForm: {
|
||||
title: 'label.assign.instance.another',
|
||||
desc: 'Please specify the account type, domain, account name and network (optional) of the new account. <br> If the default nic of the vm is on a shared network, CloudStack will check if the network can be used by the new account if you do not specify one network. <br> If the default nic of the vm is on a isolated network, and the new account has more one isolated networks, you should specify one.',
|
||||
fields: {
|
||||
accountType: {
|
||||
label: 'Account Type',
|
||||
select: function(args) {
|
||||
var items = [];
|
||||
items.push({id: 'account', description: 'Account'});
|
||||
items.push({id: 'project', description: 'Project'});
|
||||
args.response.success({data: items});
|
||||
|
||||
args.$select.change(function() {
|
||||
var $form = $(this).closest('form');
|
||||
var $account = $form.find('.form-item[rel=account]');
|
||||
var $project = $form.find('.form-item[rel=project]');
|
||||
|
||||
var accountType = $(this).val();
|
||||
if (accountType == 'account') { // Account
|
||||
$account.css('display', 'inline-block');
|
||||
$project.hide();
|
||||
} else if (accountType == 'project') { // Project
|
||||
$project.css('display', 'inline-block');
|
||||
$account.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
domainid: {
|
||||
label: 'label.domain',
|
||||
validation: {
|
||||
|
|
@ -1941,20 +1966,203 @@
|
|||
},
|
||||
account: {
|
||||
label: 'label.account',
|
||||
dependsOn: 'domainid',
|
||||
validation: {
|
||||
required: true
|
||||
}
|
||||
}
|
||||
},
|
||||
select: function(args) {
|
||||
var dataObj = {
|
||||
domainId: args.domainid,
|
||||
state: 'Enabled',
|
||||
listAll: true,
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('listAccounts', {
|
||||
ignoreProject: true
|
||||
}),
|
||||
data: dataObj,
|
||||
success: function(json) {
|
||||
accountObjs = json.listaccountsresponse.account;
|
||||
var items = [{
|
||||
id: null,
|
||||
description: ''
|
||||
}];
|
||||
$(accountObjs).each(function() {
|
||||
items.push({
|
||||
id: this.name,
|
||||
description: this.name
|
||||
});
|
||||
})
|
||||
|
||||
args.response.success({
|
||||
data: items
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
project: {
|
||||
label: 'label.project',
|
||||
dependsOn: 'domainid',
|
||||
validation: {
|
||||
required: true
|
||||
},
|
||||
select: function(args) {
|
||||
var dataObj = {
|
||||
domainId: args.domainid,
|
||||
state: 'Active',
|
||||
listAll: true,
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('listProjects', {
|
||||
ignoreProject: true
|
||||
}),
|
||||
data: dataObj,
|
||||
success: function(json) {
|
||||
projectObjs = json.listprojectsresponse.project;
|
||||
var items = [{
|
||||
id: null,
|
||||
description: ''
|
||||
}];
|
||||
$(projectObjs).each(function() {
|
||||
items.push({
|
||||
id: this.id,
|
||||
description: this.name
|
||||
});
|
||||
})
|
||||
|
||||
args.response.success({
|
||||
data: items
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
network: {
|
||||
label: 'label.network',
|
||||
dependsOn: ['accountType', 'domainid', 'account', 'project'],
|
||||
select: function(args) {
|
||||
var dataObj = {
|
||||
domainId: args.domainid,
|
||||
listAll: true,
|
||||
isrecursive: false
|
||||
};
|
||||
if (args.data.accountType == 'account' && args.data.account != null && args.data.account != '') {
|
||||
$.extend(dataObj, {
|
||||
account: args.data.account
|
||||
});
|
||||
} else if (args.data.accountType == 'project' && args.data.project != null && args.data.project != '') {
|
||||
$.extend(dataObj, {
|
||||
projectid: args.data.project
|
||||
});
|
||||
} else {
|
||||
args.response.success({
|
||||
data: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: createURL('listNetworks', {
|
||||
ignoreProject: true
|
||||
}),
|
||||
data: dataObj,
|
||||
success: function(json) {
|
||||
var networkObjs = json.listnetworksresponse.network;
|
||||
var items = [{
|
||||
id: null,
|
||||
description: ''
|
||||
}];
|
||||
$(networkObjs).each(function() {
|
||||
items.push({
|
||||
id: this.id,
|
||||
description: this.name
|
||||
});
|
||||
})
|
||||
|
||||
args.response.success({
|
||||
data: items
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
securitygroup: {
|
||||
label: 'label.security.group',
|
||||
dependsOn: ['accountType', 'domainid', 'account', 'project'],
|
||||
select: function(args) {
|
||||
var dataObj = {
|
||||
domainId: args.domainid,
|
||||
listAll: true,
|
||||
isrecursive: false
|
||||
};
|
||||
if (args.data.accountType == 'account' && args.data.account != null && args.data.account != '') {
|
||||
$.extend(dataObj, {
|
||||
account: args.data.account
|
||||
});
|
||||
} else if (args.data.accountType == 'project' && args.data.project != null && args.data.project != '') {
|
||||
$.extend(dataObj, {
|
||||
projectid: args.data.project
|
||||
});
|
||||
} else {
|
||||
args.response.success({
|
||||
data: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: createURL('listSecurityGroups', {
|
||||
ignoreProject: true
|
||||
}),
|
||||
data: dataObj,
|
||||
success: function(json) {
|
||||
var sgObjs = json.listsecuritygroupsresponse.securitygroup;
|
||||
var items = [{
|
||||
id: null,
|
||||
description: ''
|
||||
}];
|
||||
$(sgObjs).each(function() {
|
||||
items.push({
|
||||
id: this.id,
|
||||
description: this.name
|
||||
});
|
||||
})
|
||||
|
||||
args.response.success({
|
||||
data: items
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('assignVirtualMachine'),
|
||||
data: {
|
||||
virtualmachineid: args.context.instances[0].id,
|
||||
domainid: args.data.domainid,
|
||||
var dataObj = {
|
||||
virtualmachineid: args.context.instances[0].id,
|
||||
domainid: args.data.domainid,
|
||||
};
|
||||
var ignoreProject = false;
|
||||
if (args.data.accountType == 'account') {
|
||||
ignoreProject = true;
|
||||
$.extend(dataObj, {
|
||||
account: args.data.account
|
||||
},
|
||||
});
|
||||
} else if (args.data.accountType == 'project') {
|
||||
$.extend(dataObj, {
|
||||
projectid: args.data.project
|
||||
});
|
||||
}
|
||||
if (args.data.network != null && args.data.network != '') {
|
||||
$.extend(dataObj, {
|
||||
networkIds: args.data.network
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: createURL('assignVirtualMachine', {
|
||||
ignoreProject: ignoreProject
|
||||
}),
|
||||
data: dataObj,
|
||||
success: function(json) {
|
||||
var item = json.assignvirtualmachineresponse.virtualmachine;
|
||||
args.response.success({
|
||||
|
|
|
|||
Loading…
Reference in New Issue