mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-17 11:04:00 +01:00
api: introduce domainid and account parameter in createTemplate API (#8210)
Introduces domainid and account as optional parameter for createTemplate API. It will allow admin to create templates for specified domain belonging to specific account.
This commit is contained in:
parent
cc45bffdbd
commit
0735b91037
@ -21,18 +21,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
|
||||||
import org.apache.cloudstack.api.response.GuestOSResponse;
|
|
||||||
import org.apache.cloudstack.api.response.SnapshotResponse;
|
|
||||||
import org.apache.cloudstack.api.response.TemplateResponse;
|
|
||||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
|
||||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
|
||||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
@ -41,13 +29,23 @@ import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
|||||||
import org.apache.cloudstack.api.Parameter;
|
import org.apache.cloudstack.api.Parameter;
|
||||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||||
import org.apache.cloudstack.api.ServerApiException;
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||||
|
import org.apache.cloudstack.api.response.DomainResponse;
|
||||||
|
import org.apache.cloudstack.api.response.GuestOSResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||||
|
import org.apache.cloudstack.api.response.SnapshotResponse;
|
||||||
|
import org.apache.cloudstack.api.response.TemplateResponse;
|
||||||
|
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||||
|
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.event.EventTypes;
|
import com.cloud.event.EventTypes;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.exception.PermissionDeniedException;
|
import com.cloud.exception.PermissionDeniedException;
|
||||||
import com.cloud.exception.ResourceAllocationException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import com.cloud.projects.Project;
|
|
||||||
import com.cloud.storage.Snapshot;
|
import com.cloud.storage.Snapshot;
|
||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.template.VirtualMachineTemplate;
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
@ -139,6 +137,19 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
|
|||||||
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the zone for the template. Can be specified with snapshot only", since = "4.19.0")
|
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the zone for the template. Can be specified with snapshot only", since = "4.19.0")
|
||||||
private Long zoneId;
|
private Long zoneId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DOMAIN_ID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = DomainResponse.class,
|
||||||
|
description = "an optional domainId. If the account parameter is used, domainId must also be used.",
|
||||||
|
since = "4.19.0")
|
||||||
|
private Long domainId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ACCOUNT,
|
||||||
|
type = CommandType.STRING,
|
||||||
|
description = "an optional accountName. Must be used with domainId.",
|
||||||
|
since = "4.19.0")
|
||||||
|
private String accountName;
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
// ///////////////// Accessors ///////////////////////
|
// ///////////////// Accessors ///////////////////////
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
@ -217,6 +228,14 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
|
|||||||
return zoneId;
|
return zoneId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getDomainId() {
|
||||||
|
return domainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccountName() {
|
||||||
|
return accountName;
|
||||||
|
}
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
// ///////////// API Implementation///////////////////
|
// ///////////// API Implementation///////////////////
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
@ -232,46 +251,11 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getEntityOwnerId() {
|
public long getEntityOwnerId() {
|
||||||
Long volumeId = getVolumeId();
|
|
||||||
Long snapshotId = getSnapshotId();
|
|
||||||
Account callingAccount = CallContext.current().getCallingAccount();
|
Account callingAccount = CallContext.current().getCallingAccount();
|
||||||
if (volumeId != null) {
|
ensureAccessCheck(callingAccount);
|
||||||
Volume volume = _entityMgr.findById(Volume.class, volumeId);
|
return findAccountIdToUse(callingAccount);
|
||||||
if (volume != null) {
|
|
||||||
_accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, volume);
|
|
||||||
} else {
|
|
||||||
throw new InvalidParameterValueException("Unable to find volume by id=" + volumeId);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Snapshot snapshot = _entityMgr.findById(Snapshot.class, snapshotId);
|
|
||||||
if (snapshot != null) {
|
|
||||||
_accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, snapshot);
|
|
||||||
} else {
|
|
||||||
throw new InvalidParameterValueException("Unable to find snapshot by id=" + snapshotId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(projectId != null){
|
|
||||||
final Project project = _projectService.getProject(projectId);
|
|
||||||
if (project != null) {
|
|
||||||
if (project.getState() == Project.State.Active) {
|
|
||||||
Account projectAccount= _accountService.getAccount(project.getProjectAccountId());
|
|
||||||
_accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, projectAccount);
|
|
||||||
return project.getProjectAccountId();
|
|
||||||
} else {
|
|
||||||
final PermissionDeniedException ex =
|
|
||||||
new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
|
|
||||||
" as it's no longer active");
|
|
||||||
ex.addProxyObject(project.getUuid(), "projectId");
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new InvalidParameterValueException("Unable to find project by id");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return callingAccount.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getEventType() {
|
public String getEventType() {
|
||||||
@ -330,4 +314,47 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Performs access check on volume and snapshot for given account
|
||||||
|
* @param account
|
||||||
|
*/
|
||||||
|
private void ensureAccessCheck(Account account) {
|
||||||
|
if (volumeId != null) {
|
||||||
|
Volume volume = _entityMgr.findById(Volume.class, volumeId);
|
||||||
|
if (volume != null) {
|
||||||
|
_accountService.checkAccess(account, SecurityChecker.AccessType.UseEntry, false, volume);
|
||||||
|
} else {
|
||||||
|
throw new InvalidParameterValueException("Unable to find volume by id=" + volumeId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Snapshot snapshot = _entityMgr.findById(Snapshot.class, snapshotId);
|
||||||
|
if (snapshot != null) {
|
||||||
|
_accountService.checkAccess(account, SecurityChecker.AccessType.UseEntry, false, snapshot);
|
||||||
|
} else {
|
||||||
|
throw new InvalidParameterValueException("Unable to find snapshot by id=" + snapshotId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Find accountId based on accountName and domainId or projectId
|
||||||
|
* if not found, return callingAccountId for further use
|
||||||
|
* @param callingAccount
|
||||||
|
* @return accountId
|
||||||
|
*/
|
||||||
|
private Long findAccountIdToUse(Account callingAccount) {
|
||||||
|
Long accountIdToUse = null;
|
||||||
|
try {
|
||||||
|
accountIdToUse = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
|
||||||
|
} catch (InvalidParameterValueException | PermissionDeniedException ex) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug(String.format("An exception occurred while finalizing account id with accountName, domainId and projectId" +
|
||||||
|
"using callingAccountId=%s", callingAccount.getUuid()), ex);
|
||||||
|
}
|
||||||
|
s_logger.warn("Unable to find accountId associated with accountName=" + accountName + " and domainId="
|
||||||
|
+ domainId + " or projectId=" + projectId + ", using callingAccountId=" + callingAccount.getUuid());
|
||||||
|
}
|
||||||
|
return accountIdToUse != null ? accountIdToUse : callingAccount.getAccountId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,4 +29,20 @@ public class CreateTemplateCmdTest {
|
|||||||
ReflectionTestUtils.setField(cmd, "zoneId", id);
|
ReflectionTestUtils.setField(cmd, "zoneId", id);
|
||||||
Assert.assertEquals(id, cmd.getZoneId());
|
Assert.assertEquals(id, cmd.getZoneId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDomainId() {
|
||||||
|
final CreateTemplateCmd cmd = new CreateTemplateCmd();
|
||||||
|
Long id = 2L;
|
||||||
|
ReflectionTestUtils.setField(cmd, "domainId", id);
|
||||||
|
Assert.assertEquals(id, cmd.getDomainId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAccountName() {
|
||||||
|
final CreateTemplateCmd cmd = new CreateTemplateCmd();
|
||||||
|
String accountName = "user1";
|
||||||
|
ReflectionTestUtils.setField(cmd, "accountName", accountName);
|
||||||
|
Assert.assertEquals(accountName, cmd.getAccountName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user