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
+

Reply via email to