Repository: cloudstack Updated Branches: refs/heads/master 6a2c18a98 -> 0407fb334
CLOUDSTACK-7847: add max.domain.* in global setting and display domain resources in listDomainsCmd response Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/0407fb33 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/0407fb33 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/0407fb33 Branch: refs/heads/master Commit: 0407fb334f3a79f570217f35636b47076b06d500 Parents: 6a2c18a Author: Wei Zhou <w.z...@tech.leaseweb.com> Authored: Tue Dec 2 11:52:10 2014 +0100 Committer: Wei Zhou <w.z...@tech.leaseweb.com> Committed: Tue Dec 2 11:52:10 2014 +0100 ---------------------------------------------------------------------- .../command/admin/domain/ListDomainsCmd.java | 19 +- .../cloudstack/api/response/DomainResponse.java | 304 ++++++++++- .../apache/cloudstack/query/QueryService.java | 4 + .../spring-engine-schema-core-daos-context.xml | 1 + server/src/com/cloud/api/ApiDBUtils.java | 35 ++ .../com/cloud/api/query/QueryManagerImpl.java | 80 +++ .../com/cloud/api/query/ViewResponseHelper.java | 9 + .../com/cloud/api/query/dao/DomainJoinDao.java | 34 ++ .../cloud/api/query/dao/DomainJoinDaoImpl.java | 199 ++++++++ .../com/cloud/api/query/vo/DomainJoinVO.java | 501 +++++++++++++++++++ server/src/com/cloud/configuration/Config.java | 13 + .../resourcelimit/ResourceLimitManagerImpl.java | 39 +- setup/db/db/schema-450to460.sql | 130 ++++- 13 files changed, 1340 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java index 1942afd..db910f4 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java @@ -16,9 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.admin.domain; -import java.util.ArrayList; -import java.util.List; - import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -28,9 +25,6 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ListResponse; -import com.cloud.domain.Domain; -import com.cloud.utils.Pair; - @APICommand(name = "listDomains", description = "Lists domains and provides detailed information for listed domains", responseObject = DomainResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListDomainsCmd extends BaseListCmd { @@ -86,17 +80,8 @@ public class ListDomainsCmd extends BaseListCmd { } @Override - public void execute() { - Pair<List<? extends Domain>, Integer> result = _domainService.searchForDomains(this); - ListResponse<DomainResponse> response = new ListResponse<DomainResponse>(); - List<DomainResponse> domainResponses = new ArrayList<DomainResponse>(); - for (Domain domain : result.first()) { - DomainResponse domainResponse = _responseGenerator.createDomainResponse(domain); - domainResponse.setObjectName("domain"); - domainResponses.add(domainResponse); - } - - response.setResponses(domainResponses, result.second()); + public void execute(){ + ListResponse<DomainResponse> response = _queryService.searchForDomains(this); response.setResponseName(getCommandName()); this.setResponseObject(response); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/api/src/org/apache/cloudstack/api/response/DomainResponse.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/response/DomainResponse.java b/api/src/org/apache/cloudstack/api/response/DomainResponse.java index 0c0281e..e848759 100644 --- a/api/src/org/apache/cloudstack/api/response/DomainResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DomainResponse.java @@ -26,7 +26,7 @@ import com.cloud.domain.Domain; import com.cloud.serializer.Param; @EntityReference(value = Domain.class) -public class DomainResponse extends BaseResponse { +public class DomainResponse extends BaseResponse implements ResourceLimitAndCountResponse { @SerializedName(ApiConstants.ID) @Param(description = "the ID of the domain") private String id; @@ -59,6 +59,117 @@ public class DomainResponse extends BaseResponse { @Param(description = "the path of the domain") private String path; + @SerializedName(ApiConstants.STATE) @Param(description="the state of the domain") + private String state; + + @SerializedName(ApiConstants.VM_LIMIT) @Param(description="the total number of virtual machines that can be deployed by this domain") + private String vmLimit; + + @SerializedName(ApiConstants.VM_TOTAL) @Param(description="the total number of virtual machines deployed by this domain") + private Long vmTotal; + + @SerializedName(ApiConstants.VM_AVAILABLE) @Param(description="the total number of virtual machines available for this domain to acquire") + private String vmAvailable; + + @SerializedName(ApiConstants.IP_LIMIT) @Param(description="the total number of public ip addresses this domain can acquire") + private String ipLimit; + + @SerializedName(ApiConstants.IP_TOTAL) @Param(description="the total number of public ip addresses allocated for this domain") + private Long ipTotal; + + @SerializedName(ApiConstants.IP_AVAILABLE) @Param(description="the total number of public ip addresses available for this domain to acquire") + private String ipAvailable; + + @SerializedName("volumelimit") @Param(description="the total volume which can be used by this domain") + private String volumeLimit; + + @SerializedName("volumetotal") @Param(description="the total volume being used by this domain") + private Long volumeTotal; + + @SerializedName("volumeavailable") @Param(description="the total volume available for this domain") + private String volumeAvailable; + + @SerializedName("snapshotlimit") @Param(description="the total number of snapshots which can be stored by this domain") + private String snapshotLimit; + + @SerializedName("snapshottotal") @Param(description="the total number of snapshots stored by this domain") + private Long snapshotTotal; + + @SerializedName("snapshotavailable") @Param(description="the total number of snapshots available for this domain") + private String snapshotAvailable; + + @SerializedName("templatelimit") @Param(description="the total number of templates which can be created by this domain") + private String templateLimit; + + @SerializedName("templatetotal") @Param(description="the total number of templates which have been created by this domain") + private Long templateTotal; + + @SerializedName("templateavailable") @Param(description="the total number of templates available to be created by this domain") + private String templateAvailable; + + @SerializedName("projectlimit") @Param(description="the total number of projects the domain can own", since="3.0.1") + private String projectLimit; + + @SerializedName("projecttotal") @Param(description="the total number of projects being administrated by this domain", since="3.0.1") + private Long projectTotal; + + @SerializedName("projectavailable") @Param(description="the total number of projects available for administration by this domain", since="3.0.1") + private String projectAvailable; + + @SerializedName("networklimit") @Param(description="the total number of networks the domain can own", since="3.0.1") + private String networkLimit; + + @SerializedName("networktotal") @Param(description="the total number of networks owned by domain", since="3.0.1") + private Long networkTotal; + + @SerializedName("networkavailable") @Param(description="the total number of networks available to be created for this domain", since="3.0.1") + private String networkAvailable; + + @SerializedName("vpclimit") @Param(description="the total number of vpcs the domain can own", since="4.0.0") + private String vpcLimit; + + @SerializedName("vpctotal") @Param(description="the total number of vpcs owned by domain", since="4.0.0") + private Long vpcTotal; + + @SerializedName("vpcavailable") @Param(description="the total number of vpcs available to be created for this domain", since="4.0.0") + private String vpcAvailable; + + @SerializedName("cpulimit") @Param(description="the total number of cpu cores the domain can own", since="4.2.0") + private String cpuLimit; + + @SerializedName("cputotal") @Param(description="the total number of cpu cores owned by domain", since="4.2.0") + private Long cpuTotal; + + @SerializedName("cpuavailable") @Param(description="the total number of cpu cores available to be created for this domain", since="4.2.0") + private String cpuAvailable; + + @SerializedName("memorylimit") @Param(description="the total memory (in MB) the domain can own", since="4.2.0") + private String memoryLimit; + + @SerializedName("memorytotal") @Param(description="the total memory (in MB) owned by domain", since="4.2.0") + private Long memoryTotal; + + @SerializedName("memoryavailable") @Param(description="the total memory (in MB) available to be created for this domain", since="4.2.0") + private String memoryAvailable; + + @SerializedName("primarystoragelimit") @Param(description="the total primary storage space (in GiB) the domain can own", since="4.2.0") + private String primaryStorageLimit; + + @SerializedName("primarystoragetotal") @Param(description="the total primary storage space (in GiB) owned by domain", since="4.2.0") + private Long primaryStorageTotal; + + @SerializedName("primarystorageavailable") @Param(description="the total primary storage space (in GiB) available to be used for this domain", since="4.2.0") + private String primaryStorageAvailable; + + @SerializedName("secondarystoragelimit") @Param(description="the total secondary storage space (in GiB) the domain can own", since="4.2.0") + private String secondaryStorageLimit; + + @SerializedName("secondarystoragetotal") @Param(description="the total secondary storage space (in GiB) owned by domain", since="4.2.0") + private Long secondaryStorageTotal; + + @SerializedName("secondarystorageavailable") @Param(description="the total secondary storage space (in GiB) available to be used for this domain", since="4.2.0") + private String secondaryStorageAvailable; + public String getId() { return this.id; } @@ -119,4 +230,195 @@ public class DomainResponse extends BaseResponse { this.path = path; } + + @Override + public void setVmLimit(String vmLimit) { + this.vmLimit = vmLimit; + } + + @Override + public void setVmTotal(Long vmTotal) { + this.vmTotal = vmTotal; + } + + @Override + public void setVmAvailable(String vmAvailable) { + this.vmAvailable = vmAvailable; + } + + @Override + public void setIpLimit(String ipLimit) { + this.ipLimit = ipLimit; + } + + @Override + public void setIpTotal(Long ipTotal) { + this.ipTotal = ipTotal; + } + + @Override + public void setIpAvailable(String ipAvailable) { + this.ipAvailable = ipAvailable; + } + + @Override + public void setVolumeLimit(String volumeLimit) { + this.volumeLimit = volumeLimit; + } + + @Override + public void setVolumeTotal(Long volumeTotal) { + this.volumeTotal = volumeTotal; + } + + @Override + public void setVolumeAvailable(String volumeAvailable) { + this.volumeAvailable = volumeAvailable; + } + + @Override + public void setSnapshotLimit(String snapshotLimit) { + this.snapshotLimit = snapshotLimit; + } + + @Override + public void setSnapshotTotal(Long snapshotTotal) { + this.snapshotTotal = snapshotTotal; + } + + @Override + public void setSnapshotAvailable(String snapshotAvailable) { + this.snapshotAvailable = snapshotAvailable; + } + + @Override + public void setTemplateLimit(String templateLimit) { + this.templateLimit = templateLimit; + } + + @Override + public void setTemplateTotal(Long templateTotal) { + this.templateTotal = templateTotal; + } + + @Override + public void setTemplateAvailable(String templateAvailable) { + this.templateAvailable = templateAvailable; + } + + public void setProjectLimit(String projectLimit) { + this.projectLimit = projectLimit; + } + + public void setProjectTotal(Long projectTotal) { + this.projectTotal = projectTotal; + } + + public void setProjectAvailable(String projectAvailable) { + this.projectAvailable = projectAvailable; + } + + @Override + public void setNetworkLimit(String networkLimit) { + this.networkLimit = networkLimit; + } + + @Override + public void setNetworkTotal(Long networkTotal) { + this.networkTotal = networkTotal; + } + + @Override + public void setNetworkAvailable(String networkAvailable) { + this.networkAvailable = networkAvailable; + } + + @Override + public void setVpcLimit(String vpcLimit) { + this.vpcLimit = networkLimit; + } + + @Override + public void setVpcTotal(Long vpcTotal) { + this.vpcTotal = vpcTotal; + } + + @Override + public void setVpcAvailable(String vpcAvailable) { + this.vpcAvailable = vpcAvailable; + } + + @Override + public void setCpuLimit(String cpuLimit) { + this.cpuLimit = cpuLimit; + } + + @Override + public void setCpuTotal(Long cpuTotal) { + this.cpuTotal = cpuTotal; + } + + @Override + public void setCpuAvailable(String cpuAvailable) { + this.cpuAvailable = cpuAvailable; + } + + @Override + public void setMemoryLimit(String memoryLimit) { + this.memoryLimit = memoryLimit; + } + + @Override + public void setMemoryTotal(Long memoryTotal) { + this.memoryTotal = memoryTotal; + } + + @Override + public void setMemoryAvailable(String memoryAvailable) { + this.memoryAvailable = memoryAvailable; + } + + @Override + public void setPrimaryStorageLimit(String primaryStorageLimit) { + this.primaryStorageLimit = primaryStorageLimit; + } + + @Override + public void setPrimaryStorageTotal(Long primaryStorageTotal) { + this.primaryStorageTotal = primaryStorageTotal; + } + + @Override + public void setPrimaryStorageAvailable(String primaryStorageAvailable) { + this.primaryStorageAvailable = primaryStorageAvailable; + } + + @Override + public void setSecondaryStorageLimit(String secondaryStorageLimit) { + this.secondaryStorageLimit = secondaryStorageLimit; + } + + @Override + public void setSecondaryStorageTotal(Long secondaryStorageTotal) { + this.secondaryStorageTotal = secondaryStorageTotal; + } + + @Override + public void setSecondaryStorageAvailable(String secondaryStorageAvailable) { + this.secondaryStorageAvailable = secondaryStorageAvailable; + } + + public void setState(String state) { + this.state = state; + } + + @Override + public void setVmStopped(Integer vmStopped) { + // TODO Auto-generated method stub + } + + @Override + public void setVmRunning(Integer vmRunning) { + // TODO Auto-generated method stub + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/api/src/org/apache/cloudstack/query/QueryService.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java index 0013be8..a39a2d7 100644 --- a/api/src/org/apache/cloudstack/query/QueryService.java +++ b/api/src/org/apache/cloudstack/query/QueryService.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.query; import java.util.List; import org.apache.cloudstack.affinity.AffinityGroupResponse; +import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd; import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd; @@ -48,6 +49,7 @@ import org.apache.cloudstack.api.command.user.zone.ListZonesCmd; import org.apache.cloudstack.api.response.AccountResponse; import org.apache.cloudstack.api.response.AsyncJobResponse; import org.apache.cloudstack.api.response.DiskOfferingResponse; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; @@ -108,6 +110,8 @@ public interface QueryService { public ListResponse<ImageStoreResponse> searchForSecondaryStagingStores(ListSecondaryStagingStoresCmd cmd); + public ListResponse<DomainResponse> searchForDomains(ListDomainsCmd cmd); + public ListResponse<AccountResponse> searchForAccounts(ListAccountsCmd cmd); public ListResponse<AsyncJobResponse> searchForAsyncJobs(ListAsyncJobsCmd cmd); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml ---------------------------------------------------------------------- diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 9dd5571..13f3519 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -143,6 +143,7 @@ <bean id="engineDcDetailsDaoImpl" class="org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DcDetailsDaoImpl" /> <bean id="diskOfferingJoinDaoImpl" class="com.cloud.api.query.dao.DiskOfferingJoinDaoImpl" /> <bean id="domainDaoImpl" class="com.cloud.domain.dao.DomainDaoImpl" /> + <bean id="domainJoinDaoImpl" class="com.cloud.api.query.dao.DomainJoinDaoImpl" /> <bean id="domainRouterDaoImpl" class="com.cloud.vm.dao.DomainRouterDaoImpl" /> <bean id="domainRouterJoinDaoImpl" class="com.cloud.api.query.dao.DomainRouterJoinDaoImpl" /> <bean id="engineClusterDaoImpl" class="org.apache.cloudstack.engine.datacenter.entity.api.db.dao.EngineClusterDaoImpl" /> http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/server/src/com/cloud/api/ApiDBUtils.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index b6eb757..8a6f651 100644 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -37,6 +37,7 @@ import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.response.AccountResponse; import org.apache.cloudstack.api.response.AsyncJobResponse; import org.apache.cloudstack.api.response.DiskOfferingResponse; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostForMigrationResponse; @@ -73,6 +74,7 @@ import com.cloud.api.query.dao.AffinityGroupJoinDao; import com.cloud.api.query.dao.AsyncJobJoinDao; import com.cloud.api.query.dao.DataCenterJoinDao; import com.cloud.api.query.dao.DiskOfferingJoinDao; +import com.cloud.api.query.dao.DomainJoinDao; import com.cloud.api.query.dao.DomainRouterJoinDao; import com.cloud.api.query.dao.HostJoinDao; import com.cloud.api.query.dao.HostTagDao; @@ -95,6 +97,7 @@ import com.cloud.api.query.vo.AffinityGroupJoinVO; import com.cloud.api.query.vo.AsyncJobJoinVO; import com.cloud.api.query.vo.DataCenterJoinVO; import com.cloud.api.query.vo.DiskOfferingJoinVO; +import com.cloud.api.query.vo.DomainJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; @@ -120,6 +123,7 @@ import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ConfigurationService; +import com.cloud.configuration.Resource; import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.ClusterDetailsDao; @@ -327,6 +331,7 @@ public class ApiDBUtils { static DiskOfferingJoinDao s_diskOfferingJoinDao; static DataCenterJoinDao s_dcJoinDao; static DomainDao s_domainDao; + static DomainJoinDao s_domainJoinDao; static DomainRouterDao s_domainRouterDao; static DomainRouterJoinDao s_domainRouterJoinDao; static GuestOSDao s_guestOSDao; @@ -456,6 +461,8 @@ public class ApiDBUtils { @Inject private DomainDao domainDao; @Inject + private DomainJoinDao domainJoinDao; + @Inject private DomainRouterDao domainRouterDao; @Inject private DomainRouterJoinDao domainRouterJoinDao; @@ -666,6 +673,7 @@ public class ApiDBUtils { s_diskOfferingDao = diskOfferingDao; s_diskOfferingJoinDao = diskOfferingJoinDao; s_domainDao = domainDao; + s_domainJoinDao = domainJoinDao; s_domainRouterDao = domainRouterDao; s_domainRouterJoinDao = domainRouterJoinDao; s_guestOSDao = guestOSDao; @@ -803,6 +811,30 @@ public class ApiDBUtils { // Manager methods // // /////////////////////////////////////////////////////////// + public static long findCorrectResourceLimitForDomain(ResourceType type, long domainId) { + DomainVO domain = s_domainDao.findById(domainId); + + if (domain == null) { + return -1; + } + + return s_resourceLimitMgr.findCorrectResourceLimitForDomain(domain, type); + } + + public static long findCorrectResourceLimitForDomain(Long limit, boolean isRootDomain, ResourceType type, long domainId) { + long max = Resource.RESOURCE_UNLIMITED; // if resource limit is not found, then we treat it as unlimited + + // No limits for Root domain + if (isRootDomain) { + return max; + } + if (limit != null) { + return limit.longValue(); + } else { + return findCorrectResourceLimitForDomain(type, domainId); + } + } + public static long findCorrectResourceLimit(ResourceType type, long accountId) { AccountVO account = s_accountDao.findById(accountId); @@ -1774,6 +1806,9 @@ public class ApiDBUtils { return s_imageStoreJoinDao.newImageStoreView(vr); } + public static DomainResponse newDomainResponse(DomainJoinVO ve) { + return s_domainJoinDao.newDomainResponse(ve); + } public static AccountResponse newAccountResponse(ResponseView view, AccountJoinVO ve) { return s_accountJoinDao.newAccountResponse(view, ve); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/server/src/com/cloud/api/query/QueryManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index a0ad0ea..5459423 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -39,6 +39,7 @@ import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; import org.apache.cloudstack.api.ResourceDetail; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin; +import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd; import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd; @@ -73,6 +74,7 @@ import org.apache.cloudstack.api.command.user.zone.ListZonesCmd; import org.apache.cloudstack.api.response.AccountResponse; import org.apache.cloudstack.api.response.AsyncJobResponse; import org.apache.cloudstack.api.response.DiskOfferingResponse; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; @@ -110,6 +112,7 @@ import com.cloud.api.query.dao.AffinityGroupJoinDao; import com.cloud.api.query.dao.AsyncJobJoinDao; import com.cloud.api.query.dao.DataCenterJoinDao; import com.cloud.api.query.dao.DiskOfferingJoinDao; +import com.cloud.api.query.dao.DomainJoinDao; import com.cloud.api.query.dao.DomainRouterJoinDao; import com.cloud.api.query.dao.HostJoinDao; import com.cloud.api.query.dao.HostTagDao; @@ -132,6 +135,7 @@ import com.cloud.api.query.vo.AffinityGroupJoinVO; import com.cloud.api.query.vo.AsyncJobJoinVO; import com.cloud.api.query.vo.DataCenterJoinVO; import com.cloud.api.query.vo.DiskOfferingJoinVO; +import com.cloud.api.query.vo.DomainJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; @@ -232,6 +236,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { private DomainDao _domainDao; @Inject + private DomainJoinDao _domainJoinDao; + + @Inject private UserAccountJoinDao _userAccountJoinDao; @Inject @@ -1830,6 +1837,79 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } @Override + public ListResponse<DomainResponse> searchForDomains(ListDomainsCmd cmd) { + Pair<List<DomainJoinVO>, Integer> result = searchForDomainsInternal(cmd); + ListResponse<DomainResponse> response = new ListResponse<DomainResponse>(); + List<DomainResponse> domainResponses = ViewResponseHelper.createDomainResponse(result.first().toArray( + new DomainJoinVO[result.first().size()])); + response.setResponses(domainResponses, result.second()); + return response; + } + + private Pair<List<DomainJoinVO>, Integer> searchForDomainsInternal(ListDomainsCmd cmd) { + Account caller = CallContext.current().getCallingAccount(); + Long domainId = cmd.getId(); + boolean listAll = cmd.listAll(); + boolean isRecursive = false; + + if (domainId != null) { + Domain domain = _domainDao.findById(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist"); + } + _accountMgr.checkAccess(caller, domain); + } else { + if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { + domainId = caller.getDomainId(); + } + if (listAll) { + isRecursive = true; + } + } + + Filter searchFilter = new Filter(DomainJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + String domainName = cmd.getDomainName(); + Integer level = cmd.getLevel(); + Object keyword = cmd.getKeyword(); + + SearchBuilder<DomainJoinVO> sb = _domainJoinDao.createSearchBuilder(); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.and("level", sb.entity().getLevel(), SearchCriteria.Op.EQ); + sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE); + sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); + + SearchCriteria<DomainJoinVO> sc = sb.create(); + + if (keyword != null) { + SearchCriteria<DomainJoinVO> ssc = _domainJoinDao.createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (domainName != null) { + sc.setParameters("name", domainName); + } + + if (level != null) { + sc.setParameters("level", level); + } + + if (domainId != null) { + if (isRecursive) { + sc.setParameters("path", _domainDao.findById(domainId).getPath() + "%"); + } else { + sc.setParameters("id", domainId); + } + } + + // return only Active domains to the API + sc.setParameters("state", Domain.State.Active); + + return _domainJoinDao.searchAndCount(sc, searchFilter); + } + + @Override public ListResponse<AccountResponse> searchForAccounts(ListAccountsCmd cmd) { Pair<List<AccountJoinVO>, Integer> result = searchForAccountsInternal(cmd); ListResponse<AccountResponse> response = new ListResponse<AccountResponse>(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/server/src/com/cloud/api/query/ViewResponseHelper.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index bec0048..b8bb6ea 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -30,6 +30,7 @@ import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.response.AccountResponse; import org.apache.cloudstack.api.response.AsyncJobResponse; import org.apache.cloudstack.api.response.DiskOfferingResponse; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostForMigrationResponse; @@ -58,6 +59,7 @@ import com.cloud.api.query.vo.AffinityGroupJoinVO; import com.cloud.api.query.vo.AsyncJobJoinVO; import com.cloud.api.query.vo.DataCenterJoinVO; import com.cloud.api.query.vo.DiskOfferingJoinVO; +import com.cloud.api.query.vo.DomainJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; @@ -346,6 +348,13 @@ public class ViewResponseHelper { return new ArrayList<StoragePoolResponse>(vrDataList.values()); } + public static List<DomainResponse> createDomainResponse(DomainJoinVO... domains) { + List<DomainResponse> respList = new ArrayList<DomainResponse>(); + for (DomainJoinVO vt : domains){ + respList.add(ApiDBUtils.newDomainResponse(vt)); + } + return respList; + } public static List<AccountResponse> createAccountResponse(ResponseView view, AccountJoinVO... accounts) { List<AccountResponse> respList = new ArrayList<AccountResponse>(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/server/src/com/cloud/api/query/dao/DomainJoinDao.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/dao/DomainJoinDao.java b/server/src/com/cloud/api/query/dao/DomainJoinDao.java new file mode 100644 index 0000000..e6b9f4c --- /dev/null +++ b/server/src/com/cloud/api/query/dao/DomainJoinDao.java @@ -0,0 +1,34 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.query.dao; + +import org.apache.cloudstack.api.response.DomainResponse; +import org.apache.cloudstack.api.response.ResourceLimitAndCountResponse; + +import com.cloud.api.query.vo.DomainJoinVO; +import com.cloud.domain.Domain; +import com.cloud.utils.db.GenericDao; + +public interface DomainJoinDao extends GenericDao<DomainJoinVO, Long> { + + DomainResponse newDomainResponse(DomainJoinVO vol); + + DomainJoinVO newDomainView(Domain vol); + + void setResourceLimits(DomainJoinVO domain, boolean isRootDomain, ResourceLimitAndCountResponse response); + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java new file mode 100644 index 0000000..dc6b701 --- /dev/null +++ b/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java @@ -0,0 +1,199 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.query.dao; + +import java.util.List; + +import javax.ejb.Local; + +import org.apache.cloudstack.api.response.DomainResponse; +import org.apache.cloudstack.api.response.ResourceLimitAndCountResponse; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.vo.DomainJoinVO; +import com.cloud.configuration.Resource.ResourceType; +import com.cloud.domain.Domain; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Component +@Local(value={DomainJoinDao.class}) +public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implements DomainJoinDao { + public static final Logger s_logger = Logger.getLogger(DomainJoinDaoImpl.class); + + private SearchBuilder<DomainJoinVO> domainIdSearch; + + protected DomainJoinDaoImpl() { + + domainIdSearch = createSearchBuilder(); + domainIdSearch.and("id", domainIdSearch.entity().getId(), SearchCriteria.Op.EQ); + domainIdSearch.done(); + + this._count = "select count(distinct id) from domain_view WHERE "; + } + + @Override + public DomainResponse newDomainResponse(DomainJoinVO domain) { + DomainResponse domainResponse = new DomainResponse(); + domainResponse.setDomainName(domain.getName()); + domainResponse.setId(domain.getUuid()); + domainResponse.setLevel(domain.getLevel()); + domainResponse.setNetworkDomain(domain.getNetworkDomain()); + Domain parentDomain = ApiDBUtils.findDomainById(domain.getParent()); + if (parentDomain != null) { + domainResponse.setParentDomainId(parentDomain.getUuid()); + } + StringBuilder domainPath = new StringBuilder("ROOT"); + (domainPath.append(domain.getPath())).deleteCharAt(domainPath.length() - 1); + domainResponse.setPath(domainPath.toString()); + if (domain.getParent() != null) { + domainResponse.setParentDomainName(ApiDBUtils.findDomainById(domain.getParent()).getName()); + } + if (domain.getChildCount() > 0) { + domainResponse.setHasChild(true); + } + + domainResponse.setState(domain.getState().toString()); + domainResponse.setNetworkDomain(domain.getNetworkDomain()); + + boolean isRootDomain = (domain.getId() == Domain.ROOT_DOMAIN); + setResourceLimits(domain, isRootDomain, domainResponse); + + //get resource limits for projects + long projectLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getProjectLimit(), isRootDomain, ResourceType.project, domain.getId()); + String projectLimitDisplay = (isRootDomain || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit); + long projectTotal = (domain.getProjectTotal() == null) ? 0 : domain.getProjectTotal(); + String projectAvail = (isRootDomain || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit - projectTotal); + domainResponse.setProjectLimit(projectLimitDisplay); + domainResponse.setProjectTotal(projectTotal); + domainResponse.setProjectAvailable(projectAvail); + + domainResponse.setObjectName("domain"); + + return domainResponse; + } + + @Override + public void setResourceLimits(DomainJoinVO domain, boolean isRootDomain, ResourceLimitAndCountResponse response) { + // Get resource limits and counts + long vmLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getVmLimit(), isRootDomain, ResourceType.user_vm, domain.getId()); + String vmLimitDisplay = (isRootDomain || vmLimit == -1) ? "Unlimited" : String.valueOf(vmLimit); + long vmTotal = (domain.getVmTotal() == null) ? 0 : domain.getVmTotal(); + String vmAvail = (isRootDomain || vmLimit == -1) ? "Unlimited" : String.valueOf(vmLimit - vmTotal); + response.setVmLimit(vmLimitDisplay); + response.setVmTotal(vmTotal); + response.setVmAvailable(vmAvail); + + long ipLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getIpLimit(), isRootDomain, ResourceType.public_ip, domain.getId()); + String ipLimitDisplay = (isRootDomain || ipLimit == -1) ? "Unlimited" : String.valueOf(ipLimit); + long ipTotal = (domain.getIpTotal() == null) ? 0 : domain.getIpTotal(); + String ipAvail = ((isRootDomain || ipLimit == -1)) ? "Unlimited" : String.valueOf(ipLimit - ipTotal); + response.setIpLimit(ipLimitDisplay); + response.setIpTotal(ipTotal); + response.setIpAvailable(ipAvail); + + long volumeLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getVolumeLimit(), isRootDomain, ResourceType.volume, domain.getId()); + String volumeLimitDisplay = (isRootDomain || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit); + long volumeTotal = (domain.getVolumeTotal() == 0) ? 0 : domain.getVolumeTotal(); + String volumeAvail = (isRootDomain || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit - volumeTotal); + response.setVolumeLimit(volumeLimitDisplay); + response.setVolumeTotal(volumeTotal); + response.setVolumeAvailable(volumeAvail); + + long snapshotLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getSnapshotLimit(), isRootDomain, ResourceType.snapshot, domain.getId()); + String snapshotLimitDisplay = (isRootDomain || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit); + long snapshotTotal = (domain.getSnapshotTotal() == null) ? 0 : domain.getSnapshotTotal(); + String snapshotAvail = (isRootDomain || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit - snapshotTotal); + response.setSnapshotLimit(snapshotLimitDisplay); + response.setSnapshotTotal(snapshotTotal); + response.setSnapshotAvailable(snapshotAvail); + + Long templateLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getTemplateLimit(), isRootDomain, ResourceType.template, domain.getId()); + String templateLimitDisplay = (isRootDomain || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit); + Long templateTotal = (domain.getTemplateTotal() == null) ? 0 : domain.getTemplateTotal(); + String templateAvail = (isRootDomain || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit - templateTotal); + response.setTemplateLimit(templateLimitDisplay); + response.setTemplateTotal(templateTotal); + response.setTemplateAvailable(templateAvail); + + //get resource limits for networks + long networkLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getNetworkLimit(), isRootDomain, ResourceType.network, domain.getId()); + String networkLimitDisplay = (isRootDomain || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit); + long networkTotal = (domain.getNetworkTotal() == null) ? 0 : domain.getNetworkTotal(); + String networkAvail = (isRootDomain || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit - networkTotal); + response.setNetworkLimit(networkLimitDisplay); + response.setNetworkTotal(networkTotal); + response.setNetworkAvailable(networkAvail); + + //get resource limits for vpcs + long vpcLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getVpcLimit(), isRootDomain, ResourceType.vpc, domain.getId()); + String vpcLimitDisplay = (isRootDomain || vpcLimit == -1) ? "Unlimited" : String.valueOf(vpcLimit); + long vpcTotal = (domain.getVpcTotal() == null) ? 0 : domain.getVpcTotal(); + String vpcAvail = (isRootDomain || vpcLimit == -1) ? "Unlimited" : String.valueOf(vpcLimit - vpcTotal); + response.setVpcLimit(vpcLimitDisplay); + response.setVpcTotal(vpcTotal); + response.setVpcAvailable(vpcAvail); + + //get resource limits for cpu cores + long cpuLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getCpuLimit(), isRootDomain, ResourceType.cpu, domain.getId()); + String cpuLimitDisplay = (isRootDomain || cpuLimit == -1) ? "Unlimited" : String.valueOf(cpuLimit); + long cpuTotal = (domain.getCpuTotal() == null) ? 0 : domain.getCpuTotal(); + String cpuAvail = (isRootDomain || cpuLimit == -1) ? "Unlimited" : String.valueOf(cpuLimit - cpuTotal); + response.setCpuLimit(cpuLimitDisplay); + response.setCpuTotal(cpuTotal); + response.setCpuAvailable(cpuAvail); + + //get resource limits for memory + long memoryLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getMemoryLimit(), isRootDomain, ResourceType.memory, domain.getId()); + String memoryLimitDisplay = (isRootDomain || memoryLimit == -1) ? "Unlimited" : String.valueOf(memoryLimit); + long memoryTotal = (domain.getMemoryTotal() == null) ? 0 : domain.getMemoryTotal(); + String memoryAvail = (isRootDomain || memoryLimit == -1) ? "Unlimited" : String.valueOf(memoryLimit - memoryTotal); + response.setMemoryLimit(memoryLimitDisplay); + response.setMemoryTotal(memoryTotal); + response.setMemoryAvailable(memoryAvail); + + //get resource limits for primary storage space and convert it from Bytes to GiB + long primaryStorageLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getPrimaryStorageLimit(), isRootDomain, ResourceType.primary_storage, domain.getId()); + String primaryStorageLimitDisplay = (isRootDomain || primaryStorageLimit == -1) ? "Unlimited" : String.valueOf(primaryStorageLimit / ResourceType.bytesToGiB); + long primaryStorageTotal = (domain.getPrimaryStorageTotal() == null) ? 0 : (domain.getPrimaryStorageTotal() / ResourceType.bytesToGiB); + String primaryStorageAvail = (isRootDomain || primaryStorageLimit == -1) ? "Unlimited" : String.valueOf((primaryStorageLimit / ResourceType.bytesToGiB) - primaryStorageTotal); + response.setPrimaryStorageLimit(primaryStorageLimitDisplay); + response.setPrimaryStorageTotal(primaryStorageTotal); + response.setPrimaryStorageAvailable(primaryStorageAvail); + + //get resource limits for secondary storage space and convert it from Bytes to GiB + long secondaryStorageLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getSecondaryStorageLimit(), isRootDomain, ResourceType.secondary_storage, domain.getId()); + String secondaryStorageLimitDisplay = (isRootDomain || secondaryStorageLimit == -1) ? "Unlimited" : String.valueOf(secondaryStorageLimit / ResourceType.bytesToGiB); + long secondaryStorageTotal = (domain.getSecondaryStorageTotal() == null) ? 0 : (domain.getSecondaryStorageTotal() / ResourceType.bytesToGiB); + String secondaryStorageAvail = (isRootDomain || secondaryStorageLimit == -1) ? "Unlimited" : String.valueOf((secondaryStorageLimit / ResourceType.bytesToGiB) - secondaryStorageTotal); + response.setSecondaryStorageLimit(secondaryStorageLimitDisplay); + response.setSecondaryStorageTotal(secondaryStorageTotal); + response.setSecondaryStorageAvailable(secondaryStorageAvail); + } + + @Override + public DomainJoinVO newDomainView(Domain domain) { + SearchCriteria<DomainJoinVO> sc = domainIdSearch.create(); + sc.setParameters("id", domain.getId()); + List<DomainJoinVO> domains = searchIncludingRemoved(sc, null, null, false); + assert domains != null && domains.size() == 1 : "No domain found for domain id " + domain.getId(); + return domains.get(0); + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/server/src/com/cloud/api/query/vo/DomainJoinVO.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/vo/DomainJoinVO.java b/server/src/com/cloud/api/query/vo/DomainJoinVO.java new file mode 100644 index 0000000..a7c4560 --- /dev/null +++ b/server/src/com/cloud/api/query/vo/DomainJoinVO.java @@ -0,0 +1,501 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.query.vo; + +import java.util.Date; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.utils.db.GenericDao; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +@Entity +@Table(name="domain_view") +public class DomainJoinVO extends BaseViewVO implements InternalIdentity, Identity { + + @Id + @Column(name="id") + private long id; + + @Column(name="parent") + private Long parent = null; + + @Column(name="name") + private String name = null; + + @Column(name="owner") + private long accountId; + + @Column(name="path") + private String path = null; + + @Column(name="level") + private int level; + + @Column(name=GenericDao.REMOVED_COLUMN) + private Date removed; + + @Column(name="child_count") + private int childCount = 0; + + @Column(name="next_child_seq") + private long nextChildSeq = 1L; + + @Column(name="state") + private Domain.State state; + + @Column(name="network_domain") + private String networkDomain; + + @Column(name="uuid") + private String uuid; + + + @Column(name="vmLimit") + private Long vmLimit; + + @Column(name="vmTotal") + private Long vmTotal; + + + @Column(name="ipLimit") + private Long ipLimit; + + @Column(name="ipTotal") + private Long ipTotal; + + @Column(name="volumeLimit") + private Long volumeLimit; + + @Column(name="volumeTotal") + private Long volumeTotal; + + @Column(name="snapshotLimit") + private Long snapshotLimit; + + @Column(name="snapshotTotal") + private Long snapshotTotal; + + @Column(name="templateLimit") + private Long templateLimit; + + @Column(name="templateTotal") + private Long templateTotal; + + @Column(name="projectLimit") + private Long projectLimit; + + @Column(name="projectTotal") + private Long projectTotal; + + + @Column(name="networkLimit") + private Long networkLimit; + + @Column(name="networkTotal") + private Long networkTotal; + + + @Column(name="vpcLimit") + private Long vpcLimit; + + @Column(name="vpcTotal") + private Long vpcTotal; + + + @Column(name="cpuLimit") + private Long cpuLimit; + + @Column(name="cpuTotal") + private Long cpuTotal; + + + @Column(name="memoryLimit") + private Long memoryLimit; + + @Column(name="memoryTotal") + private Long memoryTotal; + + + @Column(name="primaryStorageLimit") + private Long primaryStorageLimit; + + @Column(name="primaryStorageTotal") + private Long primaryStorageTotal; + + + @Column(name="secondaryStorageLimit") + private Long secondaryStorageLimit; + + @Column(name="secondaryStorageTotal") + private Long secondaryStorageTotal; + + public DomainJoinVO() { + } + + + @Override + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + @Override + public String getUuid() { + return uuid; + } + + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + + public Long getParent() { + return parent; + } + + public void setParent(Long parent) { + if(parent == null) { + this.parent = DomainVO.ROOT_DOMAIN; + } else { + if(parent.longValue() <= DomainVO.ROOT_DOMAIN) + this.parent = DomainVO.ROOT_DOMAIN; + else + this.parent = parent; + } + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getAccountId() { + return accountId; + } + + public Date getRemoved() { + return removed; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public int getChildCount() { + return childCount; + } + + public void setChildCount(int count) { + childCount = count; + } + + public long getNextChildSeq() { + return nextChildSeq; + } + + public void setNextChildSeq(long seq) { + nextChildSeq = seq; + } + + public Domain.State getState() { + return state; + } + + public void setState(Domain.State state) { + this.state = state; + } + + public String toString() { + return new StringBuilder("Domain:").append(id).append(path).toString(); + } + + public String getNetworkDomain() { + return networkDomain; + } + + public void setNetworkDomain(String domainSuffix) { + this.networkDomain = domainSuffix; + } + + + public Long getVmTotal() { + return vmTotal; + } + + + public void setVmTotal(Long vmTotal) { + this.vmTotal = vmTotal; + } + + + public Long getIpTotal() { + return ipTotal; + } + + + public void setIpTotal(Long ipTotal) { + this.ipTotal = ipTotal; + } + + public Long getVolumeTotal() { + return volumeTotal; + } + + + public void setVolumeTotal(Long volumeTotal) { + this.volumeTotal = volumeTotal; + } + + + + public Long getSnapshotTotal() { + return snapshotTotal; + } + + + public void setSnapshotTotal(Long snapshotTotal) { + this.snapshotTotal = snapshotTotal; + } + + + + + public Long getTemplateTotal() { + return templateTotal; + } + + + public void setTemplateTotal(Long templateTotal) { + this.templateTotal = templateTotal; + } + + + public Long getProjectTotal() { + return projectTotal; + } + + + public void setProjectTotal(Long projectTotal) { + this.projectTotal = projectTotal; + } + + + + public Long getNetworkTotal() { + return networkTotal; + } + + + public void setNetworkTotal(Long networkTotal) { + this.networkTotal = networkTotal; + } + + + public Long getVpcTotal() { + return vpcTotal; + } + + + public void setVpcTotal(Long vpcTotal) { + this.vpcTotal = vpcTotal; + } + + + public Long getCpuTotal() { + return cpuTotal; + } + + + public void setCpuTotal(Long cpuTotal) { + this.cpuTotal = cpuTotal; + } + + + public Long getMemoryTotal() { + return memoryTotal; + } + + + public void setMemoryTotal(Long memoryTotal) { + this.memoryTotal = memoryTotal; + } + + + public Long getPrimaryStorageTotal() { + return primaryStorageTotal; + } + + + public void setPrimaryStorageTotal(Long primaryStorageTotal) { + this.primaryStorageTotal = primaryStorageTotal; + } + + public Long getSecondaryStorageTotal() { + return secondaryStorageTotal; + } + + + public void setSecondaryStorageTotal(Long secondaryStorageTotal) { + this.secondaryStorageTotal = secondaryStorageTotal; + } + + + public Long getVmLimit() { + return vmLimit; + } + + + public void setVmLimit(Long vmLimit) { + this.vmLimit = vmLimit; + } + + + public Long getIpLimit() { + return ipLimit; + } + + + public void setIpLimit(Long ipLimit) { + this.ipLimit = ipLimit; + } + + + public Long getVolumeLimit() { + return volumeLimit; + } + + + public void setVolumeLimit(Long volumeLimit) { + this.volumeLimit = volumeLimit; + } + + + public Long getSnapshotLimit() { + return snapshotLimit; + } + + + public void setSnapshotLimit(Long snapshotLimit) { + this.snapshotLimit = snapshotLimit; + } + + + public Long getTemplateLimit() { + return templateLimit; + } + + + public void setTemplateLimit(Long templateLimit) { + this.templateLimit = templateLimit; + } + + + public Long getProjectLimit() { + return projectLimit; + } + + + public void setProjectLimit(Long projectLimit) { + this.projectLimit = projectLimit; + } + + + public Long getNetworkLimit() { + return networkLimit; + } + + + public void setNetworkLimit(Long networkLimit) { + this.networkLimit = networkLimit; + } + + + public Long getVpcLimit() { + return vpcLimit; + } + + + public void setVpcLimit(Long vpcLimit) { + this.vpcLimit = vpcLimit; + } + + + public Long getCpuLimit() { + return cpuLimit; + } + + + public void setCpuLimit(Long cpuLimit) { + this.cpuLimit = cpuLimit; + } + + + public Long getMemoryLimit() { + return memoryLimit; + } + + + public void setMemoryLimit(Long memoryLimit) { + this.memoryLimit = memoryLimit; + } + + + public Long getPrimaryStorageLimit() { + return primaryStorageLimit; + } + + + public void setPrimaryStorageLimit(Long primaryStorageLimit) { + this.primaryStorageLimit = primaryStorageLimit; + } + + + public Long getSecondaryStorageLimit() { + return secondaryStorageLimit; + } + + + public void setSecondaryStorageLimit(Long secondaryStorageLimit) { + this.secondaryStorageLimit = secondaryStorageLimit; + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/server/src/com/cloud/configuration/Config.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 281d99c..af4da6a 100644 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -1609,6 +1609,18 @@ public enum Config { "Http response content type for .js files (default is text/javascript)", null), + DefaultMaxDomainUserVms("Domain Defaults", ManagementServer.class, Long.class, "max.domain.user.vms", "40", "The default maximum number of user VMs that can be deployed for a domain", null), + DefaultMaxDomainPublicIPs("Domain Defaults", ManagementServer.class, Long.class, "max.domain.public.ips", "40", "The default maximum number of public IPs that can be consumed by a domain", null), + DefaultMaxDomainTemplates("Domain Defaults", ManagementServer.class, Long.class, "max.domain.templates", "40", "The default maximum number of templates that can be deployed for a domain", null), + DefaultMaxDomainSnapshots("Domain Defaults", ManagementServer.class, Long.class, "max.domain.snapshots", "40", "The default maximum number of snapshots that can be created for a domain", null), + DefaultMaxDomainVolumes("Domain Defaults", ManagementServer.class, Long.class, "max.domain.volumes", "40", "The default maximum number of volumes that can be created for a domain", null), + DefaultMaxDomainNetworks("Domain Defaults", ManagementServer.class, Long.class, "max.domain.networks", "40", "The default maximum number of networks that can be created for a domain", null), + DefaultMaxDomainVpcs("Domain Defaults", ManagementServer.class, Long.class, "max.domain.vpcs", "40", "The default maximum number of vpcs that can be created for a domain", null), + DefaultMaxDomainCpus("Domain Defaults", ManagementServer.class, Long.class, "max.domain.cpus", "80", "The default maximum number of cpu cores that can be used for a domain", null), + DefaultMaxDomainMemory("Domain Defaults", ManagementServer.class, Long.class, "max.domain.memory", "81920", "The default maximum memory (in MB) that can be used for a domain", null), + DefaultMaxDomainPrimaryStorage("Domain Defaults", ManagementServer.class, Long.class, "max.domain.primary.storage", "400", "The default maximum primary storage space (in GiB) that can be used for a domain", null), + DefaultMaxDomainSecondaryStorage("Domain Defaults", ManagementServer.class, Long.class, "max.domain.secondary.storage", "800", "The default maximum secondary storage space (in GiB) that can be used for a domain", null), + DefaultMaxProjectUserVms( "Project Defaults", ManagementServer.class, @@ -2097,6 +2109,7 @@ public enum Config { Configs.put("Developer", new ArrayList<Config>()); Configs.put("Hidden", new ArrayList<Config>()); Configs.put("Account Defaults", new ArrayList<Config>()); + Configs.put("Domain Defaults", new ArrayList<Config>()); Configs.put("Project Defaults", new ArrayList<Config>()); Configs.put("Secure", new ArrayList<Config>()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index fd348af..00b76cc 100644 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -164,6 +164,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim ScheduledExecutorService _rcExecutor; long _resourceCountCheckInterval = 0; Map<ResourceType, Long> accountResourceLimitMap = new EnumMap<ResourceType, Long>(ResourceType.class); + Map<ResourceType, Long> domainResourceLimitMap = new EnumMap<ResourceType, Long>(ResourceType.class); Map<ResourceType, Long> projectResourceLimitMap = new EnumMap<ResourceType, Long>(ResourceType.class); @Override @@ -235,6 +236,18 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim accountResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountMemory.key()))); accountResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPrimaryStorage.key()))); accountResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key()))); + + domainResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainPublicIPs.key()))); + domainResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainSnapshots.key()))); + domainResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainTemplates.key()))); + domainResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainUserVms.key()))); + domainResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainVolumes.key()))); + domainResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainNetworks.key()))); + domainResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainVpcs.key()))); + domainResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainCpus.key()))); + domainResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainMemory.key()))); + domainResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainPrimaryStorage.key()))); + domainResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainSecondaryStorage.key()))); } catch (NumberFormatException e) { s_logger.error("NumberFormatException during configuration", e); throw new ConfigurationException("Configuration failed due to NumberFormatException, see log for the stacktrace"); @@ -371,9 +384,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim // check domain hierarchy Long domainId = domain.getParent(); while ((domainId != null) && (limit == null)) { - if (domainId == Domain.ROOT_DOMAIN) { - return Resource.RESOURCE_UNLIMITED; + break; } limit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type); DomainVO tmpDomain = _domainDao.findById(domainId); @@ -382,6 +394,18 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim if (limit != null) { max = limit.getMax().longValue(); + } else { + Long value = null; + value = domainResourceLimitMap.get(type); + if (value != null) { + if (value < 0) { // return unlimit if value is set to negative + return max; + } + if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) { + value = value * ResourceType.bytesToGiB; + } + return value; + } } } @@ -442,13 +466,10 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim DomainVO domain = _domainDao.findById(domainId); // no limit check if it is ROOT domain if (domainId != Domain.ROOT_DOMAIN) { - ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type); - if (domainLimit != null && domainLimit.getMax().longValue() != Resource.RESOURCE_UNLIMITED) { - long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type); - if ((domainCount + numResources) > domainLimit.getMax().longValue()) { - throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + - " has been exceeded.", type); - } + long domainLimit = findCorrectResourceLimitForDomain(domain, type); + long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type) + numResources; + if (domainLimit != Resource.RESOURCE_UNLIMITED && domainCount > domainLimit) { + throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + " has been exceeded.", type); } } domainId = domain.getParent(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0407fb33/setup/db/db/schema-450to460.sql ---------------------------------------------------------------------- diff --git a/setup/db/db/schema-450to460.sql b/setup/db/db/schema-450to460.sql index 8480c85..d207847 100644 --- a/setup/db/db/schema-450to460.sql +++ b/setup/db/db/schema-450to460.sql @@ -19,4 +19,132 @@ -- Schema upgrade from 4.5.0 to 4.6.0 -- -INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "stats.output.uri", "", "URI to additionally send StatsCollector statistics to", "", NULL, NULL, 0); \ No newline at end of file +INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "stats.output.uri", "", "URI to additionally send StatsCollector statistics to", "", NULL, NULL, 0); + +DROP VIEW IF EXISTS `cloud`.`domain_view`; +CREATE VIEW `cloud`.`domain_view` AS + select + domain.id id, + domain.parent parent, + domain.name name, + domain.uuid uuid, + domain.owner owner, + domain.path path, + domain.level level, + domain.child_count child_count, + domain.next_child_seq next_child_seq, + domain.removed removed, + domain.state state, + domain.network_domain network_domain, + domain.type type, + vmlimit.max vmLimit, + vmcount.count vmTotal, + iplimit.max ipLimit, + ipcount.count ipTotal, + volumelimit.max volumeLimit, + volumecount.count volumeTotal, + snapshotlimit.max snapshotLimit, + snapshotcount.count snapshotTotal, + templatelimit.max templateLimit, + templatecount.count templateTotal, + vpclimit.max vpcLimit, + vpccount.count vpcTotal, + projectlimit.max projectLimit, + projectcount.count projectTotal, + networklimit.max networkLimit, + networkcount.count networkTotal, + cpulimit.max cpuLimit, + cpucount.count cpuTotal, + memorylimit.max memoryLimit, + memorycount.count memoryTotal, + primary_storage_limit.max primaryStorageLimit, + primary_storage_count.count primaryStorageTotal, + secondary_storage_limit.max secondaryStorageLimit, + secondary_storage_count.count secondaryStorageTotal + from + `cloud`.`domain` + left join + `cloud`.`resource_limit` vmlimit ON domain.id = vmlimit.domain_id + and vmlimit.type = 'user_vm' + left join + `cloud`.`resource_count` vmcount ON domain.id = vmcount.domain_id + and vmcount.type = 'user_vm' + left join + `cloud`.`resource_limit` iplimit ON domain.id = iplimit.domain_id + and iplimit.type = 'public_ip' + left join + `cloud`.`resource_count` ipcount ON domain.id = ipcount.domain_id + and ipcount.type = 'public_ip' + left join + `cloud`.`resource_limit` volumelimit ON domain.id = volumelimit.domain_id + and volumelimit.type = 'volume' + left join + `cloud`.`resource_count` volumecount ON domain.id = volumecount.domain_id + and volumecount.type = 'volume' + left join + `cloud`.`resource_limit` snapshotlimit ON domain.id = snapshotlimit.domain_id + and snapshotlimit.type = 'snapshot' + left join + `cloud`.`resource_count` snapshotcount ON domain.id = snapshotcount.domain_id + and snapshotcount.type = 'snapshot' + left join + `cloud`.`resource_limit` templatelimit ON domain.id = templatelimit.domain_id + and templatelimit.type = 'template' + left join + `cloud`.`resource_count` templatecount ON domain.id = templatecount.domain_id + and templatecount.type = 'template' + left join + `cloud`.`resource_limit` vpclimit ON domain.id = vpclimit.domain_id + and vpclimit.type = 'vpc' + left join + `cloud`.`resource_count` vpccount ON domain.id = vpccount.domain_id + and vpccount.type = 'vpc' + left join + `cloud`.`resource_limit` projectlimit ON domain.id = projectlimit.domain_id + and projectlimit.type = 'project' + left join + `cloud`.`resource_count` projectcount ON domain.id = projectcount.domain_id + and projectcount.type = 'project' + left join + `cloud`.`resource_limit` networklimit ON domain.id = networklimit.domain_id + and networklimit.type = 'network' + left join + `cloud`.`resource_count` networkcount ON domain.id = networkcount.domain_id + and networkcount.type = 'network' + left join + `cloud`.`resource_limit` cpulimit ON domain.id = cpulimit.domain_id + and cpulimit.type = 'cpu' + left join + `cloud`.`resource_count` cpucount ON domain.id = cpucount.domain_id + and cpucount.type = 'cpu' + left join + `cloud`.`resource_limit` memorylimit ON domain.id = memorylimit.domain_id + and memorylimit.type = 'memory' + left join + `cloud`.`resource_count` memorycount ON domain.id = memorycount.domain_id + and memorycount.type = 'memory' + left join + `cloud`.`resource_limit` primary_storage_limit ON domain.id = primary_storage_limit.domain_id + and primary_storage_limit.type = 'primary_storage' + left join + `cloud`.`resource_count` primary_storage_count ON domain.id = primary_storage_count.domain_id + and primary_storage_count.type = 'primary_storage' + left join + `cloud`.`resource_limit` secondary_storage_limit ON domain.id = secondary_storage_limit.domain_id + and secondary_storage_limit.type = 'secondary_storage' + left join + `cloud`.`resource_count` secondary_storage_count ON domain.id = secondary_storage_count.domain_id + and secondary_storage_count.type = 'secondary_storage'; + +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.user.vms','-1','The default maximum number of user VMs that can be deployed for a domain', '-1', NULL, NULL, 0); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.public.ips','-1','The default maximum number of public IPs that can be consumed by a domain', '-1', NULL, NULL, 0); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.templates','-1','The default maximum number of templates that can be deployed for a domain', '-1', NULL, NULL, 0); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.snapshots','-1','The default maximum number of snapshots that can be created for a domain', '-1', NULL, NULL, 0); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.volumes','-1','The default maximum number of volumes that can be created for a domain', '-1', NULL, NULL, 0); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.networks', '-1', 'The default maximum number of networks that can be created for a domain', '-1', NULL, NULL, 0); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.vpcs', '-1', 'The default maximum number of vpcs that can be created for a domain', '-1', NULL, NULL, 0); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.cpus', '-1', 'The default maximum number of cpu cores that can be used for a domain', '-1', NULL, NULL, 0); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.memory', '-1', 'The default maximum memory (in MiB) that can be used for a domain', '-1', NULL, NULL, 0); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.primary.storage', '-1', 'The default maximum primary storage space (in GiB) that can be used for a domain', '-1', NULL, +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Domain Defaults', 'DEFAULT', 'management-server', 'max.domain.secondary.storage', '-1', 'The default maximum secondary storage space (in GiB) that can be used for a domain', '-1', NU +