From 3fd17ae0290a632984c6599ac315062b756f1bea Mon Sep 17 00:00:00 2001 From: prachi Date: Fri, 25 May 2012 14:33:22 -0700 Subject: [PATCH] Merge awsapi related changes to CloudStack --- api/src/com/cloud/api/ApiConstants.java | 1 + .../MarkDefaultZoneForAccountCmd.java | 110 ++++++++++++++++++ .../cloud/api/response/AccountResponse.java | 7 ++ .../configuration/ConfigurationService.java | 12 ++ api/src/com/cloud/event/EventTypes.java | 1 + api/src/com/cloud/user/Account.java | 2 + core/src/com/cloud/user/AccountVO.java | 12 ++ .../src/com/cloud/api/ApiResponseHelper.java | 15 +-- .../src/com/cloud/configuration/Config.java | 2 + .../ConfigurationManagerImpl.java | 30 ++++- .../cloud/storage/dao/VMTemplateDaoImpl.java | 9 +- 11 files changed, 187 insertions(+), 14 deletions(-) create mode 100644 api/src/com/cloud/api/commands/MarkDefaultZoneForAccountCmd.java diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index fa6fa4e3c6a..4f73250456f 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -333,6 +333,7 @@ public class ApiConstants { public static final String HA_HOST = "hahost"; public static final String CUSTOM_DISK_OFF_MAX_SIZE = "customdiskofferingmaxsize"; + public static final String DEFAULT_ZONE_ID = "defaultzoneid"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/com/cloud/api/commands/MarkDefaultZoneForAccountCmd.java b/api/src/com/cloud/api/commands/MarkDefaultZoneForAccountCmd.java new file mode 100644 index 00000000000..aa37b22dd7f --- /dev/null +++ b/api/src/com/cloud/api/commands/MarkDefaultZoneForAccountCmd.java @@ -0,0 +1,110 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ApiConstants; +import com.cloud.api.IdentityMapper; +import com.cloud.user.Account; +import com.cloud.event.EventTypes; +import com.cloud.async.AsyncJob; +import com.cloud.api.response.AccountResponse; +import com.cloud.api.ServerApiException; +import com.cloud.api.BaseCmd; + +@Implementation(description="Marks a default zone for this account", responseObject=AccountResponse.class, since="3.0.3") +public class MarkDefaultZoneForAccountCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(MarkDefaultZoneForAccountCmd.class.getName()); + + private static final String s_name = "markdefaultzoneforaccountresponse"; + + ///////////////////////////////////////////////////// + ////////////////API parameters ////////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="account") + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, required=true, description="Name of the account that is to be marked.") + private String accountName; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, required=true, description="Marks the account that belongs to the specified domain.") + private Long domainId; + + @IdentityMapper(entityTableName="data_center") + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="The Zone ID with which the account is to be marked.") + private Long defaultZoneId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + + public Long getDefaultZoneId() { + return defaultZoneId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE; + } + + @Override + public String getEventDescription() { + return "Marking account with the default zone: " + getDefaultZoneId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.Account; + } + + @Override + public void execute(){ + Account result = _configService.markDefaultZone(getAccountName(),getDomainId(), getDefaultZoneId()); + if (result != null) { + AccountResponse response = _responseGenerator.createAccountResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to mark the account with the default zone"); + } + } +} + diff --git a/api/src/com/cloud/api/response/AccountResponse.java b/api/src/com/cloud/api/response/AccountResponse.java index b673bbe759e..016a0e77a64 100755 --- a/api/src/com/cloud/api/response/AccountResponse.java +++ b/api/src/com/cloud/api/response/AccountResponse.java @@ -35,6 +35,9 @@ public class AccountResponse extends BaseResponse { @SerializedName(ApiConstants.DOMAIN) @Param(description="name of the Domain the account belongs too") private String domainName; + + @SerializedName(ApiConstants.DEFAULT_ZONE_ID) @Param(description="the default zone of the account") + private IdentityProxy defaultZoneId = new IdentityProxy("data_center"); @SerializedName(ApiConstants.RECEIVED_BYTES) @Param(description="the total number of network traffic bytes received") private Long bytesReceived; @@ -266,4 +269,8 @@ public class AccountResponse extends BaseResponse { public void setNetworkAvailable(String networkAvailable) { this.networkAvailable = networkAvailable; } + + public void setDefaultZone(Long defaultZoneId) { + this.defaultZoneId.setValue(defaultZoneId); + } } diff --git a/api/src/com/cloud/configuration/ConfigurationService.java b/api/src/com/cloud/configuration/ConfigurationService.java index 87a1f46682b..9d84338bff7 100644 --- a/api/src/com/cloud/configuration/ConfigurationService.java +++ b/api/src/com/cloud/configuration/ConfigurationService.java @@ -30,6 +30,7 @@ import com.cloud.api.commands.DeleteZoneCmd; import com.cloud.api.commands.LDAPConfigCmd; import com.cloud.api.commands.LDAPRemoveCmd; import com.cloud.api.commands.ListNetworkOfferingsCmd; +import com.cloud.api.commands.MarkDefaultZoneForAccountCmd; import com.cloud.api.commands.UpdateCfgCmd; import com.cloud.api.commands.UpdateDiskOfferingCmd; import com.cloud.api.commands.UpdateNetworkOfferingCmd; @@ -216,6 +217,17 @@ public interface ConfigurationService { */ Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException; + /** + * Marks the the account with the default zone-id. + * + * @param accountName + * @param domainId + * @param zoneId + * @return The new account object + * @throws , + */ + Account markDefaultZone(String accountName, long domainId, long defaultZoneId); + boolean deleteVlanIpRange(DeleteVlanIpRangeCmd cmd); NetworkOffering createNetworkOffering(CreateNetworkOfferingCmd cmd); diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 7fab040eee4..a13ff2c2cd7 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -72,6 +72,7 @@ public class EventTypes { public static final String EVENT_ACCOUNT_DISABLE = "ACCOUNT.DISABLE"; public static final String EVENT_ACCOUNT_CREATE = "ACCOUNT.CREATE"; public static final String EVENT_ACCOUNT_DELETE = "ACCOUNT.DELETE"; + public static final String EVENT_ACCOUNT_MARK_DEFAULT_ZONE = "ACCOUNT.MARK.DEFAULT.ZONE"; // UserVO Events public static final String EVENT_USER_LOGIN = "USER.LOGIN"; diff --git a/api/src/com/cloud/user/Account.java b/api/src/com/cloud/user/Account.java index 6d9776b6704..9b581dd24b5 100755 --- a/api/src/com/cloud/user/Account.java +++ b/api/src/com/cloud/user/Account.java @@ -55,4 +55,6 @@ public interface Account extends ControlledEntity { public Date getRemoved(); public String getNetworkDomain(); + + public Long getDefaultZoneId(); } diff --git a/core/src/com/cloud/user/AccountVO.java b/core/src/com/cloud/user/AccountVO.java index 3ecf9b26de3..b8f3940c370 100644 --- a/core/src/com/cloud/user/AccountVO.java +++ b/core/src/com/cloud/user/AccountVO.java @@ -59,6 +59,9 @@ public class AccountVO implements Account, Identity { @Column(name="uuid") private String uuid; + + @Column(name="default_zone_id") + private Long defaultZoneId = null; public AccountVO() { this.uuid = UUID.randomUUID().toString(); @@ -117,6 +120,15 @@ public class AccountVO implements Account, Identity { public void setDomainId(long domainId) { this.domainId = domainId; } + + @Override + public Long getDefaultZoneId() { + return defaultZoneId; + } + + public void setDefaultZoneId(Long defaultZoneId) { + this.defaultZoneId = defaultZoneId; + } @Override public State getState() { diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 80e2b2dd965..eb64d98512c 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1391,12 +1391,10 @@ public class ApiResponseHelper implements ResponseGenerator { } } - if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - if (userVm.getHypervisorType() != null) { - userVmResponse.setHypervisor(userVm.getHypervisorType().toString()); - } + if (userVm.getHypervisorType() != null) { + userVmResponse.setHypervisor(userVm.getHypervisorType().toString()); } - + if (details.contains(VMDetails.all) || details.contains(VMDetails.tmpl)) { // Template Info VMTemplateVO template = templates.get(userVm.getTemplateId()); @@ -2973,11 +2971,8 @@ public class ApiResponseHelper implements ResponseGenerator { userVmData.setDomainId(userVm.getDomainId()); - Account caller = UserContext.current().getCaller(); - if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - if (userVm.getHypervisorType() != null) { - userVmData.setHypervisor(userVm.getHypervisorType().toString()); - } + if (userVm.getHypervisorType() != null) { + userVmData.setHypervisor(userVm.getHypervisorType().toString()); } if (userVm.getPassword() != null) { diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 5f2d5e4f312..e9d553be74f 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -219,6 +219,8 @@ public enum Config { ElasticLoadBalancerVmNumVcpu("Advanced", ManagementServer.class, Integer.class, "network.loadbalancer.basiczone.elb.vm.vcpu.num", "1", "Number of VCPU for the elastic load balancer vm", null), ElasticLoadBalancerVmGcInterval("Advanced", ManagementServer.class, Integer.class, "network.loadbalancer.basiczone.elb.gc.interval.minutes", "30", "Garbage collection interval to destroy unused ELB vms in minutes. Minimum of 5", null), SortKeyAlgorithm("Advanced", ManagementServer.class, Boolean.class, "sortkey.algorithm", "false", "Sort algorithm for those who use sort key(template, disk offering, service offering, network offering), true means ascending sort while false means descending sort", null), + EnableEC2API("Advanced", ManagementServer.class, Boolean.class, "enable.ec2.api", "false", "enable EC2 API on CloudStack", null), + EnableS3API("Advanced", ManagementServer.class, Boolean.class, "enable.s3.api", "false", "enable Amazon S3 API on CloudStack", null), // Ovm OvmPublicNetwork("Hidden", ManagementServer.class, String.class, "ovm.public.network.device", null, "Specify the public bridge on host for public network", null), diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index ba178efb717..d4891086ffe 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -138,8 +138,8 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.test.IPRangeConfig; import com.cloud.user.Account; -import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; +import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserContext; @@ -3574,6 +3574,34 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } } + @Override + @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the default zone", async=true) + public AccountVO markDefaultZone(String accountName, long domainId, long defaultZoneId) { + + // Check if the account exists + Account account = _accountDao.findEnabledAccount(accountName, domainId); + if (account == null) { + s_logger.error("Unable to find account by name: " + accountName + " in domain " + domainId); + throw new InvalidParameterValueException("Account by name: " + accountName + " doesn't exist in domain " + domainId); + } + + // Don't allow modification of system account + if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { + throw new InvalidParameterValueException("Can not modify system account"); + } + + AccountVO acctForUpdate = _accountDao.findById(account.getId()); + + acctForUpdate.setDefaultZoneId(defaultZoneId); + + if (_accountDao.update(account.getId(), acctForUpdate)) { + UserContext.current().setEventDetails("Default zone id= " + defaultZoneId); + return _accountDao.findById(account.getId()); + } else { + return null; + } + } + // Note: This method will be used for entity name validations in the coming // releases (place holder for now) private void validateEntityName(String str) { diff --git a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 8b640b35ff5..8bd5119a223 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -455,7 +455,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem //String accountId = null; String guestOSJoin = ""; StringBuilder templateHostRefJoin = new StringBuilder(); - String dataCenterJoin = ""; + String dataCenterJoin = "", lpjoin = ""; if (isIso && !hyperType.equals(HypervisorType.None)) { guestOSJoin = " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) "; @@ -468,8 +468,11 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if ((templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) { dataCenterJoin = " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } + if (templateFilter == TemplateFilter.sharedexecutable){ + lpjoin = " INNER JOIN launch_permission lp ON t.id = lp.template_id "; + } - sql += guestOSJoin + templateHostRefJoin + dataCenterJoin; + sql += guestOSJoin + templateHostRefJoin + dataCenterJoin + lpjoin; String whereClause = ""; //All joins have to be made before we start setting the condition settings @@ -552,7 +555,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) { whereClause += " AND t.account_id IN (" + permittedAccountsStr + ")"; } else if (templateFilter == TemplateFilter.sharedexecutable) { - whereClause += " LEFT JOIN launch_permission lp ON t.id = lp.template_id WHERE" + + whereClause += " AND " + " (t.account_id IN (" + permittedAccountsStr + ") OR" + " lp.account_id IN (" + permittedAccountsStr + "))"; } else if (templateFilter == TemplateFilter.executable && !permittedAccounts.isEmpty()) {