mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-16 10:32:34 +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 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.ApiCommandResourceType;
|
||||
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.ResponseObject.ResponseView;
|
||||
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.commons.lang3.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.storage.Snapshot;
|
||||
import com.cloud.storage.Volume;
|
||||
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")
|
||||
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 ///////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
@ -217,6 +228,14 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////// API Implementation///////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
@ -232,47 +251,12 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Long volumeId = getVolumeId();
|
||||
Long snapshotId = getSnapshotId();
|
||||
Account callingAccount = CallContext.current().getCallingAccount();
|
||||
if (volumeId != null) {
|
||||
Volume volume = _entityMgr.findById(Volume.class, volumeId);
|
||||
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();
|
||||
ensureAccessCheck(callingAccount);
|
||||
return findAccountIdToUse(callingAccount);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_TEMPLATE_CREATE;
|
||||
@ -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);
|
||||
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