diff --git a/server/src/com/cloud/api/commands/RegisterIsoCmd.java b/server/src/com/cloud/api/commands/RegisterIsoCmd.java index 8adec4b668d..b197e9ae1cf 100755 --- a/server/src/com/cloud/api/commands/RegisterIsoCmd.java +++ b/server/src/com/cloud/api/commands/RegisterIsoCmd.java @@ -28,6 +28,7 @@ import com.cloud.api.BaseCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; +import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.ListResponse; import com.cloud.api.response.TemplateResponse; import com.cloud.dc.DataCenterVO; @@ -75,8 +76,14 @@ public class RegisterIsoCmd extends BaseCmd { private String url; @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the ID of the zone you wish to register the ISO to.") - private Long zoneId; + private Long zoneId; + + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId. If the account parameter is used, domainId must also be used.") + private Long domainId; + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account name. Must be used with domainId.") + private String accountName; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -113,11 +120,19 @@ public class RegisterIsoCmd extends BaseCmd { return zoneId; } + public Long getDomainId() { + return domainId; + } + + public String getAccountName() { + return accountName; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// - @Override + @Override public String getName() { return s_name; } diff --git a/server/src/com/cloud/api/commands/RegisterTemplateCmd.java b/server/src/com/cloud/api/commands/RegisterTemplateCmd.java index b4eaa941b3c..78814e66fc1 100755 --- a/server/src/com/cloud/api/commands/RegisterTemplateCmd.java +++ b/server/src/com/cloud/api/commands/RegisterTemplateCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.BaseCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; +import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.ListResponse; import com.cloud.api.response.TemplateResponse; import com.cloud.dc.DataCenterVO; @@ -90,6 +91,12 @@ public class RegisterTemplateCmd extends BaseCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the ID of the zone the template is to be hosted on") private Long zoneId; + + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId. If the account parameter is used, domainId must also be used.") + private Long domainId; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional accountName. Must be used with domainId.") + private String accountName; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -143,11 +150,19 @@ public class RegisterTemplateCmd extends BaseCmd { return zoneId; } + public Long getDomainId() { + return domainId; + } + + public String getAccountName() { + return accountName; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// - @Override + @Override public String getName() { return s_name; } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 2c35646ead5..84f5d8618ba 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -159,7 +159,7 @@ public class TemplateManagerImpl implements TemplateManager { @Override public VMTemplateVO registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException{ - Account account = UserContext.current().getAccount(); + Account ctxAccount = UserContext.current().getAccount(); Long userId = UserContext.current().getUserId(); String name = cmd.getIsoName(); String displayText = cmd.getDisplayText(); @@ -169,28 +169,50 @@ public class TemplateManagerImpl implements TemplateManager { Long guestOSId = cmd.getOsTypeId(); Boolean bootable = cmd.isBootable(); Long zoneId = cmd.getZoneId(); - + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + Account resourceAccount = null; + Long accountId = null; + if (isPublic == null) { isPublic = Boolean.FALSE; } if (zoneId.longValue() == -1) { zoneId = null; + } + + if ( (accountName == null) ^ (domainId == null) ){// XOR - Both have to be passed or don't pass any of them + throw new InvalidParameterValueException("Please specify both account and domainId or dont specify any of them"); } - long accountId = 1L; // default to system account - if (account != null) { - accountId = account.getId(); - } - - Account accountObj; - if (account == null) { - accountObj = _accountDao.findById(accountId); + if ((ctxAccount == null) || isAdmin(ctxAccount.getType())) { + if (domainId != null) { + if ((ctxAccount != null) && !_domainDao.isChildDomain(ctxAccount.getDomainId(), domainId)) { + throw new PermissionDeniedException("Failed to register ISO, invalid domain id (" + domainId + ") given."); + } + if (accountName != null) { + resourceAccount = _accountDao.findActiveAccount(accountName, domainId); + if (resourceAccount == null) { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + accountId = resourceAccount.getId(); + } + } else { + accountId = ((ctxAccount != null) ? ctxAccount.getId() : null); + } } else { - accountObj = account; + accountId = ctxAccount.getId(); } - boolean isAdmin = (accountObj.getType() == Account.ACCOUNT_TYPE_ADMIN); + if (null == accountId && null == accountName && null == domainId && null == ctxAccount){ + accountId = 1L; + } + if (accountId == null) { + throw new InvalidParameterValueException("No valid account specified for registering an ISO."); + } + + boolean isAdmin = _accountDao.findById(accountId).getType() == Account.ACCOUNT_TYPE_ADMIN; if (!isAdmin && zoneId == null) { throw new ServerApiException(BaseCmd.PARAM_ERROR, "Please specify a valid zone Id."); @@ -224,13 +246,13 @@ public class TemplateManagerImpl implements TemplateManager { throw new ServerApiException(BaseCmd.PARAM_ERROR, "File:// type urls are currently unsupported"); } - return createTemplateOrIso(userId, zoneId, name, displayText, isPublic.booleanValue(), featured.booleanValue(), ImageFormat.ISO.toString(), null, url, null, true, 64 /*bits*/, false, guestOSId, bootable, HypervisorType.None); + return createTemplateOrIso(userId, accountId, zoneId, name, displayText, isPublic.booleanValue(), featured.booleanValue(), ImageFormat.ISO.toString(), null, url, null, true, 64 /*bits*/, false, guestOSId, bootable, HypervisorType.None); } @Override public VMTemplateVO registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException{ - Account account = UserContext.current().getAccount(); + Account ctxAccount = UserContext.current().getAccount(); Long userId = UserContext.current().getUserId(); String name = cmd.getTemplateName(); String displayText = cmd.getDisplayText(); @@ -244,6 +266,10 @@ public class TemplateManagerImpl implements TemplateManager { Long guestOSId = cmd.getOsTypeId(); Long zoneId = cmd.getZoneId(); HypervisorType hypervisorType = HypervisorType.valueOf(cmd.getHypervisor()); + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + Account resourceAccount = null; + Long accountId = null; //parameters verification if (bits == null) { @@ -262,20 +288,39 @@ public class TemplateManagerImpl implements TemplateManager { if (zoneId.longValue() == -1) { zoneId = null; } - - long accountId = 1L; // default to system account - if (account != null) { - accountId = account.getId(); + + if ( (accountName == null) ^ (domainId == null) ){// XOR - Both have to be passed or don't pass any of them + throw new InvalidParameterValueException("Please specify both account and domainId or dont specify any of them"); } - Account accountObj; - if (account == null) { - accountObj = _accountDao.findById(accountId); + // This complex logic is just for figuring out the template owning account because a user can register templates on other account's behalf. + if ((ctxAccount == null) || isAdmin(ctxAccount.getType())) { + if (domainId != null) { + if ((ctxAccount != null) && !_domainDao.isChildDomain(ctxAccount.getDomainId(), domainId)) { + throw new PermissionDeniedException("Failed to register template, invalid domain id (" + domainId + ") given."); + } + if (accountName != null) { + resourceAccount = _accountDao.findActiveAccount(accountName, domainId); + if (resourceAccount == null) { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + accountId = resourceAccount.getId(); + } + } else { + accountId = ((ctxAccount != null) ? ctxAccount.getId() : null); + } } else { - accountObj = account; + accountId = ctxAccount.getId(); } - boolean isAdmin = (accountObj.getType() == Account.ACCOUNT_TYPE_ADMIN); + if (null == accountId && null == accountName && null == domainId && null == ctxAccount){ + accountId = 1L; + } + if (null == accountId) { + throw new InvalidParameterValueException("No valid account specified for registering template."); + } + + boolean isAdmin = _accountDao.findById(accountId).getType() == Account.ACCOUNT_TYPE_ADMIN; if (!isAdmin && zoneId == null) { throw new ServerApiException(BaseCmd.PARAM_ERROR, "Please specify a valid zone Id."); @@ -306,11 +351,11 @@ public class TemplateManagerImpl implements TemplateManager { userId = Long.valueOf(1); } - return createTemplateOrIso(userId, zoneId, name, displayText, isPublic, featured, format, "ext3", url, null, requiresHVM, bits, passwordEnabled, guestOSId, true, hypervisorType); + return createTemplateOrIso(userId, accountId, zoneId, name, displayText, isPublic, featured, format, "ext3", url, null, requiresHVM, bits, passwordEnabled, guestOSId, true, hypervisorType); } - private VMTemplateVO createTemplateOrIso(long userId, Long zoneId, String name, String displayText, boolean isPublic, boolean featured, String format, String diskType, String url, String chksum, boolean requiresHvm, int bits, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hypervisorType) throws IllegalArgumentException, ResourceAllocationException { + private VMTemplateVO createTemplateOrIso(long userId, Long accountId, Long zoneId, String name, String displayText, boolean isPublic, boolean featured, String format, String diskType, String url, String chksum, boolean requiresHvm, int bits, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hypervisorType) throws IllegalArgumentException, ResourceAllocationException { try { if (name.length() > 32) @@ -354,7 +399,7 @@ public class TemplateManagerImpl implements TemplateManager { if (user == null) { throw new IllegalArgumentException("Unable to find user with id " + userId); } - AccountVO account = _accountDao.findById(user.getAccountId()); + AccountVO account = _accountDao.findById(accountId); if (_accountMgr.resourceLimitExceeded(account, ResourceType.template)) { ResourceAllocationException rae = new ResourceAllocationException("Maximum number of templates and ISOs for account: " + account.getAccountName() + " has been exceeded."); rae.setResourceType("template"); @@ -372,7 +417,7 @@ public class TemplateManagerImpl implements TemplateManager { throw new IllegalArgumentException("Cannot use reserved names for templates"); } - return create(userId, account.getId(), zoneId, name, displayText, isPublic, featured, imgfmt, null, uri, chksum, requiresHvm, bits, enablePassword, guestOSId, bootable, hypervisorType); + return create(userId, accountId, zoneId, name, displayText, isPublic, featured, imgfmt, null, uri, chksum, requiresHvm, bits, enablePassword, guestOSId, bootable, hypervisorType); } catch (URISyntaxException e) { throw new IllegalArgumentException("Invalid URL " + url); }