mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
api,server,ui: granular resource limit management (#8362)
Feature spec: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Granular+Resource+Limit+Management Introduces the concept of tagged resource limits for granular resource limit management. Limits can be enforced on accounts and domains for the deployment of entities for a tagged resource. Current tagged resource limits can be used for the following resource types, Host limits - user_vm - cpu - memory Storage limits - volume - primary_storage Following global settings can used to specify tags for which limit needs to be enforced, Host: `resource.limit.host.tags` Storage: `resource.limit.storage.tags` Option for specifying tagged resource limits and viewing tagged resource usage are made available in the UI. Enhances the use of templatetag for VM deployment and template creation Adds option to list service/compute offerings that can be used with a given template. A new parameter named templateid has been added. Adds option to list disk offering with suitability flag for a virtual machine. A new parameter named virtualmachineid has been added to the listDiskOfferings API which when passed returns suitableforvirtualmachine param in the response.
This commit is contained in:
parent
6af1c25f52
commit
592038a304
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@ -179,7 +179,8 @@ jobs:
|
|||||||
"component/test_project_usage
|
"component/test_project_usage
|
||||||
component/test_protocol_number_security_group
|
component/test_protocol_number_security_group
|
||||||
component/test_public_ip
|
component/test_public_ip
|
||||||
component/test_resource_limits",
|
component/test_resource_limits
|
||||||
|
component/test_resource_limit_tags",
|
||||||
"component/test_regions_accounts
|
"component/test_regions_accounts
|
||||||
component/test_routers
|
component/test_routers
|
||||||
component/test_snapshots
|
component/test_snapshots
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.capacity;
|
package com.cloud.capacity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.Identity;
|
import org.apache.cloudstack.api.Identity;
|
||||||
import org.apache.cloudstack.api.InternalIdentity;
|
import org.apache.cloudstack.api.InternalIdentity;
|
||||||
|
|
||||||
@ -35,6 +37,11 @@ public interface Capacity extends InternalIdentity, Identity {
|
|||||||
|
|
||||||
public static final short CAPACITY_TYPE_CPU_CORE = 90;
|
public static final short CAPACITY_TYPE_CPU_CORE = 90;
|
||||||
|
|
||||||
|
public static final List<Short> STORAGE_CAPACITY_TYPES = List.of(CAPACITY_TYPE_STORAGE,
|
||||||
|
CAPACITY_TYPE_STORAGE_ALLOCATED,
|
||||||
|
CAPACITY_TYPE_SECONDARY_STORAGE,
|
||||||
|
CAPACITY_TYPE_LOCAL_STORAGE);
|
||||||
|
|
||||||
public Long getHostOrPoolId();
|
public Long getHostOrPoolId();
|
||||||
|
|
||||||
public Long getDataCenterId();
|
public Long getDataCenterId();
|
||||||
@ -54,4 +61,6 @@ public interface Capacity extends InternalIdentity, Identity {
|
|||||||
public Float getUsedPercentage();
|
public Float getUsedPercentage();
|
||||||
|
|
||||||
public Long getAllocatedCapacity();
|
public Long getAllocatedCapacity();
|
||||||
|
|
||||||
|
public String getTag();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,5 +85,6 @@ public interface Resource {
|
|||||||
long getOwnerId();
|
long getOwnerId();
|
||||||
|
|
||||||
ResourceOwnerType getResourceOwnerType();
|
ResourceOwnerType getResourceOwnerType();
|
||||||
|
String getTag();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,8 @@ import com.cloud.utils.fsm.StateObject;
|
|||||||
|
|
||||||
public interface Volume extends ControlledEntity, Identity, InternalIdentity, BasedOn, StateObject<Volume.State>, Displayable {
|
public interface Volume extends ControlledEntity, Identity, InternalIdentity, BasedOn, StateObject<Volume.State>, Displayable {
|
||||||
|
|
||||||
|
static final long DISK_OFFERING_SUITABILITY_CHECK_VOLUME_ID = -1;
|
||||||
|
|
||||||
// Managed storage volume parameters (specified in the compute/disk offering for PowerFlex)
|
// Managed storage volume parameters (specified in the compute/disk offering for PowerFlex)
|
||||||
String BANDWIDTH_LIMIT_IN_MBPS = "bandwidthLimitInMbps";
|
String BANDWIDTH_LIMIT_IN_MBPS = "bandwidthLimitInMbps";
|
||||||
String IOPS_LIMIT = "iopsLimit";
|
String IOPS_LIMIT = "iopsLimit";
|
||||||
|
|||||||
@ -18,13 +18,18 @@ package com.cloud.user;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.response.AccountResponse;
|
||||||
|
import org.apache.cloudstack.api.response.DomainResponse;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource.ResourceType;
|
import com.cloud.configuration.Resource.ResourceType;
|
||||||
import com.cloud.configuration.ResourceCount;
|
import com.cloud.configuration.ResourceCount;
|
||||||
import com.cloud.configuration.ResourceLimit;
|
import com.cloud.configuration.ResourceLimit;
|
||||||
import com.cloud.domain.Domain;
|
import com.cloud.domain.Domain;
|
||||||
import com.cloud.exception.ResourceAllocationException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
import com.cloud.offering.DiskOffering;
|
||||||
import org.apache.cloudstack.user.ResourceReservation;
|
import com.cloud.offering.ServiceOffering;
|
||||||
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
|
|
||||||
public interface ResourceLimitService {
|
public interface ResourceLimitService {
|
||||||
|
|
||||||
@ -34,6 +39,13 @@ public interface ResourceLimitService {
|
|||||||
"The default maximum secondary storage space (in GiB) that can be used for a project", false);
|
"The default maximum secondary storage space (in GiB) that can be used for a project", false);
|
||||||
static final ConfigKey<Long> ResourceCountCheckInterval = new ConfigKey<>("Advanced", Long.class, "resourcecount.check.interval", "300",
|
static final ConfigKey<Long> ResourceCountCheckInterval = new ConfigKey<>("Advanced", Long.class, "resourcecount.check.interval", "300",
|
||||||
"Time (in seconds) to wait before running resource recalculation and fixing task. Default is 300 seconds, Setting this to 0 disables execution of the task", false);
|
"Time (in seconds) to wait before running resource recalculation and fixing task. Default is 300 seconds, Setting this to 0 disables execution of the task", false);
|
||||||
|
static final ConfigKey<String> ResourceLimitHostTags = new ConfigKey<>("Advanced", String.class, "resource.limit.host.tags", "",
|
||||||
|
"A comma-separated list of tags for host resource limits", true);
|
||||||
|
static final ConfigKey<String> ResourceLimitStorageTags = new ConfigKey<>("Advanced", String.class, "resource.limit.storage.tags", "",
|
||||||
|
"A comma-separated list of tags for storage resource limits", true);
|
||||||
|
|
||||||
|
static final List<ResourceType> HostTagsSupportingTypes = List.of(ResourceType.user_vm, ResourceType.cpu, ResourceType.memory);
|
||||||
|
static final List<ResourceType> StorageTagsSupportingTypes = List.of(ResourceType.volume, ResourceType.primary_storage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an existing resource limit with the specified details. If a limit doesn't exist, will create one.
|
* Updates an existing resource limit with the specified details. If a limit doesn't exist, will create one.
|
||||||
@ -46,22 +58,27 @@ public interface ResourceLimitService {
|
|||||||
* TODO
|
* TODO
|
||||||
* @param max
|
* @param max
|
||||||
* TODO
|
* TODO
|
||||||
|
* @param tag
|
||||||
|
* tag for the resource type
|
||||||
*
|
*
|
||||||
* @return the updated/created resource limit
|
* @return the updated/created resource limit
|
||||||
*/
|
*/
|
||||||
ResourceLimit updateResourceLimit(Long accountId, Long domainId, Integer resourceType, Long max);
|
ResourceLimit updateResourceLimit(Long accountId, Long domainId, Integer resourceType, Long max, String tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an existing resource count details for the account/domain
|
* Updates an existing resource count details for the account/domain
|
||||||
*
|
*
|
||||||
* @param accountId
|
* @param accountId
|
||||||
* TODO
|
* Id of the account for which resource recalculation to be done
|
||||||
* @param domainId
|
* @param domainId
|
||||||
* TODO
|
* Id of the domain for which resource recalculation to be doneDO
|
||||||
* @param typeId
|
* @param typeId
|
||||||
* TODO
|
* type of the resource for which recalculation to be done
|
||||||
|
* @param tag
|
||||||
|
* tag for the resource type for which recalculation to be done
|
||||||
* @return the updated/created resource counts
|
* @return the updated/created resource counts
|
||||||
*/
|
*/
|
||||||
|
List<? extends ResourceCount> recalculateResourceCount(Long accountId, Long domainId, Integer typeId, String tag);
|
||||||
List<? extends ResourceCount> recalculateResourceCount(Long accountId, Long domainId, Integer typeId);
|
List<? extends ResourceCount> recalculateResourceCount(Long accountId, Long domainId, Integer typeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +94,7 @@ public interface ResourceLimitService {
|
|||||||
* TODO
|
* TODO
|
||||||
* @return a list of limits that match the criteria
|
* @return a list of limits that match the criteria
|
||||||
*/
|
*/
|
||||||
public List<? extends ResourceLimit> searchForLimits(Long id, Long accountId, Long domainId, ResourceType resourceType, Long startIndex, Long pageSizeVal);
|
public List<? extends ResourceLimit> searchForLimits(Long id, Long accountId, Long domainId, ResourceType resourceType, String tag, Long startIndex, Long pageSizeVal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the resource limit for a specified account and type. If the account has an infinite limit, will check
|
* Finds the resource limit for a specified account and type. If the account has an infinite limit, will check
|
||||||
@ -85,9 +102,10 @@ public interface ResourceLimitService {
|
|||||||
*
|
*
|
||||||
* @param account
|
* @param account
|
||||||
* @param type
|
* @param type
|
||||||
|
* @param tag
|
||||||
* @return resource limit
|
* @return resource limit
|
||||||
*/
|
*/
|
||||||
public long findCorrectResourceLimitForAccount(Account account, ResourceType type);
|
public long findCorrectResourceLimitForAccount(Account account, ResourceType type, String tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This call should be used when we have already queried resource limit for an account. This is to handle
|
* This call should be used when we have already queried resource limit for an account. This is to handle
|
||||||
@ -105,9 +123,10 @@ public interface ResourceLimitService {
|
|||||||
*
|
*
|
||||||
* @param domain
|
* @param domain
|
||||||
* @param type
|
* @param type
|
||||||
|
* @param tag
|
||||||
* @return resource limit
|
* @return resource limit
|
||||||
*/
|
*/
|
||||||
public long findCorrectResourceLimitForDomain(Domain domain, ResourceType type);
|
public long findCorrectResourceLimitForDomain(Domain domain, ResourceType type, String tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the default resource limit for a specified type.
|
* Finds the default resource limit for a specified type.
|
||||||
@ -122,9 +141,10 @@ public interface ResourceLimitService {
|
|||||||
*
|
*
|
||||||
* @param domain
|
* @param domain
|
||||||
* @param type
|
* @param type
|
||||||
|
* @param tag
|
||||||
* @return resource limit
|
* @return resource limit
|
||||||
*/
|
*/
|
||||||
public long findCorrectResourceLimitForAccountAndDomain(Account account, Domain domain, ResourceType type);
|
public long findCorrectResourceLimitForAccountAndDomain(Account account, Domain domain, ResourceType type, String tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments the resource count
|
* Increments the resource count
|
||||||
@ -134,6 +154,7 @@ public interface ResourceLimitService {
|
|||||||
* @param delta
|
* @param delta
|
||||||
*/
|
*/
|
||||||
public void incrementResourceCount(long accountId, ResourceType type, Long... delta);
|
public void incrementResourceCount(long accountId, ResourceType type, Long... delta);
|
||||||
|
public void incrementResourceCountWithTag(long accountId, ResourceType type, String tag, Long... delta);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrements the resource count
|
* Decrements the resource count
|
||||||
@ -143,6 +164,7 @@ public interface ResourceLimitService {
|
|||||||
* @param delta
|
* @param delta
|
||||||
*/
|
*/
|
||||||
public void decrementResourceCount(long accountId, ResourceType type, Long... delta);
|
public void decrementResourceCount(long accountId, ResourceType type, Long... delta);
|
||||||
|
public void decrementResourceCountWithTag(long accountId, ResourceType type, String tag, Long... delta);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a limit has been exceeded for an account
|
* Checks if a limit has been exceeded for an account
|
||||||
@ -155,15 +177,17 @@ public interface ResourceLimitService {
|
|||||||
* @throws ResourceAllocationException
|
* @throws ResourceAllocationException
|
||||||
*/
|
*/
|
||||||
public void checkResourceLimit(Account account, ResourceCount.ResourceType type, long... count) throws ResourceAllocationException;
|
public void checkResourceLimit(Account account, ResourceCount.ResourceType type, long... count) throws ResourceAllocationException;
|
||||||
|
public void checkResourceLimitWithTag(Account account, ResourceCount.ResourceType type, String tag, long... count) throws ResourceAllocationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the count of resources for a resource type and account
|
* Gets the count of resources for a resource type and account
|
||||||
*
|
*
|
||||||
* @param account
|
* @param account
|
||||||
* @param type
|
* @param type
|
||||||
|
* @param tag
|
||||||
* @return count of resources
|
* @return count of resources
|
||||||
*/
|
*/
|
||||||
public long getResourceCount(Account account, ResourceType type);
|
public long getResourceCount(Account account, ResourceType type, String tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a limit has been exceeded for an account if displayResource flag is on
|
* Checks if a limit has been exceeded for an account if displayResource flag is on
|
||||||
@ -208,15 +232,25 @@ public interface ResourceLimitService {
|
|||||||
*/
|
*/
|
||||||
void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta);
|
void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta);
|
||||||
|
|
||||||
/**
|
List<String> getResourceLimitHostTags();
|
||||||
* Adds a reservation that will be counted in subsequent calls to {count}getResourceCount{code} until {code}this[code}
|
List<String> getResourceLimitHostTags(ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||||
* is closed. It will create a reservation record that will be counted when resource limits are checked.
|
List<String> getResourceLimitStorageTags();
|
||||||
* @param account The account for which the reservation is.
|
List<String> getResourceLimitStorageTags(DiskOffering diskOffering);
|
||||||
* @param displayResource whether this resource is shown to users at all (if not it is not counted to limits)
|
void updateTaggedResourceLimitsAndCountsForAccounts(List<AccountResponse> responses, String tag);
|
||||||
* @param type resource type
|
void updateTaggedResourceLimitsAndCountsForDomains(List<DomainResponse> responses, String tag);
|
||||||
* @param delta amount to reserve (will not be <+ 0)
|
void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException;
|
||||||
* @return a {code}AutoClosable{Code} object representing the resource the user needs
|
void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||||
*/
|
void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||||
ResourceReservation getReservation(Account account, Boolean displayResource, ResourceType type, Long delta) throws ResourceAllocationException;
|
void incrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||||
|
void decrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||||
|
void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template) throws ResourceAllocationException;
|
||||||
|
void incrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||||
|
void decrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||||
|
void checkVmCpuResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu) throws ResourceAllocationException;
|
||||||
|
void incrementVmCpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu);
|
||||||
|
void decrementVmCpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu);
|
||||||
|
void checkVmMemoryResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory) throws ResourceAllocationException;
|
||||||
|
void incrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory);
|
||||||
|
void decrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -285,6 +285,7 @@ public class ApiConstants {
|
|||||||
public static final String LAST_SERVER_STOP = "lastserverstop";
|
public static final String LAST_SERVER_STOP = "lastserverstop";
|
||||||
public static final String LEVEL = "level";
|
public static final String LEVEL = "level";
|
||||||
public static final String LENGTH = "length";
|
public static final String LENGTH = "length";
|
||||||
|
public static final String LIMIT = "limit";
|
||||||
public static final String LIMIT_CPU_USE = "limitcpuuse";
|
public static final String LIMIT_CPU_USE = "limitcpuuse";
|
||||||
public static final String LIST_HOSTS = "listhosts";
|
public static final String LIST_HOSTS = "listhosts";
|
||||||
public static final String LOCK = "lock";
|
public static final String LOCK = "lock";
|
||||||
@ -380,6 +381,7 @@ public class ApiConstants {
|
|||||||
public static final String RECONNECT = "reconnect";
|
public static final String RECONNECT = "reconnect";
|
||||||
public static final String RECOVER = "recover";
|
public static final String RECOVER = "recover";
|
||||||
public static final String REQUIRES_HVM = "requireshvm";
|
public static final String REQUIRES_HVM = "requireshvm";
|
||||||
|
public static final String RESOURCE_COUNT = "resourcecount";
|
||||||
public static final String RESOURCE_NAME = "resourcename";
|
public static final String RESOURCE_NAME = "resourcename";
|
||||||
public static final String RESOURCE_TYPE = "resourcetype";
|
public static final String RESOURCE_TYPE = "resourcetype";
|
||||||
public static final String RESOURCE_TYPE_NAME = "resourcetypename";
|
public static final String RESOURCE_TYPE_NAME = "resourcetypename";
|
||||||
@ -420,8 +422,9 @@ public class ApiConstants {
|
|||||||
public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
|
public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
|
||||||
public static final String SNAPSHOT_TYPE = "snapshottype";
|
public static final String SNAPSHOT_TYPE = "snapshottype";
|
||||||
public static final String SNAPSHOT_QUIESCEVM = "quiescevm";
|
public static final String SNAPSHOT_QUIESCEVM = "quiescevm";
|
||||||
public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot";
|
|
||||||
public static final String SOURCE_ZONE_ID = "sourcezoneid";
|
public static final String SOURCE_ZONE_ID = "sourcezoneid";
|
||||||
|
public static final String SUITABLE_FOR_VM = "suitableforvirtualmachine";
|
||||||
|
public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot";
|
||||||
public static final String START_DATE = "startdate";
|
public static final String START_DATE = "startdate";
|
||||||
public static final String START_ID = "startid";
|
public static final String START_ID = "startid";
|
||||||
public static final String START_IP = "startip";
|
public static final String START_IP = "startip";
|
||||||
@ -449,6 +452,7 @@ public class ApiConstants {
|
|||||||
public static final String TIMEOUT = "timeout";
|
public static final String TIMEOUT = "timeout";
|
||||||
public static final String TIMEZONE = "timezone";
|
public static final String TIMEZONE = "timezone";
|
||||||
public static final String TIMEZONEOFFSET = "timezoneoffset";
|
public static final String TIMEZONEOFFSET = "timezoneoffset";
|
||||||
|
public static final String TOTAL = "total";
|
||||||
public static final String TOTAL_SUBNETS = "totalsubnets";
|
public static final String TOTAL_SUBNETS = "totalsubnets";
|
||||||
public static final String TYPE = "type";
|
public static final String TYPE = "type";
|
||||||
public static final String TRUST_STORE = "truststore";
|
public static final String TRUST_STORE = "truststore";
|
||||||
@ -719,6 +723,7 @@ public class ApiConstants {
|
|||||||
public static final String POLICY_UUID = "policyuuid";
|
public static final String POLICY_UUID = "policyuuid";
|
||||||
public static final String RULE_UUID = "ruleuuid";
|
public static final String RULE_UUID = "ruleuuid";
|
||||||
public static final String DIRECTION = "direction";
|
public static final String DIRECTION = "direction";
|
||||||
|
public static final String TAGGED_RESOURCES = "taggedresources";
|
||||||
public static final String TAG_UUID = "taguuid";
|
public static final String TAG_UUID = "taguuid";
|
||||||
public static final String TAG_TYPE = "tagtype";
|
public static final String TAG_TYPE = "tagtype";
|
||||||
public static final String TAG_VALUE = "tagvalue";
|
public static final String TAG_VALUE = "tagvalue";
|
||||||
|
|||||||
@ -20,10 +20,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.cloud.server.ResourceIcon;
|
|
||||||
import com.cloud.server.ResourceTag;
|
|
||||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
|
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
|
||||||
@ -33,9 +29,13 @@ import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
|||||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||||
import org.apache.cloudstack.api.response.DomainResponse;
|
import org.apache.cloudstack.api.response.DomainResponse;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
import com.cloud.domain.Domain;
|
import com.cloud.domain.Domain;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
import com.cloud.server.ResourceIcon;
|
||||||
|
import com.cloud.server.ResourceTag;
|
||||||
|
|
||||||
@APICommand(name = "listDomains", description = "Lists domains and provides detailed information for listed domains", responseObject = DomainResponse.class, responseView = ResponseView.Restricted, entityType = {Domain.class},
|
@APICommand(name = "listDomains", description = "Lists domains and provides detailed information for listed domains", responseObject = DomainResponse.class, responseView = ResponseView.Restricted, entityType = {Domain.class},
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
@ -71,6 +71,9 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||||||
description = "flag to display the resource icon for domains")
|
description = "flag to display the resource icon for domains")
|
||||||
private Boolean showIcon;
|
private Boolean showIcon;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for resource type to return usage", since = "4.20.0")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -110,10 +113,14 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||||||
return dv;
|
return dv;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getShowIcon() {
|
public boolean getShowIcon() {
|
||||||
return showIcon != null ? showIcon : false;
|
return showIcon != null ? showIcon : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -128,12 +135,17 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||||||
ListResponse<DomainResponse> response = _queryService.searchForDomains(this);
|
ListResponse<DomainResponse> response = _queryService.searchForDomains(this);
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
this.setResponseObject(response);
|
this.setResponseObject(response);
|
||||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
updateDomainResponse(response.getResponses());
|
||||||
updateDomainResponse(response.getResponses());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDomainResponse(List<DomainResponse> response) {
|
protected void updateDomainResponse(List<DomainResponse> response) {
|
||||||
|
if (CollectionUtils.isEmpty(response)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_resourceLimitService.updateTaggedResourceLimitsAndCountsForDomains(response, getTag());
|
||||||
|
if (!getShowIcon()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (DomainResponse domainResponse : response) {
|
for (DomainResponse domainResponse : response) {
|
||||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Domain, domainResponse.getId());
|
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Domain, domainResponse.getId());
|
||||||
if (resourceIcon == null) {
|
if (resourceIcon == null) {
|
||||||
|
|||||||
@ -71,6 +71,9 @@ public class ListCapacityCmd extends BaseListCmd {
|
|||||||
@Parameter(name = ApiConstants.SORT_BY, type = CommandType.STRING, since = "3.0.0", description = "Sort the results. Available values: Usage")
|
@Parameter(name = ApiConstants.SORT_BY, type = CommandType.STRING, since = "3.0.0", description = "Sort the results. Available values: Usage")
|
||||||
private String sortBy;
|
private String sortBy;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for the resource type", since = "4.20.0")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -107,6 +110,10 @@ public class ListCapacityCmd extends BaseListCmd {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import org.apache.cloudstack.api.command.user.UserCmd;
|
|||||||
import org.apache.cloudstack.api.response.AccountResponse;
|
import org.apache.cloudstack.api.response.AccountResponse;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.server.ResourceIcon;
|
import com.cloud.server.ResourceIcon;
|
||||||
@ -73,6 +74,9 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd implements UserC
|
|||||||
description = "flag to display the resource icon for accounts")
|
description = "flag to display the resource icon for accounts")
|
||||||
private Boolean showIcon;
|
private Boolean showIcon;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for resource type to return usage", since = "4.20.0")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -116,10 +120,14 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd implements UserC
|
|||||||
return dv;
|
return dv;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getShowIcon() {
|
public boolean getShowIcon() {
|
||||||
return showIcon != null ? showIcon : false;
|
return showIcon != null ? showIcon : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -134,12 +142,17 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd implements UserC
|
|||||||
ListResponse<AccountResponse> response = _queryService.searchForAccounts(this);
|
ListResponse<AccountResponse> response = _queryService.searchForAccounts(this);
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
setResponseObject(response);
|
setResponseObject(response);
|
||||||
if (response != null && response.getCount() > 0 && getShowIcon()) {
|
updateAccountResponse(response.getResponses());
|
||||||
updateAccountResponse(response.getResponses());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAccountResponse(List<AccountResponse> response) {
|
protected void updateAccountResponse(List<AccountResponse> response) {
|
||||||
|
if (CollectionUtils.isEmpty(response)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_resourceLimitService.updateTaggedResourceLimitsAndCountsForAccounts(response, getTag());
|
||||||
|
if (!getShowIcon()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (AccountResponse accountResponse : response) {
|
for (AccountResponse accountResponse : response) {
|
||||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Account, accountResponse.getObjectId());
|
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Account, accountResponse.getObjectId());
|
||||||
if (resourceIcon == null) {
|
if (resourceIcon == null) {
|
||||||
|
|||||||
@ -16,17 +16,16 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.command.user.offering;
|
package org.apache.cloudstack.api.command.user.offering;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
|
||||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
|
||||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||||
import org.apache.cloudstack.api.Parameter;
|
import org.apache.cloudstack.api.Parameter;
|
||||||
import org.apache.cloudstack.api.BaseCmd.CommandType;
|
|
||||||
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
|
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||||
|
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||||
|
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
|
|
||||||
@APICommand(name = "listDiskOfferings", description = "Lists all available disk offerings.", responseObject = DiskOfferingResponse.class,
|
@APICommand(name = "listDiskOfferings", description = "Lists all available disk offerings.", responseObject = DiskOfferingResponse.class,
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
@ -65,6 +64,13 @@ public class ListDiskOfferingsCmd extends BaseListProjectAndAccountResourcesCmd
|
|||||||
since = "4.19")
|
since = "4.19")
|
||||||
private String storageType;
|
private String storageType;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = UserVmResponse.class,
|
||||||
|
description = "The ID of a virtual machine. Pass this in if you want to see the suitable disk offering that can be used to create and add a disk to the virtual machine. Suitability is returned with suitableforvirtualmachine flag in the response",
|
||||||
|
since = "4.20.0")
|
||||||
|
private Long virtualMachineId;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -93,13 +99,16 @@ public class ListDiskOfferingsCmd extends BaseListProjectAndAccountResourcesCmd
|
|||||||
return storageType;
|
return storageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getVirtualMachineId() {
|
||||||
|
return virtualMachineId;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
|
|
||||||
ListResponse<DiskOfferingResponse> response = _queryService.searchForDiskOfferings(this);
|
ListResponse<DiskOfferingResponse> response = _queryService.searchForDiskOfferings(this);
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
this.setResponseObject(response);
|
this.setResponseObject(response);
|
||||||
|
|||||||
@ -16,15 +16,15 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.command.user.offering;
|
package org.apache.cloudstack.api.command.user.offering;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||||
import org.apache.cloudstack.api.Parameter;
|
import org.apache.cloudstack.api.Parameter;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||||
|
import org.apache.cloudstack.api.response.TemplateResponse;
|
||||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
|
|
||||||
@APICommand(name = "listServiceOfferings", description = "Lists all available service offerings.", responseObject = ServiceOfferingResponse.class,
|
@APICommand(name = "listServiceOfferings", description = "Lists all available service offerings.", responseObject = ServiceOfferingResponse.class,
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
@ -92,6 +92,14 @@ public class ListServiceOfferingsCmd extends BaseListProjectAndAccountResourcesC
|
|||||||
since = "4.19")
|
since = "4.19")
|
||||||
private String storageType;
|
private String storageType;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TEMPLATE_ID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = TemplateResponse.class,
|
||||||
|
description = "The ID of the template that listed offerings must support",
|
||||||
|
since = "4.20.0")
|
||||||
|
private Long templateId;
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -138,6 +146,10 @@ public class ListServiceOfferingsCmd extends BaseListProjectAndAccountResourcesC
|
|||||||
return storageType;
|
return storageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getTemplateId() {
|
||||||
|
return templateId;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -19,8 +19,6 @@ package org.apache.cloudstack.api.command.user.resource;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||||
@ -28,7 +26,9 @@ import org.apache.cloudstack.api.Parameter;
|
|||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
import org.apache.cloudstack.api.response.ResourceLimitResponse;
|
import org.apache.cloudstack.api.response.ResourceLimitResponse;
|
||||||
|
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
import com.cloud.configuration.ResourceLimit;
|
import com.cloud.configuration.ResourceLimit;
|
||||||
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
|
||||||
@APICommand(name = "listResourceLimits", description = "Lists resource limits.", responseObject = ResourceLimitResponse.class,
|
@APICommand(name = "listResourceLimits", description = "Lists resource limits.", responseObject = ResourceLimitResponse.class,
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
@ -72,6 +72,10 @@ public class ListResourceLimitsCmd extends BaseListProjectAndAccountResourcesCmd
|
|||||||
+ "secondary_storage - SecondaryStorage. Total secondary storage space (in GiB) a user can use. ")
|
+ "secondary_storage - SecondaryStorage. Total secondary storage space (in GiB) a user can use. ")
|
||||||
private String resourceTypeName;
|
private String resourceTypeName;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for the resource type", since = "4.20.0")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -88,6 +92,10 @@ public class ListResourceLimitsCmd extends BaseListProjectAndAccountResourcesCmd
|
|||||||
return resourceTypeName;
|
return resourceTypeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -96,7 +104,7 @@ public class ListResourceLimitsCmd extends BaseListProjectAndAccountResourcesCmd
|
|||||||
public void execute() {
|
public void execute() {
|
||||||
List<? extends ResourceLimit> result =
|
List<? extends ResourceLimit> result =
|
||||||
_resourceLimitService.searchForLimits(id, _accountService.finalyzeAccountId(this.getAccountName(), this.getDomainId(), this.getProjectId(), false), this.getDomainId(),
|
_resourceLimitService.searchForLimits(id, _accountService.finalyzeAccountId(this.getAccountName(), this.getDomainId(), this.getProjectId(), false), this.getDomainId(),
|
||||||
getResourceTypeEnum(), this.getStartIndex(), this.getPageSizeVal());
|
getResourceTypeEnum(), getTag(), this.getStartIndex(), this.getPageSizeVal());
|
||||||
ListResponse<ResourceLimitResponse> response = new ListResponse<ResourceLimitResponse>();
|
ListResponse<ResourceLimitResponse> response = new ListResponse<ResourceLimitResponse>();
|
||||||
List<ResourceLimitResponse> limitResponses = new ArrayList<ResourceLimitResponse>();
|
List<ResourceLimitResponse> limitResponses = new ArrayList<ResourceLimitResponse>();
|
||||||
for (ResourceLimit limit : result) {
|
for (ResourceLimit limit : result) {
|
||||||
|
|||||||
@ -75,6 +75,9 @@ public class UpdateResourceCountCmd extends BaseCmd {
|
|||||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Update resource limits for project")
|
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Update resource limits for project")
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for the resource type", since = "4.20.0")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -91,6 +94,10 @@ public class UpdateResourceCountCmd extends BaseCmd {
|
|||||||
return resourceType;
|
return resourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -117,7 +124,7 @@ public class UpdateResourceCountCmd extends BaseCmd {
|
|||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
List<? extends ResourceCount> result =
|
List<? extends ResourceCount> result =
|
||||||
_resourceLimitService.recalculateResourceCount(_accountService.finalyzeAccountId(accountName, domainId, projectId, true), getDomainId(), getResourceType());
|
_resourceLimitService.recalculateResourceCount(_accountService.finalyzeAccountId(accountName, domainId, projectId, true), getDomainId(), getResourceType(), getTag());
|
||||||
|
|
||||||
if ((result != null) && (result.size() > 0)) {
|
if ((result != null) && (result.size() > 0)) {
|
||||||
ListResponse<ResourceCountResponse> response = new ListResponse<ResourceCountResponse>();
|
ListResponse<ResourceCountResponse> response = new ListResponse<ResourceCountResponse>();
|
||||||
@ -125,7 +132,6 @@ public class UpdateResourceCountCmd extends BaseCmd {
|
|||||||
|
|
||||||
for (ResourceCount count : result) {
|
for (ResourceCount count : result) {
|
||||||
ResourceCountResponse resourceCountResponse = _responseGenerator.createResourceCountResponse(count);
|
ResourceCountResponse resourceCountResponse = _responseGenerator.createResourceCountResponse(count);
|
||||||
resourceCountResponse.setObjectName("resourcecount");
|
|
||||||
countResponses.add(resourceCountResponse);
|
countResponses.add(resourceCountResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -70,6 +70,9 @@ public class UpdateResourceLimitCmd extends BaseCmd {
|
|||||||
+ "11 - SecondaryStorage. Total secondary storage space (in GiB) a user can use. ")
|
+ "11 - SecondaryStorage. Total secondary storage space (in GiB) a user can use. ")
|
||||||
private Integer resourceType;
|
private Integer resourceType;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for the resource type", since = "4.20.0")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -82,6 +85,10 @@ public class UpdateResourceLimitCmd extends BaseCmd {
|
|||||||
return domainId;
|
return domainId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getResourceType() {
|
public Integer getResourceType() {
|
||||||
return resourceType;
|
return resourceType;
|
||||||
}
|
}
|
||||||
@ -102,7 +109,7 @@ public class UpdateResourceLimitCmd extends BaseCmd {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
ResourceLimit result = _resourceLimitService.updateResourceLimit(_accountService.finalyzeAccountId(accountName, domainId, projectId, true), getDomainId(), resourceType, max);
|
ResourceLimit result = _resourceLimitService.updateResourceLimit(_accountService.finalyzeAccountId(accountName, domainId, projectId, true), getDomainId(), resourceType, max, getTag());
|
||||||
if (result != null || (result == null && max != null && max.longValue() == -1L)) {
|
if (result != null || (result == null && max != null && max.longValue() == -1L)) {
|
||||||
ResourceLimitResponse response = _responseGenerator.createResourceLimitResponse(result);
|
ResourceLimitResponse response = _responseGenerator.createResourceLimitResponse(result);
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.command.user.template;
|
package org.apache.cloudstack.api.command.user.template;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
@ -44,6 +43,9 @@ public class UpdateTemplateCmd extends BaseUpdateTemplateOrIsoCmd implements Use
|
|||||||
description = "the type of the template. Valid options are: USER/VNF (for all users) and SYSTEM/ROUTING/BUILTIN (for admins only).")
|
description = "the type of the template. Valid options are: USER/VNF (for all users) and SYSTEM/ROUTING/BUILTIN (for admins only).")
|
||||||
private String templateType;
|
private String templateType;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TEMPLATE_TAG, type = CommandType.STRING, description = "the tag for this template.", since = "4.20.0")
|
||||||
|
private String templateTag;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -57,6 +59,10 @@ public class UpdateTemplateCmd extends BaseUpdateTemplateOrIsoCmd implements Use
|
|||||||
return templateType;
|
return templateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTemplateTag() {
|
||||||
|
return templateTag;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -267,6 +267,10 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
|
|||||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||||
ResourceIconResponse icon;
|
ResourceIconResponse icon;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.TAGGED_RESOURCES)
|
||||||
|
@Param(description = "The tagged resource limit and count for the account", since = "4.20.0")
|
||||||
|
List<TaggedResourceLimitAndCountResponse> taggedResources;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getObjectId() {
|
public String getObjectId() {
|
||||||
return id;
|
return id;
|
||||||
@ -545,4 +549,9 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
|
|||||||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTaggedResourceLimitsAndCounts(List<TaggedResourceLimitAndCountResponse> taggedResourceLimitsAndCounts) {
|
||||||
|
this.taggedResources = taggedResourceLimitsAndCounts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,12 +16,11 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.response;
|
package org.apache.cloudstack.api.response;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.BaseResponse;
|
import org.apache.cloudstack.api.BaseResponse;
|
||||||
|
|
||||||
import com.cloud.serializer.Param;
|
import com.cloud.serializer.Param;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
public class CapacityResponse extends BaseResponse {
|
public class CapacityResponse extends BaseResponse {
|
||||||
@SerializedName(ApiConstants.TYPE)
|
@SerializedName(ApiConstants.TYPE)
|
||||||
@ -72,6 +71,10 @@ public class CapacityResponse extends BaseResponse {
|
|||||||
@Param(description = "the percentage of capacity currently in use")
|
@Param(description = "the percentage of capacity currently in use")
|
||||||
private String percentUsed;
|
private String percentUsed;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.TAG)
|
||||||
|
@Param(description = "The tag for the capacity type", since = "4.20.0")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
public Short getCapacityType() {
|
public Short getCapacityType() {
|
||||||
return capacityType;
|
return capacityType;
|
||||||
}
|
}
|
||||||
@ -167,4 +170,8 @@ public class CapacityResponse extends BaseResponse {
|
|||||||
public void setPercentUsed(String percentUsed) {
|
public void setPercentUsed(String percentUsed) {
|
||||||
this.percentUsed = percentUsed;
|
this.percentUsed = percentUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -169,6 +169,10 @@ public class DiskOfferingResponse extends BaseResponseWithAnnotations {
|
|||||||
@Param(description = "additional key/value details tied with this disk offering", since = "4.17")
|
@Param(description = "additional key/value details tied with this disk offering", since = "4.17")
|
||||||
private Map<String, String> details;
|
private Map<String, String> details;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.SUITABLE_FOR_VM)
|
||||||
|
@Param(description = "Returns true if the disk offering is suitable for the given virtual machine for disk creation otherwise false", since = "4.20.0")
|
||||||
|
private Boolean suitableForVm;
|
||||||
|
|
||||||
public Boolean getDisplayOffering() {
|
public Boolean getDisplayOffering() {
|
||||||
return displayOffering;
|
return displayOffering;
|
||||||
}
|
}
|
||||||
@ -391,4 +395,8 @@ public class DiskOfferingResponse extends BaseResponseWithAnnotations {
|
|||||||
public void setDetails(Map<String, String> details) {
|
public void setDetails(Map<String, String> details) {
|
||||||
this.details = details;
|
this.details = details;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSuitableForVm(Boolean suitableForVm) {
|
||||||
|
this.suitableForVm = suitableForVm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import com.cloud.domain.Domain;
|
|||||||
import com.cloud.serializer.Param;
|
import com.cloud.serializer.Param;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@EntityReference(value = Domain.class)
|
@EntityReference(value = Domain.class)
|
||||||
@ -184,6 +185,10 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||||||
@Param(description = "details for the domain")
|
@Param(description = "details for the domain")
|
||||||
private Map<String, String> details;
|
private Map<String, String> details;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.TAGGED_RESOURCES)
|
||||||
|
@Param(description = "The tagged resource limit and count for the domain", since = "4.20.0")
|
||||||
|
List<TaggedResourceLimitAndCountResponse> taggedResources;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
@ -447,4 +452,9 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||||||
public void setDetails(Map<String, String> details) {
|
public void setDetails(Map<String, String> details) {
|
||||||
this.details = details;
|
this.details = details;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTaggedResourceLimitsAndCounts(List<TaggedResourceLimitAndCountResponse> taggedResourceLimitsAndCounts) {
|
||||||
|
this.taggedResources = taggedResourceLimitsAndCounts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -216,6 +216,10 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||||||
@Param(description = "the date this project was created", since = "4.16.0")
|
@Param(description = "the date this project was created", since = "4.16.0")
|
||||||
private Date created;
|
private Date created;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.TAGGED_RESOURCES)
|
||||||
|
@Param(description = "The tagged resource limit and count for the project", since = "4.20.0")
|
||||||
|
List<TaggedResourceLimitAndCountResponse> taggedResources;
|
||||||
|
|
||||||
public void setId(String id) {
|
public void setId(String id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
@ -447,4 +451,9 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||||||
public void setCreated(Date created) {
|
public void setCreated(Date created) {
|
||||||
this.created = created;
|
this.created = created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTaggedResourceLimitsAndCounts(List<TaggedResourceLimitAndCountResponse> taggedResourceLimitsAndCounts) {
|
||||||
|
this.taggedResources = taggedResourceLimitsAndCounts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,13 +16,12 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.response;
|
package org.apache.cloudstack.api.response;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.BaseResponse;
|
import org.apache.cloudstack.api.BaseResponse;
|
||||||
|
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
import com.cloud.serializer.Param;
|
import com.cloud.serializer.Param;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class ResourceCountResponse extends BaseResponse implements ControlledEntityResponse {
|
public class ResourceCountResponse extends BaseResponse implements ControlledEntityResponse {
|
||||||
@ -54,10 +53,14 @@ public class ResourceCountResponse extends BaseResponse implements ControlledEnt
|
|||||||
@Param(description = "resource type name. Values include user_vm, public_ip, volume, snapshot, template, project, network, vpc, cpu, memory, primary_storage, secondary_storage.")
|
@Param(description = "resource type name. Values include user_vm, public_ip, volume, snapshot, template, project, network, vpc, cpu, memory, primary_storage, secondary_storage.")
|
||||||
private String resourceTypeName;
|
private String resourceTypeName;
|
||||||
|
|
||||||
@SerializedName("resourcecount")
|
@SerializedName(ApiConstants.RESOURCE_COUNT)
|
||||||
@Param(description = "resource count")
|
@Param(description = "The resource count")
|
||||||
private long resourceCount;
|
private long resourceCount;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.TAG)
|
||||||
|
@Param(description = "Tag for the resource", since = "4.20.0")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAccountName(String accountName) {
|
public void setAccountName(String accountName) {
|
||||||
this.accountName = accountName;
|
this.accountName = accountName;
|
||||||
@ -92,4 +95,7 @@ public class ResourceCountResponse extends BaseResponse implements ControlledEnt
|
|||||||
this.projectName = projectName;
|
this.projectName = projectName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,8 @@ have limits and resource count **/
|
|||||||
|
|
||||||
package org.apache.cloudstack.api.response;
|
package org.apache.cloudstack.api.response;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface ResourceLimitAndCountResponse {
|
public interface ResourceLimitAndCountResponse {
|
||||||
|
|
||||||
public void setNetworkLimit(String networkLimit);
|
public void setNetworkLimit(String networkLimit);
|
||||||
@ -92,4 +94,6 @@ public interface ResourceLimitAndCountResponse {
|
|||||||
|
|
||||||
public void setVmRunning(Integer vmRunning);
|
public void setVmRunning(Integer vmRunning);
|
||||||
|
|
||||||
|
public void setTaggedResourceLimitsAndCounts(List<TaggedResourceLimitAndCountResponse> taggedResourceLimitsAndCounts);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,15 +16,14 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.response;
|
package org.apache.cloudstack.api.response;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.BaseResponse;
|
import org.apache.cloudstack.api.BaseResponse;
|
||||||
import org.apache.cloudstack.api.EntityReference;
|
import org.apache.cloudstack.api.EntityReference;
|
||||||
|
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
import com.cloud.configuration.ResourceLimit;
|
import com.cloud.configuration.ResourceLimit;
|
||||||
import com.cloud.serializer.Param;
|
import com.cloud.serializer.Param;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
@EntityReference(value = ResourceLimit.class)
|
@EntityReference(value = ResourceLimit.class)
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -61,6 +60,10 @@ public class ResourceLimitResponse extends BaseResponse implements ControlledEnt
|
|||||||
@Param(description = "the project name of the resource limit")
|
@Param(description = "the project name of the resource limit")
|
||||||
private String projectName;
|
private String projectName;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.TAG)
|
||||||
|
@Param(description = "The tag for the resource limit", since = "4.20.0")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAccountName(String accountName) {
|
public void setAccountName(String accountName) {
|
||||||
this.accountName = accountName;
|
this.accountName = accountName;
|
||||||
@ -94,4 +97,8 @@ public class ResourceLimitResponse extends BaseResponse implements ControlledEnt
|
|||||||
public void setProjectId(String projectId) {
|
public void setProjectId(String projectId) {
|
||||||
this.projectId = projectId;
|
this.projectId = projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,86 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.response;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.BaseResponse;
|
||||||
|
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
|
import com.cloud.serializer.Param;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
public class TaggedResourceLimitAndCountResponse extends BaseResponse {
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.RESOURCE_TYPE)
|
||||||
|
@Param(description = "Numerical value for the type of the resource. See the ResourceType for more information on these values.")
|
||||||
|
private Integer resourceType;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.RESOURCE_TYPE_NAME)
|
||||||
|
@Param(description = "Name for the type of the resource")
|
||||||
|
private String resourceTypeName;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.TAG)
|
||||||
|
@Param(description = "The tag for the resource type")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.LIMIT)
|
||||||
|
@Param(description = "The limit for the resource count for the type and tag for the owner")
|
||||||
|
private Long limit;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.TOTAL)
|
||||||
|
@Param(description = "The total amount of the resource for the type and tag that is used by the owner")
|
||||||
|
private Long total;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.AVAILABLE)
|
||||||
|
@Param(description = "The available amount of the resource for the type and tag that is available for the owner")
|
||||||
|
private Long available;
|
||||||
|
|
||||||
|
|
||||||
|
public void setResourceType(Resource.ResourceType resourceType) {
|
||||||
|
this.resourceType = resourceType.getOrdinal();
|
||||||
|
this.resourceTypeName = resourceType.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLimit(Long limit) {
|
||||||
|
this.limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(Long total) {
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvailable(Long available) {
|
||||||
|
this.available = available;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getLimit() {
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTotal() {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAvailable() {
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,9 +18,10 @@
|
|||||||
//
|
//
|
||||||
package org.apache.cloudstack.user;
|
package org.apache.cloudstack.user;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
|
||||||
import org.apache.cloudstack.api.InternalIdentity;
|
import org.apache.cloudstack.api.InternalIdentity;
|
||||||
|
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* an interface defining an {code}AutoClosable{code} reservation object
|
* an interface defining an {code}AutoClosable{code} reservation object
|
||||||
*/
|
*/
|
||||||
@ -33,5 +34,7 @@ ResourceReservation extends InternalIdentity {
|
|||||||
|
|
||||||
Resource.ResourceType getResourceType();
|
Resource.ResourceType getResourceType();
|
||||||
|
|
||||||
|
String getTag();
|
||||||
|
|
||||||
Long getReservedAmount();
|
Long getReservedAmount();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,77 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.command.admin.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.response.DomainResponse;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import com.cloud.user.ResourceLimitService;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ListDomainsCmdTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ResourceLimitService resourceLimitService;
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetShowIcon() {
|
||||||
|
ListDomainsCmd cmd = new ListDomainsCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "showIcon", null);
|
||||||
|
Assert.assertFalse(cmd.getShowIcon());
|
||||||
|
ReflectionTestUtils.setField(cmd, "showIcon", false);
|
||||||
|
Assert.assertFalse(cmd.getShowIcon());
|
||||||
|
ReflectionTestUtils.setField(cmd, "showIcon", true);
|
||||||
|
Assert.assertTrue(cmd.getShowIcon());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTag() {
|
||||||
|
ListDomainsCmd cmd = new ListDomainsCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", null);
|
||||||
|
Assert.assertNull(cmd.getTag());
|
||||||
|
String tag = "ABC";
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", tag);
|
||||||
|
Assert.assertEquals(tag, cmd.getTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateDomainResponseNoDomains() {
|
||||||
|
ListDomainsCmd cmd = new ListDomainsCmd();
|
||||||
|
cmd._resourceLimitService = resourceLimitService;
|
||||||
|
cmd.updateDomainResponse(null);
|
||||||
|
Mockito.verify(resourceLimitService, Mockito.never()).updateTaggedResourceLimitsAndCountsForDomains(Mockito.anyList(), Mockito.anyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateDomainResponseWithDomains() {
|
||||||
|
ListDomainsCmd cmd = new ListDomainsCmd();
|
||||||
|
cmd._resourceLimitService = resourceLimitService;
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", "abc");
|
||||||
|
cmd.updateDomainResponse(List.of(Mockito.mock(DomainResponse.class)));
|
||||||
|
Mockito.verify(resourceLimitService, Mockito.times(1)).updateTaggedResourceLimitsAndCountsForDomains(Mockito.any(), Mockito.any());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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 org.apache.cloudstack.api.command.admin.resource;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
public class ListCapacityCmdTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTag() {
|
||||||
|
ListCapacityCmd cmd = new ListCapacityCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", null);
|
||||||
|
Assert.assertNull(cmd.getTag());
|
||||||
|
String tag = "ABC";
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", tag);
|
||||||
|
Assert.assertEquals(tag, cmd.getTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.command.user.account;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.response.AccountResponse;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import com.cloud.user.ResourceLimitService;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ListAccountsCmdTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ResourceLimitService resourceLimitService;
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetShowIcon() {
|
||||||
|
ListAccountsCmd cmd = new ListAccountsCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "showIcon", null);
|
||||||
|
Assert.assertFalse(cmd.getShowIcon());
|
||||||
|
ReflectionTestUtils.setField(cmd, "showIcon", false);
|
||||||
|
Assert.assertFalse(cmd.getShowIcon());
|
||||||
|
ReflectionTestUtils.setField(cmd, "showIcon", true);
|
||||||
|
Assert.assertTrue(cmd.getShowIcon());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTag() {
|
||||||
|
ListAccountsCmd cmd = new ListAccountsCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", null);
|
||||||
|
Assert.assertNull(cmd.getTag());
|
||||||
|
String tag = "ABC";
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", tag);
|
||||||
|
Assert.assertEquals(tag, cmd.getTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateDomainResponseNoDomains() {
|
||||||
|
ListAccountsCmd cmd = new ListAccountsCmd();
|
||||||
|
cmd._resourceLimitService = resourceLimitService;
|
||||||
|
cmd.updateAccountResponse(null);
|
||||||
|
Mockito.verify(resourceLimitService, Mockito.never()).updateTaggedResourceLimitsAndCountsForAccounts(Mockito.anyList(), Mockito.anyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateDomainResponseWithDomains() {
|
||||||
|
ListAccountsCmd cmd = new ListAccountsCmd();
|
||||||
|
cmd._resourceLimitService = resourceLimitService;
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", "abc");
|
||||||
|
cmd.updateAccountResponse(List.of(Mockito.mock(AccountResponse.class)));
|
||||||
|
Mockito.verify(resourceLimitService, Mockito.times(1)).updateTaggedResourceLimitsAndCountsForAccounts(Mockito.any(), Mockito.any());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.command.user.offering;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ListDiskOfferingsCmdTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetVirtualMachineId() {
|
||||||
|
ListDiskOfferingsCmd cmd = new ListDiskOfferingsCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "virtualMachineId", null);
|
||||||
|
Assert.assertNull(cmd.getVirtualMachineId());
|
||||||
|
Long id = 100L;
|
||||||
|
ReflectionTestUtils.setField(cmd, "virtualMachineId", id);
|
||||||
|
Assert.assertEquals(id, cmd.getVirtualMachineId());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.command.user.offering;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ListServiceOfferingsCmdTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTemplateId() {
|
||||||
|
ListServiceOfferingsCmd cmd = new ListServiceOfferingsCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "templateId", null);
|
||||||
|
Assert.assertNull(cmd.getTemplateId());
|
||||||
|
Long id = 100L;
|
||||||
|
ReflectionTestUtils.setField(cmd, "templateId", id);
|
||||||
|
Assert.assertEquals(id, cmd.getTemplateId());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.command.user.resource;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ListResourceLimitsCmdTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTag() {
|
||||||
|
ListResourceLimitsCmd cmd = new ListResourceLimitsCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", null);
|
||||||
|
Assert.assertNull(cmd.getTag());
|
||||||
|
String tag = "ABC";
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", tag);
|
||||||
|
Assert.assertEquals(tag, cmd.getTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.command.user.resource;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class UpdateResourceCountCmdTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTag() {
|
||||||
|
UpdateResourceCountCmd cmd = new UpdateResourceCountCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", null);
|
||||||
|
Assert.assertNull(cmd.getTag());
|
||||||
|
String tag = "ABC";
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", tag);
|
||||||
|
Assert.assertEquals(tag, cmd.getTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.command.user.resource;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class UpdateResourceLimitCmdTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTag() {
|
||||||
|
UpdateResourceLimitCmd cmd = new UpdateResourceLimitCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", null);
|
||||||
|
Assert.assertNull(cmd.getTag());
|
||||||
|
String tag = "ABC";
|
||||||
|
ReflectionTestUtils.setField(cmd, "tag", tag);
|
||||||
|
Assert.assertEquals(tag, cmd.getTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.command.user.template;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import com.cloud.storage.Storage;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class UpdateTemplateCmdTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTemplateType() {
|
||||||
|
UpdateTemplateCmd cmd = new UpdateTemplateCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "templateType", null);
|
||||||
|
Assert.assertNull(cmd.getTemplateType());
|
||||||
|
String type = Storage.TemplateType.ROUTING.toString();
|
||||||
|
ReflectionTestUtils.setField(cmd, "templateTag", type);
|
||||||
|
Assert.assertEquals(type, cmd.getTemplateTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTemplateTag() {
|
||||||
|
UpdateTemplateCmd cmd = new UpdateTemplateCmd();
|
||||||
|
ReflectionTestUtils.setField(cmd, "templateTag", null);
|
||||||
|
Assert.assertNull(cmd.getTemplateTag());
|
||||||
|
String tag = "ABC";
|
||||||
|
ReflectionTestUtils.setField(cmd, "templateTag", tag);
|
||||||
|
Assert.assertEquals(tag, cmd.getTemplateTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -290,4 +290,6 @@ public interface VirtualMachineManager extends Manager {
|
|||||||
|
|
||||||
HashMap<Long, List<? extends VmNetworkStats>> getVmNetworkStatistics(long hostId, String hostName, Map<Long, ? extends VirtualMachine> vmMap);
|
HashMap<Long, List<? extends VmNetworkStats>> getVmNetworkStatistics(long hostId, String hostName, Map<Long, ? extends VirtualMachine> vmMap);
|
||||||
|
|
||||||
|
Map<Long, Boolean> getDiskOfferingSuitabilityForVm(long vmId, List<Long> diskOfferingIds);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -277,6 +277,8 @@ public interface StorageManager extends StorageService {
|
|||||||
|
|
||||||
CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId);
|
CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId);
|
||||||
|
|
||||||
|
CapacityVO getStoragePoolUsedStats(Long zoneId, Long podId, Long clusterId, List<Long> poolIds);
|
||||||
|
|
||||||
List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, HypervisorType type);
|
List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, HypervisorType type);
|
||||||
|
|
||||||
List<VMInstanceVO> listByStoragePool(long storagePoolId);
|
List<VMInstanceVO> listByStoragePool(long storagePoolId);
|
||||||
@ -303,6 +305,9 @@ public interface StorageManager extends StorageService {
|
|||||||
|
|
||||||
boolean storagePoolHasEnoughIops(List<Pair<Volume, DiskProfile>> volumeDiskProfilePairs, StoragePool pool);
|
boolean storagePoolHasEnoughIops(List<Pair<Volume, DiskProfile>> volumeDiskProfilePairs, StoragePool pool);
|
||||||
|
|
||||||
|
boolean storagePoolHasEnoughIops(Long requestedIops, StoragePool pool);
|
||||||
|
boolean storagePoolHasEnoughSpace(Long size, StoragePool pool);
|
||||||
|
|
||||||
boolean storagePoolHasEnoughSpace(List<Pair<Volume, DiskProfile>> volumeDiskProfilePairs, StoragePool pool);
|
boolean storagePoolHasEnoughSpace(List<Pair<Volume, DiskProfile>> volumeDiskProfilePairs, StoragePool pool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -335,6 +340,8 @@ public interface StorageManager extends StorageService {
|
|||||||
|
|
||||||
boolean isStoragePoolCompliantWithStoragePolicy(List<Pair<Volume, DiskProfile>> volumes, StoragePool pool) throws StorageUnavailableException;
|
boolean isStoragePoolCompliantWithStoragePolicy(List<Pair<Volume, DiskProfile>> volumes, StoragePool pool) throws StorageUnavailableException;
|
||||||
|
|
||||||
|
boolean isStoragePoolCompliantWithStoragePolicy(long diskOfferingId, StoragePool pool) throws StorageUnavailableException;
|
||||||
|
|
||||||
boolean registerHostListener(String providerUuid, HypervisorHostListener listener);
|
boolean registerHostListener(String providerUuid, HypervisorHostListener listener);
|
||||||
|
|
||||||
boolean connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException, StorageConflictException;
|
boolean connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException, StorageConflictException;
|
||||||
|
|||||||
@ -19,6 +19,7 @@ package com.cloud.vm;
|
|||||||
|
|
||||||
import static com.cloud.configuration.ConfigurationManagerImpl.MIGRATE_VM_ACROSS_CLUSTERS;
|
import static com.cloud.configuration.ConfigurationManagerImpl.MIGRATE_VM_ACROSS_CLUSTERS;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@ -148,7 +149,6 @@ import com.cloud.api.query.dao.UserVmJoinDao;
|
|||||||
import com.cloud.api.query.vo.DomainRouterJoinVO;
|
import com.cloud.api.query.vo.DomainRouterJoinVO;
|
||||||
import com.cloud.api.query.vo.UserVmJoinVO;
|
import com.cloud.api.query.vo.UserVmJoinVO;
|
||||||
import com.cloud.capacity.CapacityManager;
|
import com.cloud.capacity.CapacityManager;
|
||||||
import com.cloud.configuration.Resource.ResourceType;
|
|
||||||
import com.cloud.dc.ClusterDetailsDao;
|
import com.cloud.dc.ClusterDetailsDao;
|
||||||
import com.cloud.dc.ClusterDetailsVO;
|
import com.cloud.dc.ClusterDetailsVO;
|
||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
@ -1130,7 +1130,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
// check resource count if ResourceCountRunningVMsonly.value() = true
|
// check resource count if ResourceCountRunningVMsonly.value() = true
|
||||||
final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
|
final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
|
||||||
if (VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
if (VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
||||||
resourceCountIncrement(owner.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
_resourceLimitMgr.incrementVmResourceCount(owner.getAccountId(), vm.isDisplay(), offering, template);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean canRetry = true;
|
boolean canRetry = true;
|
||||||
@ -1438,7 +1438,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
} finally {
|
} finally {
|
||||||
if (startedVm == null) {
|
if (startedVm == null) {
|
||||||
if (VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
if (VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
||||||
resourceCountDecrement(owner.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
_resourceLimitMgr.decrementVmResourceCount(owner.getAccountId(), vm.isDisplay(), offering, template);
|
||||||
}
|
}
|
||||||
if (canRetry) {
|
if (canRetry) {
|
||||||
try {
|
try {
|
||||||
@ -2208,7 +2208,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
if (result) {
|
if (result) {
|
||||||
if (VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
if (VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
||||||
ServiceOfferingVO offering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
|
ServiceOfferingVO offering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
|
||||||
resourceCountDecrement(vm.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||||
|
_resourceLimitMgr.decrementVmResourceCount(vm.getAccountId(), vm.isDisplay(), offering, template);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new CloudRuntimeException("unable to stop " + vm);
|
throw new CloudRuntimeException("unable to stop " + vm);
|
||||||
@ -5605,18 +5606,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
return workJob;
|
return workJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void resourceCountIncrement (long accountId, Long cpu, Long memory) {
|
|
||||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm);
|
|
||||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, cpu);
|
|
||||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void resourceCountDecrement (long accountId, Long cpu, Long memory) {
|
|
||||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm);
|
|
||||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, cpu);
|
|
||||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserVm restoreVirtualMachine(final long vmId, final Long newTemplateId) throws ResourceUnavailableException, InsufficientCapacityException {
|
public UserVm restoreVirtualMachine(final long vmId, final Long newTemplateId) throws ResourceUnavailableException, InsufficientCapacityException {
|
||||||
final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
||||||
@ -6044,4 +6033,48 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
}
|
}
|
||||||
return vmNetworkStatsById;
|
return vmNetworkStatsById;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isDiskOfferingSuitableForVm(VMInstanceVO vm, VirtualMachineProfile profile, long podId, long clusterId, long hostId, long diskOfferingId) {
|
||||||
|
|
||||||
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
|
VolumeVO dummyVolume = new VolumeVO("Data", vm.getDataCenterId(), podId, vm.getAccountId(),
|
||||||
|
vm.getDomainId(), vm.getId(), null, null, diskOffering.getProvisioningType(), diskOffering.getDiskSize(), Type.DATADISK);
|
||||||
|
try {
|
||||||
|
Field idField = dummyVolume.getClass().getDeclaredField("id");
|
||||||
|
idField.setAccessible(true);
|
||||||
|
idField.set(dummyVolume, Volume.DISK_OFFERING_SUITABILITY_CHECK_VOLUME_ID);
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException ignored) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dummyVolume.setDiskOfferingId(diskOfferingId);
|
||||||
|
DiskProfile diskProfile = new DiskProfile(dummyVolume, diskOffering, profile.getHypervisorType());
|
||||||
|
diskProfile.setMinIops(diskOffering.getMinIops());
|
||||||
|
diskProfile.setMaxIops(diskOffering.getMaxIops());
|
||||||
|
ExcludeList avoid = new ExcludeList();
|
||||||
|
DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), podId, clusterId, hostId, null, null);
|
||||||
|
for (StoragePoolAllocator allocator : _storagePoolAllocators) {
|
||||||
|
List<StoragePool> poolListFromAllocator = allocator.allocateToPool(diskProfile, profile, plan, avoid, 1);
|
||||||
|
if (CollectionUtils.isNotEmpty(poolListFromAllocator)) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(String.format("Found a suitable pool: %s for disk offering: %s", poolListFromAllocator.get(0).getName(), diskOffering.getName()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Long, Boolean> getDiskOfferingSuitabilityForVm(long vmId, List<Long> diskOfferingIds) {
|
||||||
|
VMInstanceVO vm = _vmDao.findById(vmId);
|
||||||
|
VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
|
||||||
|
Pair<Long, Long> clusterAndHost = findClusterAndHostIdForVm(vm, false);
|
||||||
|
Long clusterId = clusterAndHost.first();
|
||||||
|
Cluster cluster = _clusterDao.findById(clusterId);
|
||||||
|
Map<Long, Boolean> result = new HashMap<>();
|
||||||
|
for (Long diskOfferingId : diskOfferingIds) {
|
||||||
|
result.put(diskOfferingId, isDiskOfferingSuitableForVm(vm, profile, cluster.getPodId(), clusterId, clusterAndHost.second(), diskOfferingId));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,6 +130,7 @@ import com.cloud.storage.Volume.Type;
|
|||||||
import com.cloud.storage.VolumeApiService;
|
import com.cloud.storage.VolumeApiService;
|
||||||
import com.cloud.storage.VolumeDetailVO;
|
import com.cloud.storage.VolumeDetailVO;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
import com.cloud.storage.dao.SnapshotDao;
|
import com.cloud.storage.dao.SnapshotDao;
|
||||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||||
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
||||||
@ -245,6 +246,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
PassphraseDao passphraseDao;
|
PassphraseDao passphraseDao;
|
||||||
@Inject
|
@Inject
|
||||||
StoragePoolHostDao storagePoolHostDao;
|
StoragePoolHostDao storagePoolHostDao;
|
||||||
|
@Inject
|
||||||
|
DiskOfferingDao diskOfferingDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected SnapshotHelper snapshotHelper;
|
protected SnapshotHelper snapshotHelper;
|
||||||
@ -878,9 +881,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
if (vm.getType() == VirtualMachine.Type.User) {
|
if (vm.getType() == VirtualMachine.Type.User) {
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size,
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size,
|
||||||
Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
|
Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
|
||||||
|
_resourceLimitMgr.incrementVolumeResourceCount(vm.getAccountId(), vol.isDisplayVolume(), vol.getSize(), offering);
|
||||||
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
|
|
||||||
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
|
|
||||||
}
|
}
|
||||||
DiskProfile diskProfile = toDiskProfile(vol, offering);
|
DiskProfile diskProfile = toDiskProfile(vol, offering);
|
||||||
|
|
||||||
@ -962,8 +963,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, vol.getTemplateId(), size,
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, vol.getTemplateId(), size,
|
||||||
Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
|
Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
|
||||||
|
|
||||||
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
|
_resourceLimitMgr.incrementVolumeResourceCount(vm.getAccountId(), vol.isDisplayVolume(), vol.getSize(), offering);
|
||||||
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
|
|
||||||
}
|
}
|
||||||
return toDiskProfile(vol, offering);
|
return toDiskProfile(vol, offering);
|
||||||
}
|
}
|
||||||
@ -1142,6 +1142,10 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
// Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account.
|
// Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account.
|
||||||
_resourceLimitMgr.decrementResourceCount(volumeInfo.getAccountId(), ResourceType.secondary_storage, volumeInfo.getSize());
|
_resourceLimitMgr.decrementResourceCount(volumeInfo.getAccountId(), ResourceType.secondary_storage, volumeInfo.getSize());
|
||||||
_resourceLimitMgr.incrementResourceCount(volumeInfo.getAccountId(), ResourceType.primary_storage, volumeInfo.getSize());
|
_resourceLimitMgr.incrementResourceCount(volumeInfo.getAccountId(), ResourceType.primary_storage, volumeInfo.getSize());
|
||||||
|
List<String> tags = _resourceLimitMgr.getResourceLimitStorageTags(diskVO);
|
||||||
|
for (String tag : tags) {
|
||||||
|
_resourceLimitMgr.incrementResourceCountWithTag(volumeInfo.getAccountId(), ResourceType.primary_storage, tag, volumeInfo.getSize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2102,8 +2106,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
if (volume.getState() == Volume.State.Allocated) {
|
if (volume.getState() == Volume.State.Allocated) {
|
||||||
_volsDao.remove(volume.getId());
|
_volsDao.remove(volume.getId());
|
||||||
stateTransitTo(volume, Volume.Event.DestroyRequested);
|
stateTransitTo(volume, Volume.Event.DestroyRequested);
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplay());
|
_resourceLimitMgr.decrementVolumeResourceCount(volume.getAccountId(), volume.isDisplay(), volume.getSize(), diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId()));
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplay(), new Long(volume.getSize()));
|
|
||||||
} else {
|
} else {
|
||||||
destroyVolumeInContext(volume);
|
destroyVolumeInContext(volume);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import static org.junit.Assert.assertNull;
|
|||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@ -38,27 +39,12 @@ import java.util.Map;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.cloud.dc.ClusterDetailsDao;
|
|
||||||
import com.cloud.dc.ClusterDetailsVO;
|
|
||||||
import com.cloud.dc.Pod;
|
|
||||||
import com.cloud.deploy.DeployDestination;
|
|
||||||
import com.cloud.deploy.DeploymentPlanningManager;
|
|
||||||
import com.cloud.hypervisor.HypervisorGuruManager;
|
|
||||||
import com.cloud.org.Cluster;
|
|
||||||
import com.cloud.template.VirtualMachineTemplate;
|
|
||||||
import com.cloud.user.Account;
|
|
||||||
import com.cloud.user.User;
|
|
||||||
import com.cloud.utils.Journal;
|
|
||||||
import com.cloud.utils.Pair;
|
|
||||||
import com.cloud.utils.Ternary;
|
|
||||||
import com.cloud.utils.db.EntityManager;
|
|
||||||
import com.cloud.utils.fsm.StateMachine2;
|
|
||||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
|
import org.apache.commons.collections.MapUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -71,6 +57,7 @@ import org.mockito.Mockito;
|
|||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
@ -78,16 +65,25 @@ import com.cloud.agent.api.StopAnswer;
|
|||||||
import com.cloud.agent.api.StopCommand;
|
import com.cloud.agent.api.StopCommand;
|
||||||
import com.cloud.agent.api.routing.NetworkElementCommand;
|
import com.cloud.agent.api.routing.NetworkElementCommand;
|
||||||
import com.cloud.api.query.dao.UserVmJoinDao;
|
import com.cloud.api.query.dao.UserVmJoinDao;
|
||||||
|
import com.cloud.dc.ClusterDetailsDao;
|
||||||
|
import com.cloud.dc.ClusterDetailsVO;
|
||||||
|
import com.cloud.dc.ClusterVO;
|
||||||
|
import com.cloud.dc.Pod;
|
||||||
|
import com.cloud.dc.dao.ClusterDao;
|
||||||
import com.cloud.deploy.DataCenterDeployment;
|
import com.cloud.deploy.DataCenterDeployment;
|
||||||
|
import com.cloud.deploy.DeployDestination;
|
||||||
import com.cloud.deploy.DeploymentPlan;
|
import com.cloud.deploy.DeploymentPlan;
|
||||||
import com.cloud.deploy.DeploymentPlanner;
|
import com.cloud.deploy.DeploymentPlanner;
|
||||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||||
|
import com.cloud.deploy.DeploymentPlanningManager;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
|
import com.cloud.hypervisor.HypervisorGuruManager;
|
||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
|
import com.cloud.org.Cluster;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.DiskOfferingVO;
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
@ -105,11 +101,19 @@ import com.cloud.storage.dao.StoragePoolHostDao;
|
|||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import com.cloud.storage.dao.VMTemplateZoneDao;
|
import com.cloud.storage.dao.VMTemplateZoneDao;
|
||||||
import com.cloud.storage.dao.VolumeDao;
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.user.User;
|
||||||
|
import com.cloud.utils.Journal;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
|
import com.cloud.utils.Ternary;
|
||||||
|
import com.cloud.utils.db.EntityManager;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.utils.fsm.StateMachine2;
|
||||||
import com.cloud.vm.VirtualMachine.State;
|
import com.cloud.vm.VirtualMachine.State;
|
||||||
import com.cloud.vm.dao.UserVmDao;
|
import com.cloud.vm.dao.UserVmDao;
|
||||||
|
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class VirtualMachineManagerImplTest {
|
public class VirtualMachineManagerImplTest {
|
||||||
@ -184,6 +188,8 @@ public class VirtualMachineManagerImplTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private HypervisorGuruManager _hvGuruMgr;
|
private HypervisorGuruManager _hvGuruMgr;
|
||||||
@Mock
|
@Mock
|
||||||
|
private ClusterDao clusterDao;
|
||||||
|
@Mock
|
||||||
private ClusterDetailsDao _clusterDetailsDao;
|
private ClusterDetailsDao _clusterDetailsDao;
|
||||||
@Mock
|
@Mock
|
||||||
private UserVmDetailsDao userVmDetailsDao;
|
private UserVmDetailsDao userVmDetailsDao;
|
||||||
@ -1117,4 +1123,47 @@ public class VirtualMachineManagerImplTest {
|
|||||||
|
|
||||||
assertNull(vmInstance.getPodIdToDeployIn());
|
assertNull(vmInstance.getPodIdToDeployIn());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsDiskOfferingSuitableForVmSuccess() {
|
||||||
|
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(anyLong());
|
||||||
|
List<StoragePool> poolListMock = new ArrayList<>();
|
||||||
|
poolListMock.add(storagePoolVoMock);
|
||||||
|
Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(any(DiskProfile.class), any(VirtualMachineProfile.class), any(DeploymentPlan.class),
|
||||||
|
any(ExcludeList.class), Mockito.eq(1));
|
||||||
|
boolean result = virtualMachineManagerImpl.isDiskOfferingSuitableForVm(vmInstanceMock, virtualMachineProfileMock, 1L, 1L,1L, 1L);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsDiskOfferingSuitableForVmNegative() {
|
||||||
|
Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(anyLong());
|
||||||
|
Mockito.doReturn(new ArrayList<>()).when(storagePoolAllocatorMock).allocateToPool(any(DiskProfile.class), any(VirtualMachineProfile.class), any(DeploymentPlan.class),
|
||||||
|
any(ExcludeList.class), Mockito.eq(1));
|
||||||
|
boolean result = virtualMachineManagerImpl.isDiskOfferingSuitableForVm(vmInstanceMock, virtualMachineProfileMock, 1L, 1L,1L, 1L);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetDiskOfferingSuitabilityForVm() {
|
||||||
|
Mockito.doReturn(vmInstanceMock).when(vmInstanceDaoMock).findById(1L);
|
||||||
|
Mockito.when(vmInstanceMock.getHostId()).thenReturn(1L);
|
||||||
|
Mockito.doReturn(hostMock).when(hostDaoMock).findById(1L);
|
||||||
|
Mockito.when(hostMock.getClusterId()).thenReturn(1L);
|
||||||
|
ClusterVO cluster = Mockito.mock(ClusterVO.class);
|
||||||
|
Mockito.when(cluster.getPodId()).thenReturn(1L);
|
||||||
|
Mockito.doReturn(cluster).when(clusterDao).findById(1L);
|
||||||
|
List<Long> diskOfferingIds = List.of(1L, 2L);
|
||||||
|
Mockito.doReturn(false).when(virtualMachineManagerImpl)
|
||||||
|
.isDiskOfferingSuitableForVm(eq(vmInstanceMock), any(VirtualMachineProfile.class),
|
||||||
|
eq(1L), eq(1L), eq(1L), eq(1L));
|
||||||
|
Mockito.doReturn(true).when(virtualMachineManagerImpl)
|
||||||
|
.isDiskOfferingSuitableForVm(eq(vmInstanceMock), any(VirtualMachineProfile.class),
|
||||||
|
eq(1L), eq(1L), eq(1L), eq(2L));
|
||||||
|
Map<Long, Boolean> result = virtualMachineManagerImpl.getDiskOfferingSuitabilityForVm(1L, diskOfferingIds);
|
||||||
|
assertTrue(MapUtils.isNotEmpty(result));
|
||||||
|
assertEquals(2, result.keySet().size());
|
||||||
|
assertFalse(result.get(1L));
|
||||||
|
assertTrue(result.get(2L));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,6 +80,9 @@ public class CapacityVO implements Capacity {
|
|||||||
@Transient
|
@Transient
|
||||||
private Long allocatedCapacity;
|
private Long allocatedCapacity;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private String tag;
|
||||||
|
|
||||||
public CapacityVO() {
|
public CapacityVO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,6 +224,15 @@ public class CapacityVO implements Capacity {
|
|||||||
this.allocatedCapacity = allocatedCapacity;
|
this.allocatedCapacity = allocatedCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUuid() {
|
public String getUuid() {
|
||||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||||
|
|||||||
@ -44,6 +44,8 @@ public interface CapacityDao extends GenericDao<CapacityVO, Long> {
|
|||||||
|
|
||||||
List<SummedCapacity> findCapacityBy(Integer capacityType, Long zoneId, Long podId, Long clusterId);
|
List<SummedCapacity> findCapacityBy(Integer capacityType, Long zoneId, Long podId, Long clusterId);
|
||||||
|
|
||||||
|
List<SummedCapacity> findFilteredCapacityBy(Integer capacityType, Long zoneId, Long podId, Long clusterId, List<Long> hostIds, List<Long> poolIds);
|
||||||
|
|
||||||
List<Long> listPodsByHostCapacities(long zoneId, int requiredCpu, long requiredRam, short capacityType);
|
List<Long> listPodsByHostCapacities(long zoneId, int requiredCpu, long requiredRam, short capacityType);
|
||||||
|
|
||||||
Pair<List<Long>, Map<Long, Double>> orderPodsByAggregateCapacity(long zoneId, short capacityType);
|
Pair<List<Long>, Map<Long, Double>> orderPodsByAggregateCapacity(long zoneId, short capacityType);
|
||||||
@ -51,7 +53,8 @@ public interface CapacityDao extends GenericDao<CapacityVO, Long> {
|
|||||||
List<SummedCapacity> findCapacityBy(Integer capacityType, Long zoneId,
|
List<SummedCapacity> findCapacityBy(Integer capacityType, Long zoneId,
|
||||||
Long podId, Long clusterId, String resourceState);
|
Long podId, Long clusterId, String resourceState);
|
||||||
|
|
||||||
List<SummedCapacity> listCapacitiesGroupedByLevelAndType(Integer capacityType, Long zoneId, Long podId, Long clusterId, int level, Long limit);
|
List<SummedCapacity> listCapacitiesGroupedByLevelAndType(Integer capacityType, Long zoneId, Long podId,
|
||||||
|
Long clusterId, int level, List<Long> hostIds, List<Long> poolIds, Long limit);
|
||||||
|
|
||||||
void updateCapacityState(Long dcId, Long podId, Long clusterId, Long hostId, String capacityState, short[] capacityType);
|
void updateCapacityState(Long dcId, Long podId, Long clusterId, Long hostId, String capacityState, short[] capacityType);
|
||||||
|
|
||||||
|
|||||||
@ -26,11 +26,11 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.capacity.Capacity;
|
import com.cloud.capacity.Capacity;
|
||||||
import com.cloud.capacity.CapacityVO;
|
import com.cloud.capacity.CapacityVO;
|
||||||
@ -339,7 +339,8 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SummedCapacity> listCapacitiesGroupedByLevelAndType(Integer capacityType, Long zoneId, Long podId, Long clusterId, int level, Long limit) {
|
public List<SummedCapacity> listCapacitiesGroupedByLevelAndType(Integer capacityType, Long zoneId, Long podId,
|
||||||
|
Long clusterId, int level, List<Long> hostIds, List<Long> poolIds, Long limit) {
|
||||||
|
|
||||||
StringBuilder finalQuery = new StringBuilder();
|
StringBuilder finalQuery = new StringBuilder();
|
||||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||||
@ -378,6 +379,18 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||||||
finalQuery.append(" AND capacity_type = ?");
|
finalQuery.append(" AND capacity_type = ?");
|
||||||
resourceIdList.add(capacityType.longValue());
|
resourceIdList.add(capacityType.longValue());
|
||||||
}
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(hostIds)) {
|
||||||
|
finalQuery.append(String.format(" AND capacity.host_id IN (%s)", StringUtils.join(hostIds, ",")));
|
||||||
|
if (capacityType == null) {
|
||||||
|
finalQuery.append(String.format(" AND capacity_type NOT IN (%s)", StringUtils.join(Capacity.STORAGE_CAPACITY_TYPES, ",")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(poolIds)) {
|
||||||
|
finalQuery.append(String.format(" AND capacity.host_id IN (%s)", StringUtils.join(poolIds, ",")));
|
||||||
|
if (capacityType == null) {
|
||||||
|
finalQuery.append(String.format(" AND capacity_type IN (%s)", StringUtils.join(Capacity.STORAGE_CAPACITY_TYPES, ",")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case 1: // List all the capacities grouped by zone, capacity Type
|
case 1: // List all the capacities grouped by zone, capacity Type
|
||||||
@ -461,8 +474,37 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getHostAndPoolConditionForFilteredCapacity(Integer capacityType, List<Long> hostIds, List<Long> poolIds) {
|
||||||
|
StringBuilder sql = new StringBuilder();
|
||||||
|
if (CollectionUtils.isEmpty(hostIds) && CollectionUtils.isEmpty(poolIds)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
sql.append(" AND (");
|
||||||
|
boolean hostConditionAdded = false;
|
||||||
|
if (CollectionUtils.isNotEmpty(hostIds) && (capacityType == null || !Capacity.STORAGE_CAPACITY_TYPES.contains(capacityType.shortValue()))) {
|
||||||
|
sql.append(String.format("(capacity.host_id IN (%s)", StringUtils.join(hostIds, ",")));
|
||||||
|
if (capacityType == null) {
|
||||||
|
sql.append(String.format(" AND capacity_type NOT IN (%s)", StringUtils.join(Capacity.STORAGE_CAPACITY_TYPES, ",")));
|
||||||
|
}
|
||||||
|
sql.append(")");
|
||||||
|
hostConditionAdded = true;
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(poolIds) && (capacityType == null || Capacity.STORAGE_CAPACITY_TYPES.contains(capacityType.shortValue()))) {
|
||||||
|
if (hostConditionAdded) {
|
||||||
|
sql.append(" OR ");
|
||||||
|
}
|
||||||
|
sql.append(String.format("(capacity.host_id IN (%s)", StringUtils.join(poolIds, ",")));
|
||||||
|
if (capacityType == null || Capacity.STORAGE_CAPACITY_TYPES.contains(capacityType.shortValue())) {
|
||||||
|
sql.append(String.format(" AND capacity_type IN (%s)", StringUtils.join(Capacity.STORAGE_CAPACITY_TYPES, ",")));
|
||||||
|
}
|
||||||
|
sql.append(")");
|
||||||
|
}
|
||||||
|
sql.append(")");
|
||||||
|
return sql.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SummedCapacity> findCapacityBy(Integer capacityType, Long zoneId, Long podId, Long clusterId) {
|
public List<SummedCapacity> findFilteredCapacityBy(Integer capacityType, Long zoneId, Long podId, Long clusterId, List<Long> hostIds, List<Long> poolIds) {
|
||||||
|
|
||||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
@ -516,6 +558,8 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||||||
resourceIdList.add(capacityType.longValue());
|
resourceIdList.add(capacityType.longValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sql.append(getHostAndPoolConditionForFilteredCapacity(capacityType, hostIds, poolIds));
|
||||||
|
|
||||||
if (podId == null && clusterId == null) {
|
if (podId == null && clusterId == null) {
|
||||||
sql.append(" GROUP BY capacity_type, data_center_id");
|
sql.append(" GROUP BY capacity_type, data_center_id");
|
||||||
} else {
|
} else {
|
||||||
@ -591,6 +635,11 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SummedCapacity> findCapacityBy(Integer capacityType, Long zoneId, Long podId, Long clusterId) {
|
||||||
|
return findFilteredCapacityBy(capacityType, zoneId, podId, clusterId, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateAllocated(Long hostId, long allocatedAmount, short capacityType, boolean add) {
|
public void updateAllocated(Long hostId, long allocatedAmount, short capacityType, boolean add) {
|
||||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
@ -702,6 +751,7 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||||||
public Long clusterId;
|
public Long clusterId;
|
||||||
public Long podId;
|
public Long podId;
|
||||||
public Long dcId;
|
public Long dcId;
|
||||||
|
public String tag;
|
||||||
|
|
||||||
public SummedCapacity() {
|
public SummedCapacity() {
|
||||||
}
|
}
|
||||||
@ -790,6 +840,14 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||||||
public void setAllocatedCapacity(Long sumAllocated) {
|
public void setAllocatedCapacity(Long sumAllocated) {
|
||||||
this.sumAllocated = sumAllocated;
|
this.sumAllocated = sumAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -47,10 +47,13 @@ public class ResourceCountVO implements ResourceCount {
|
|||||||
@Column(name = "count")
|
@Column(name = "count")
|
||||||
private long count;
|
private long count;
|
||||||
|
|
||||||
|
@Column(name = "tag")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
public ResourceCountVO() {
|
public ResourceCountVO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceCountVO(ResourceType type, long count, long ownerId, ResourceOwnerType ownerType) {
|
public ResourceCountVO(ResourceType type, long count, long ownerId, ResourceOwnerType ownerType, String tag) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.count = count;
|
this.count = count;
|
||||||
|
|
||||||
@ -59,6 +62,11 @@ public class ResourceCountVO implements ResourceCount {
|
|||||||
} else if (ownerType == ResourceOwnerType.Domain) {
|
} else if (ownerType == ResourceOwnerType.Domain) {
|
||||||
this.domainId = ownerId;
|
this.domainId = ownerId;
|
||||||
}
|
}
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceCountVO(ResourceType type, long count, long ownerId, ResourceOwnerType ownerType) {
|
||||||
|
this(type, count, ownerId, ownerType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -99,7 +107,7 @@ public class ResourceCountVO implements ResourceCount {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringBuilder("REsourceCount[").append("-")
|
return new StringBuilder("ResourceCount[").append("-")
|
||||||
.append(id)
|
.append(id)
|
||||||
.append("-")
|
.append("-")
|
||||||
.append(type)
|
.append(type)
|
||||||
@ -107,6 +115,8 @@ public class ResourceCountVO implements ResourceCount {
|
|||||||
.append(accountId)
|
.append(accountId)
|
||||||
.append("-")
|
.append("-")
|
||||||
.append(domainId)
|
.append(domainId)
|
||||||
|
.append("-")
|
||||||
|
.append(tag)
|
||||||
.append("]")
|
.append("]")
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
@ -136,4 +146,13 @@ public class ResourceCountVO implements ResourceCount {
|
|||||||
public void setAccountId(Long accountId) {
|
public void setAccountId(Long accountId) {
|
||||||
this.accountId = accountId;
|
this.accountId = accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,10 +47,13 @@ public class ResourceLimitVO implements ResourceLimit {
|
|||||||
@Column(name = "max")
|
@Column(name = "max")
|
||||||
private Long max;
|
private Long max;
|
||||||
|
|
||||||
|
@Column(name = "tag")
|
||||||
|
private String tag;
|
||||||
|
|
||||||
public ResourceLimitVO() {
|
public ResourceLimitVO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceLimitVO(ResourceCount.ResourceType type, Long max, long ownerId, ResourceOwnerType ownerType) {
|
public ResourceLimitVO(ResourceCount.ResourceType type, Long max, long ownerId, ResourceOwnerType ownerType, String tag) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
|
|
||||||
@ -59,6 +62,11 @@ public class ResourceLimitVO implements ResourceLimit {
|
|||||||
} else if (ownerType == ResourceOwnerType.Domain) {
|
} else if (ownerType == ResourceOwnerType.Domain) {
|
||||||
this.domainId = ownerId;
|
this.domainId = ownerId;
|
||||||
}
|
}
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceLimitVO(ResourceCount.ResourceType type, Long max, long ownerId, ResourceOwnerType ownerType) {
|
||||||
|
this(type, max, ownerId, ownerType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -123,4 +131,12 @@ public class ResourceLimitVO implements ResourceLimit {
|
|||||||
this.accountId = accountId;
|
this.accountId = accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,18 +26,20 @@ import com.cloud.utils.db.GenericDao;
|
|||||||
|
|
||||||
public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
|
public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
|
||||||
/**
|
/**
|
||||||
* @param domainId the id of the domain to get the resource count
|
* @param ownerId the id of the owner to get the resource count
|
||||||
* @param type the type of resource (e.g. user_vm, public_ip, volume)
|
* @param type the type of resource (e.g. user_vm, public_ip, volume)
|
||||||
|
* @param tag for the type of resource
|
||||||
* @return the count of resources in use for the given type and domain
|
* @return the count of resources in use for the given type and domain
|
||||||
*/
|
*/
|
||||||
long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type);
|
long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param domainId the id of the domain to set the resource count
|
* @param ownerId the id of the owner to set the resource count
|
||||||
* @param type the type of resource (e.g. user_vm, public_ip, volume)
|
* @param type the type of resource (e.g. user_vm, public_ip, volume)
|
||||||
* @param the count of resources in use for the given type and domain
|
* @param tag the tag for the type of resource
|
||||||
|
* @param count the count of resources in use for the given type and domain
|
||||||
*/
|
*/
|
||||||
void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, long count);
|
void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag, long count);
|
||||||
|
|
||||||
boolean updateById(long id, boolean increment, long delta);
|
boolean updateById(long id, boolean increment, long delta);
|
||||||
|
|
||||||
@ -45,13 +47,13 @@ public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
|
|||||||
|
|
||||||
List<ResourceCountVO> listByOwnerId(long ownerId, ResourceOwnerType ownerType);
|
List<ResourceCountVO> listByOwnerId(long ownerId, ResourceOwnerType ownerType);
|
||||||
|
|
||||||
ResourceCountVO findByOwnerAndType(long ownerId, ResourceOwnerType ownerType, ResourceType type);
|
ResourceCountVO findByOwnerAndTypeAndTag(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag);
|
||||||
|
|
||||||
List<ResourceCountVO> listResourceCountByOwnerType(ResourceOwnerType ownerType);
|
List<ResourceCountVO> listResourceCountByOwnerType(ResourceOwnerType ownerType);
|
||||||
|
|
||||||
Set<Long> listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type);
|
Set<Long> listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag);
|
||||||
|
|
||||||
Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type);
|
Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type, String tag);
|
||||||
|
|
||||||
long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType);
|
long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType);
|
||||||
|
|
||||||
@ -68,4 +70,6 @@ public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
|
|||||||
* Side note: This method is not using the "resource_count" table. It is executing the actual count instead.
|
* Side note: This method is not using the "resource_count" table. It is executing the actual count instead.
|
||||||
*/
|
*/
|
||||||
long countMemoryAllocatedToAccount(long accountId);
|
long countMemoryAllocatedToAccount(long accountId);
|
||||||
|
|
||||||
|
void removeResourceCountsForNonMatchingTags(Long ownerId, ResourceOwnerType ownerType, List<ResourceType> types, List<String> tags);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -27,6 +28,9 @@ import java.util.Set;
|
|||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
import com.cloud.configuration.Resource;
|
||||||
@ -37,6 +41,7 @@ import com.cloud.configuration.ResourceLimit;
|
|||||||
import com.cloud.domain.DomainVO;
|
import com.cloud.domain.DomainVO;
|
||||||
import com.cloud.domain.dao.DomainDao;
|
import com.cloud.domain.dao.DomainDao;
|
||||||
import com.cloud.user.AccountVO;
|
import com.cloud.user.AccountVO;
|
||||||
|
import com.cloud.user.ResourceLimitService;
|
||||||
import com.cloud.user.dao.AccountDao;
|
import com.cloud.user.dao.AccountDao;
|
||||||
import com.cloud.utils.db.DB;
|
import com.cloud.utils.db.DB;
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
@ -49,6 +54,8 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||||||
@Component
|
@Component
|
||||||
public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long> implements ResourceCountDao {
|
public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long> implements ResourceCountDao {
|
||||||
private final SearchBuilder<ResourceCountVO> TypeSearch;
|
private final SearchBuilder<ResourceCountVO> TypeSearch;
|
||||||
|
private final SearchBuilder<ResourceCountVO> TypeNullTagSearch;
|
||||||
|
private final SearchBuilder<ResourceCountVO> NonMatchingTagsSearch;
|
||||||
|
|
||||||
private final SearchBuilder<ResourceCountVO> AccountSearch;
|
private final SearchBuilder<ResourceCountVO> AccountSearch;
|
||||||
private final SearchBuilder<ResourceCountVO> DomainSearch;
|
private final SearchBuilder<ResourceCountVO> DomainSearch;
|
||||||
@ -63,8 +70,24 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||||||
TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ);
|
TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ);
|
||||||
TypeSearch.and("accountId", TypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
TypeSearch.and("accountId", TypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
TypeSearch.and("domainId", TypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
TypeSearch.and("domainId", TypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||||
|
TypeSearch.and("tag", TypeSearch.entity().getTag(), SearchCriteria.Op.EQ);
|
||||||
TypeSearch.done();
|
TypeSearch.done();
|
||||||
|
|
||||||
|
TypeNullTagSearch = createSearchBuilder();
|
||||||
|
TypeNullTagSearch.and("type", TypeNullTagSearch.entity().getType(), SearchCriteria.Op.EQ);
|
||||||
|
TypeNullTagSearch.and("accountId", TypeNullTagSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
TypeNullTagSearch.and("domainId", TypeNullTagSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||||
|
TypeNullTagSearch.and("tag", TypeNullTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
|
||||||
|
TypeNullTagSearch.done();
|
||||||
|
|
||||||
|
NonMatchingTagsSearch = createSearchBuilder();
|
||||||
|
NonMatchingTagsSearch.and("accountId", NonMatchingTagsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
NonMatchingTagsSearch.and("domainId", NonMatchingTagsSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||||
|
NonMatchingTagsSearch.and("types", NonMatchingTagsSearch.entity().getType(), SearchCriteria.Op.IN);
|
||||||
|
NonMatchingTagsSearch.and("tagNotNull", NonMatchingTagsSearch.entity().getTag(), SearchCriteria.Op.NNULL);
|
||||||
|
NonMatchingTagsSearch.and("tags", NonMatchingTagsSearch.entity().getTag(), SearchCriteria.Op.NIN);
|
||||||
|
NonMatchingTagsSearch.done();
|
||||||
|
|
||||||
AccountSearch = createSearchBuilder();
|
AccountSearch = createSearchBuilder();
|
||||||
DomainSearch = createSearchBuilder();
|
DomainSearch = createSearchBuilder();
|
||||||
}
|
}
|
||||||
@ -85,9 +108,12 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourceCountVO findByOwnerAndType(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
|
public ResourceCountVO findByOwnerAndTypeAndTag(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag) {
|
||||||
SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
|
SearchCriteria<ResourceCountVO> sc = tag != null ? TypeSearch.create() : TypeNullTagSearch.create();
|
||||||
sc.setParameters("type", type);
|
sc.setParameters("type", type);
|
||||||
|
if (tag != null) {
|
||||||
|
sc.setParameters("tag", tag);
|
||||||
|
}
|
||||||
|
|
||||||
if (ownerType == ResourceOwnerType.Account) {
|
if (ownerType == ResourceOwnerType.Account) {
|
||||||
sc.setParameters("accountId", ownerId);
|
sc.setParameters("accountId", ownerId);
|
||||||
@ -101,8 +127,8 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
|
public long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag) {
|
||||||
ResourceCountVO vo = findByOwnerAndType(ownerId, ownerType, type);
|
ResourceCountVO vo = findByOwnerAndTypeAndTag(ownerId, ownerType, type, tag);
|
||||||
if (vo != null) {
|
if (vo != null) {
|
||||||
return vo.getCount();
|
return vo.getCount();
|
||||||
} else {
|
} else {
|
||||||
@ -111,8 +137,8 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, long count) {
|
public void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag, long count) {
|
||||||
ResourceCountVO resourceCountVO = findByOwnerAndType(ownerId, ownerType, type);
|
ResourceCountVO resourceCountVO = findByOwnerAndTypeAndTag(ownerId, ownerType, type, tag);
|
||||||
if (resourceCountVO != null && count != resourceCountVO.getCount()) {
|
if (resourceCountVO != null && count != resourceCountVO.getCount()) {
|
||||||
resourceCountVO.setCount(count);
|
resourceCountVO.setCount(count);
|
||||||
update(resourceCountVO.getId(), resourceCountVO);
|
update(resourceCountVO.getId(), resourceCountVO);
|
||||||
@ -129,38 +155,59 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type) {
|
public Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type, String tag) {
|
||||||
Set<Long> rowIds = new HashSet<Long>();
|
Set<Long> rowIds = new HashSet<Long>();
|
||||||
Set<Long> domainIdsToUpdate = _domainDao.getDomainParentIds(domainId);
|
Set<Long> domainIdsToUpdate = _domainDao.getDomainParentIds(domainId);
|
||||||
for (Long domainIdToUpdate : domainIdsToUpdate) {
|
for (Long domainIdToUpdate : domainIdsToUpdate) {
|
||||||
ResourceCountVO domainCountRecord = findByOwnerAndType(domainIdToUpdate, ResourceOwnerType.Domain, type);
|
ResourceCountVO domainCountRecord = findByOwnerAndTypeAndTag(domainIdToUpdate, ResourceOwnerType.Domain, type, tag);
|
||||||
if (domainCountRecord != null) {
|
if (domainCountRecord != null) {
|
||||||
rowIds.add(domainCountRecord.getId());
|
rowIds.add(domainCountRecord.getId());
|
||||||
|
} else {
|
||||||
|
if (StringUtils.isNotEmpty(tag)) {
|
||||||
|
ResourceCountVO resourceCountVO = createTaggedResourceCount(domainIdToUpdate, ResourceOwnerType.Domain, type, tag);
|
||||||
|
rowIds.add(resourceCountVO.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rowIds;
|
return rowIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
|
public Set<Long> listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag) {
|
||||||
Set<Long> rowIds = new HashSet<Long>();
|
Set<Long> rowIds = new HashSet<Long>();
|
||||||
|
|
||||||
if (ownerType == ResourceOwnerType.Account) {
|
if (ownerType == ResourceOwnerType.Account) {
|
||||||
//get records for account
|
//get records for account
|
||||||
ResourceCountVO accountCountRecord = findByOwnerAndType(ownerId, ResourceOwnerType.Account, type);
|
ResourceCountVO accountCountRecord = findByOwnerAndTypeAndTag(ownerId, ResourceOwnerType.Account, type, tag);
|
||||||
if (accountCountRecord != null) {
|
if (accountCountRecord != null) {
|
||||||
rowIds.add(accountCountRecord.getId());
|
rowIds.add(accountCountRecord.getId());
|
||||||
|
} else {
|
||||||
|
if (StringUtils.isNotEmpty(tag)) {
|
||||||
|
ResourceCountVO resourceCountVO = createTaggedResourceCount(ownerId, ownerType, type, tag);
|
||||||
|
rowIds.add(resourceCountVO.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//get records for account's domain and all its parent domains
|
//get records for account's domain and all its parent domains
|
||||||
rowIds.addAll(listRowsToUpdateForDomain(_accountDao.findByIdIncludingRemoved(ownerId).getDomainId(), type));
|
rowIds.addAll(listRowsToUpdateForDomain(_accountDao.findByIdIncludingRemoved(ownerId).getDomainId(), type, tag));
|
||||||
} else if (ownerType == ResourceOwnerType.Domain) {
|
} else if (ownerType == ResourceOwnerType.Domain) {
|
||||||
return listRowsToUpdateForDomain(ownerId, type);
|
rowIds = listRowsToUpdateForDomain(ownerId, type, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rowIds;
|
return rowIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ResourceCountVO createTaggedResourceCount(long ownerId, ResourceLimit.ResourceOwnerType ownerType, ResourceType resourceType, String tag) {
|
||||||
|
ResourceCountVO taggedResourceCountVO = new ResourceCountVO(resourceType, 0, ownerId, ownerType, tag);
|
||||||
|
return persist(taggedResourceCountVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createTaggedResourceCounts(long ownerId, ResourceLimit.ResourceOwnerType ownerType, ResourceType resourceType, List<String> tags) {
|
||||||
|
for (String tag : tags) {
|
||||||
|
createTaggedResourceCount(ownerId, ownerType, resourceType, tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DB
|
@DB
|
||||||
public void createResourceCounts(long ownerId, ResourceLimit.ResourceOwnerType ownerType) {
|
public void createResourceCounts(long ownerId, ResourceLimit.ResourceOwnerType ownerType) {
|
||||||
@ -169,9 +216,23 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||||||
txn.start();
|
txn.start();
|
||||||
|
|
||||||
ResourceType[] resourceTypes = Resource.ResourceType.values();
|
ResourceType[] resourceTypes = Resource.ResourceType.values();
|
||||||
|
List<String> hostTags = new ArrayList<>();
|
||||||
|
if (StringUtils.isNotEmpty(ResourceLimitService.ResourceLimitHostTags.value())) {
|
||||||
|
hostTags = Arrays.asList(ResourceLimitService.ResourceLimitHostTags.value().split(","));
|
||||||
|
}
|
||||||
|
List<String> storageTags = new ArrayList<>();
|
||||||
|
if (StringUtils.isNotEmpty(ResourceLimitService.ResourceLimitStorageTags.value())) {
|
||||||
|
storageTags = Arrays.asList(ResourceLimitService.ResourceLimitStorageTags.value().split(","));
|
||||||
|
}
|
||||||
for (ResourceType resourceType : resourceTypes) {
|
for (ResourceType resourceType : resourceTypes) {
|
||||||
ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, ownerId, ownerType);
|
ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, ownerId, ownerType);
|
||||||
persist(resourceCountVO);
|
persist(resourceCountVO);
|
||||||
|
if (ResourceLimitService.HostTagsSupportingTypes.contains(resourceType)) {
|
||||||
|
createTaggedResourceCounts(ownerId, ownerType, resourceType, hostTags);
|
||||||
|
}
|
||||||
|
if (ResourceLimitService.StorageTagsSupportingTypes.contains(resourceType)) {
|
||||||
|
createTaggedResourceCounts(ownerId, ownerType, resourceType, storageTags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
@ -266,4 +327,22 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeResourceCountsForNonMatchingTags(Long ownerId, ResourceOwnerType ownerType, List<ResourceType> types, List<String> tags) {
|
||||||
|
SearchCriteria<ResourceCountVO> sc = NonMatchingTagsSearch.create();
|
||||||
|
if (ObjectUtils.allNotNull(ownerId, ownerType)) {
|
||||||
|
if (ResourceOwnerType.Account.equals(ownerType)) {
|
||||||
|
sc.setParameters("accountId", ownerId);
|
||||||
|
} else {
|
||||||
|
sc.setParameters("domainId", ownerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(types)) {
|
||||||
|
sc.setParameters("types", types.stream().map(ResourceType::getName).toArray());
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(tags)) {
|
||||||
|
sc.setParameters("tags", tags.toArray());
|
||||||
|
}
|
||||||
|
remove(sc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ package com.cloud.configuration.dao;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
import com.cloud.configuration.Resource.ResourceOwnerType;
|
import com.cloud.configuration.Resource.ResourceOwnerType;
|
||||||
import com.cloud.configuration.ResourceCount;
|
import com.cloud.configuration.ResourceCount;
|
||||||
import com.cloud.configuration.ResourceLimitVO;
|
import com.cloud.configuration.ResourceLimitVO;
|
||||||
@ -31,7 +32,8 @@ public interface ResourceLimitDao extends GenericDao<ResourceLimitVO, Long> {
|
|||||||
|
|
||||||
ResourceCount.ResourceType getLimitType(String type);
|
ResourceCount.ResourceType getLimitType(String type);
|
||||||
|
|
||||||
ResourceLimitVO findByOwnerIdAndType(long ownerId, ResourceOwnerType ownerType, ResourceCount.ResourceType type);
|
ResourceLimitVO findByOwnerIdAndTypeAndTag(long ownerId, ResourceOwnerType ownerType, ResourceCount.ResourceType type, String tag);
|
||||||
|
|
||||||
long removeEntriesByOwner(Long ownerId, ResourceOwnerType ownerType);
|
long removeEntriesByOwner(Long ownerId, ResourceOwnerType ownerType);
|
||||||
|
void removeResourceLimitsForNonMatchingTags(Long ownerId, ResourceOwnerType ownerType, List<Resource.ResourceType> types, List<String> tags);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
import com.cloud.configuration.Resource;
|
||||||
@ -33,19 +35,36 @@ import com.cloud.utils.db.SearchCriteria;
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long> implements ResourceLimitDao {
|
public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long> implements ResourceLimitDao {
|
||||||
private SearchBuilder<ResourceLimitVO> IdTypeSearch;
|
private SearchBuilder<ResourceLimitVO> IdTypeTagSearch;
|
||||||
|
private SearchBuilder<ResourceLimitVO> IdTypeNullTagSearch;
|
||||||
|
private SearchBuilder<ResourceLimitVO> NonMatchingTagsSearch;
|
||||||
|
|
||||||
public ResourceLimitDaoImpl() {
|
public ResourceLimitDaoImpl() {
|
||||||
IdTypeSearch = createSearchBuilder();
|
IdTypeTagSearch = createSearchBuilder();
|
||||||
IdTypeSearch.and("type", IdTypeSearch.entity().getType(), SearchCriteria.Op.EQ);
|
IdTypeTagSearch.and("type", IdTypeTagSearch.entity().getType(), SearchCriteria.Op.EQ);
|
||||||
IdTypeSearch.and("domainId", IdTypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
IdTypeTagSearch.and("domainId", IdTypeTagSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||||
IdTypeSearch.and("accountId", IdTypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
IdTypeTagSearch.and("accountId", IdTypeTagSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
IdTypeSearch.done();
|
IdTypeTagSearch.and("tag", IdTypeTagSearch.entity().getTag(), SearchCriteria.Op.EQ);
|
||||||
|
|
||||||
|
IdTypeNullTagSearch = createSearchBuilder();
|
||||||
|
IdTypeNullTagSearch.and("type", IdTypeNullTagSearch.entity().getType(), SearchCriteria.Op.EQ);
|
||||||
|
IdTypeNullTagSearch.and("domainId", IdTypeNullTagSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||||
|
IdTypeNullTagSearch.and("accountId", IdTypeNullTagSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
IdTypeNullTagSearch.and("tag", IdTypeNullTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
|
||||||
|
IdTypeNullTagSearch.done();
|
||||||
|
|
||||||
|
NonMatchingTagsSearch = createSearchBuilder();
|
||||||
|
NonMatchingTagsSearch.and("accountId", NonMatchingTagsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
NonMatchingTagsSearch.and("domainId", NonMatchingTagsSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||||
|
NonMatchingTagsSearch.and("types", NonMatchingTagsSearch.entity().getType(), SearchCriteria.Op.IN);
|
||||||
|
NonMatchingTagsSearch.and("tagNotNull", NonMatchingTagsSearch.entity().getTag(), SearchCriteria.Op.NNULL);
|
||||||
|
NonMatchingTagsSearch.and("tags", NonMatchingTagsSearch.entity().getTag(), SearchCriteria.Op.NIN);
|
||||||
|
NonMatchingTagsSearch.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ResourceLimitVO> listByOwner(Long ownerId, ResourceOwnerType ownerType) {
|
public List<ResourceLimitVO> listByOwner(Long ownerId, ResourceOwnerType ownerType) {
|
||||||
SearchCriteria<ResourceLimitVO> sc = IdTypeSearch.create();
|
SearchCriteria<ResourceLimitVO> sc = IdTypeTagSearch.create();
|
||||||
|
|
||||||
if (ownerType == ResourceOwnerType.Account) {
|
if (ownerType == ResourceOwnerType.Account) {
|
||||||
sc.setParameters("accountId", ownerId);
|
sc.setParameters("accountId", ownerId);
|
||||||
@ -81,9 +100,12 @@ public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourceLimitVO findByOwnerIdAndType(long ownerId, ResourceOwnerType ownerType, ResourceCount.ResourceType type) {
|
public ResourceLimitVO findByOwnerIdAndTypeAndTag(long ownerId, ResourceOwnerType ownerType, ResourceCount.ResourceType type, String tag) {
|
||||||
SearchCriteria<ResourceLimitVO> sc = IdTypeSearch.create();
|
SearchCriteria<ResourceLimitVO> sc = tag != null ? IdTypeTagSearch.create() : IdTypeNullTagSearch.create();
|
||||||
sc.setParameters("type", type);
|
sc.setParameters("type", type);
|
||||||
|
if (tag != null) {
|
||||||
|
sc.setParameters("tag", tag);
|
||||||
|
}
|
||||||
|
|
||||||
if (ownerType == ResourceOwnerType.Account) {
|
if (ownerType == ResourceOwnerType.Account) {
|
||||||
sc.setParameters("accountId", ownerId);
|
sc.setParameters("accountId", ownerId);
|
||||||
@ -98,7 +120,7 @@ public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long removeEntriesByOwner(Long ownerId, ResourceOwnerType ownerType) {
|
public long removeEntriesByOwner(Long ownerId, ResourceOwnerType ownerType) {
|
||||||
SearchCriteria<ResourceLimitVO> sc = IdTypeSearch.create();
|
SearchCriteria<ResourceLimitVO> sc = IdTypeTagSearch.create();
|
||||||
|
|
||||||
if (ownerType == ResourceOwnerType.Account) {
|
if (ownerType == ResourceOwnerType.Account) {
|
||||||
sc.setParameters("accountId", ownerId);
|
sc.setParameters("accountId", ownerId);
|
||||||
@ -109,4 +131,23 @@ public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long>
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeResourceLimitsForNonMatchingTags(Long ownerId, ResourceOwnerType ownerType, List<ResourceType> types, List<String> tags) {
|
||||||
|
SearchCriteria<ResourceLimitVO> sc = NonMatchingTagsSearch.create();
|
||||||
|
if (ObjectUtils.allNotNull(ownerId, ownerType)) {
|
||||||
|
if (ResourceOwnerType.Account.equals(ownerType)) {
|
||||||
|
sc.setParameters("accountId", ownerId);
|
||||||
|
} else {
|
||||||
|
sc.setParameters("domainId", ownerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(types)) {
|
||||||
|
sc.setParameters("types", types.stream().map(ResourceType::getName).toArray());
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(tags)) {
|
||||||
|
sc.setParameters("tags", tags.toArray());
|
||||||
|
}
|
||||||
|
remove(sc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,8 +16,11 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.host;
|
package com.cloud.host;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -39,21 +42,21 @@ import javax.persistence.Temporal;
|
|||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
import javax.persistence.Transient;
|
import javax.persistence.Transient;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.utils.jsinterpreter.TagAsRuleHelper;
|
||||||
|
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||||
|
import org.apache.commons.lang.BooleanUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.cloud.agent.api.VgpuTypesInfo;
|
import com.cloud.agent.api.VgpuTypesInfo;
|
||||||
import com.cloud.host.dao.HostTagsDao;
|
import com.cloud.host.dao.HostTagsDao;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
import com.cloud.resource.ResourceState;
|
import com.cloud.resource.ResourceState;
|
||||||
import com.cloud.storage.Storage.StoragePoolType;
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
import com.cloud.util.StoragePoolTypeConverter;
|
import com.cloud.util.StoragePoolTypeConverter;
|
||||||
import com.cloud.utils.NumbersUtil;
|
import com.cloud.utils.NumbersUtil;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.utils.jsinterpreter.TagAsRuleHelper;
|
|
||||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
|
||||||
import org.apache.commons.lang.BooleanUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "host")
|
@Table(name = "host")
|
||||||
@ -764,7 +767,28 @@ public class HostVO implements Host {
|
|||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkHostServiceOfferingTags(ServiceOffering serviceOffering){
|
public boolean checkHostServiceOfferingAndTemplateTags(ServiceOffering serviceOffering, VirtualMachineTemplate template) {
|
||||||
|
if (serviceOffering == null || template == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(serviceOffering.getHostTag()) && StringUtils.isEmpty(template.getTemplateTag())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (getHostTags() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HashSet<String> hostTagsSet = new HashSet<>(getHostTags());
|
||||||
|
List<String> tags = new ArrayList<>();
|
||||||
|
if (StringUtils.isNotEmpty(serviceOffering.getHostTag())) {
|
||||||
|
tags.addAll(Arrays.asList(serviceOffering.getHostTag().split(",")));
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(template.getTemplateTag()) && !tags.contains(template.getTemplateTag())) {
|
||||||
|
tags.add(template.getTemplateTag());
|
||||||
|
}
|
||||||
|
return hostTagsSet.containsAll(tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkHostServiceOfferingTags(ServiceOffering serviceOffering) {
|
||||||
if (serviceOffering == null) {
|
if (serviceOffering == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -776,7 +800,6 @@ public class HostVO implements Host {
|
|||||||
if (StringUtils.isEmpty(serviceOffering.getHostTag())) {
|
if (StringUtils.isEmpty(serviceOffering.getHostTag())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> serviceOfferingTags = Arrays.asList(serviceOffering.getHostTag().split(","));
|
List<String> serviceOfferingTags = Arrays.asList(serviceOffering.getHostTag().split(","));
|
||||||
return this.getHostTags() != null && this.getHostTags().containsAll(serviceOfferingTags);
|
return this.getHostTags() != null && this.getHostTags().containsAll(serviceOfferingTags);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,7 +63,7 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
|
|||||||
|
|
||||||
void loadHostTags(HostVO host);
|
void loadHostTags(HostVO host);
|
||||||
|
|
||||||
List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag);
|
List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, Long dcId, String hostTag);
|
||||||
|
|
||||||
List<HostVO> findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId);
|
List<HostVO> findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId);
|
||||||
|
|
||||||
|
|||||||
@ -780,7 +780,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag) {
|
public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, Long dcId, String hostTag) {
|
||||||
SearchBuilder<HostVO> hostSearch = createSearchBuilder();
|
SearchBuilder<HostVO> hostSearch = createSearchBuilder();
|
||||||
HostVO entity = hostSearch.entity();
|
HostVO entity = hostSearch.entity();
|
||||||
hostSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
|
hostSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
|
||||||
@ -798,7 +798,9 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||||||
if (clusterId != null) {
|
if (clusterId != null) {
|
||||||
sc.setParameters("cluster", clusterId);
|
sc.setParameters("cluster", clusterId);
|
||||||
}
|
}
|
||||||
sc.setParameters("dc", dcId);
|
if (dcId != null) {
|
||||||
|
sc.setParameters("dc", dcId);
|
||||||
|
}
|
||||||
sc.setParameters("status", Status.Up.toString());
|
sc.setParameters("status", Status.Up.toString());
|
||||||
sc.setParameters("resourceState", ResourceState.Enabled.toString());
|
sc.setParameters("resourceState", ResourceState.Enabled.toString());
|
||||||
|
|
||||||
|
|||||||
@ -55,4 +55,6 @@ public interface ServiceOfferingDao extends GenericDao<ServiceOfferingVO, Long>
|
|||||||
List<ServiceOfferingVO> listPublicByCpuAndMemory(Integer cpus, Integer memory);
|
List<ServiceOfferingVO> listPublicByCpuAndMemory(Integer cpus, Integer memory);
|
||||||
|
|
||||||
ServiceOfferingVO findServiceOfferingByComputeOnlyDiskOffering(long diskOfferingId);
|
ServiceOfferingVO findServiceOfferingByComputeOnlyDiskOffering(long diskOfferingId);
|
||||||
|
|
||||||
|
List<ServiceOfferingVO> listByHostTag(String tag);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -291,4 +291,22 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
|||||||
}
|
}
|
||||||
return vos.get(0);
|
return vos.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ServiceOfferingVO> listByHostTag(String tag) {
|
||||||
|
SearchBuilder<ServiceOfferingVO> sb = createSearchBuilder();
|
||||||
|
sb.and("tagNotNull", sb.entity().getHostTag(), SearchCriteria.Op.NNULL);
|
||||||
|
sb.and().op("tagEq", sb.entity().getHostTag(), SearchCriteria.Op.EQ);
|
||||||
|
sb.or("tagStartLike", sb.entity().getHostTag(), SearchCriteria.Op.LIKE);
|
||||||
|
sb.or("tagMidLike", sb.entity().getHostTag(), SearchCriteria.Op.LIKE);
|
||||||
|
sb.or("tagEndLike", sb.entity().getHostTag(), SearchCriteria.Op.LIKE);
|
||||||
|
sb.cp();
|
||||||
|
sb.done();
|
||||||
|
SearchCriteria<ServiceOfferingVO> sc = sb.create();
|
||||||
|
sc.setParameters("tagEq", tag);
|
||||||
|
sc.setParameters("tagStartLike", tag + ",%");
|
||||||
|
sc.setParameters("tagMidLike", "%," + tag + ",%");
|
||||||
|
sc.setParameters("tagEndLike", "%," + tag);
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,5 +31,6 @@ public interface DiskOfferingDao extends GenericDao<DiskOfferingVO, Long> {
|
|||||||
List<DiskOfferingVO> listAllBySizeAndProvisioningType(long size, Storage.ProvisioningType provisioningType);
|
List<DiskOfferingVO> listAllBySizeAndProvisioningType(long size, Storage.ProvisioningType provisioningType);
|
||||||
|
|
||||||
List<DiskOfferingVO> findCustomDiskOfferings();
|
List<DiskOfferingVO> findCustomDiskOfferings();
|
||||||
|
List<DiskOfferingVO> listByStorageTag(String tag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -157,4 +157,22 @@ public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> im
|
|||||||
|
|
||||||
return update(id, diskOffering);
|
return update(id, diskOffering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DiskOfferingVO> listByStorageTag(String tag) {
|
||||||
|
SearchBuilder<DiskOfferingVO> sb = createSearchBuilder();
|
||||||
|
sb.and("tagNotNull", sb.entity().getTags(), SearchCriteria.Op.NNULL);
|
||||||
|
sb.and().op("tagEq", sb.entity().getTags(), SearchCriteria.Op.EQ);
|
||||||
|
sb.or("tagStartLike", sb.entity().getTags(), SearchCriteria.Op.LIKE);
|
||||||
|
sb.or("tagMidLike", sb.entity().getTags(), SearchCriteria.Op.LIKE);
|
||||||
|
sb.or("tagEndLike", sb.entity().getTags(), SearchCriteria.Op.LIKE);
|
||||||
|
sb.cp();
|
||||||
|
sb.done();
|
||||||
|
SearchCriteria<DiskOfferingVO> sc = sb.create();
|
||||||
|
sc.setParameters("tagEq", tag);
|
||||||
|
sc.setParameters("tagStartLike", tag + ",%");
|
||||||
|
sc.setParameters("tagMidLike", "%," + tag + ",%");
|
||||||
|
sc.setParameters("tagEndLike", "%," + tag);
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,5 +34,6 @@ public interface StoragePoolTagsDao extends GenericDao<StoragePoolTagVO, Long> {
|
|||||||
StorageTagResponse newStorageTagResponse(StoragePoolTagVO tag);
|
StorageTagResponse newStorageTagResponse(StoragePoolTagVO tag);
|
||||||
|
|
||||||
List<StoragePoolTagVO> findStoragePoolTags(long poolId);
|
List<StoragePoolTagVO> findStoragePoolTags(long poolId);
|
||||||
|
List<Long> listPoolIdsByTag(String tag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,12 +18,10 @@ package com.cloud.storage.dao;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import com.cloud.utils.db.Transaction;
|
|
||||||
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
|
||||||
import com.cloud.utils.db.TransactionStatus;
|
|
||||||
import org.apache.cloudstack.api.response.StorageTagResponse;
|
import org.apache.cloudstack.api.response.StorageTagResponse;
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
|
|
||||||
@ -31,7 +29,10 @@ import com.cloud.storage.StoragePoolTagVO;
|
|||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import com.cloud.utils.db.Transaction;
|
||||||
|
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||||
import com.cloud.utils.db.TransactionLegacy;
|
import com.cloud.utils.db.TransactionLegacy;
|
||||||
|
import com.cloud.utils.db.TransactionStatus;
|
||||||
|
|
||||||
public class StoragePoolTagsDaoImpl extends GenericDaoBase<StoragePoolTagVO, Long> implements StoragePoolTagsDao {
|
public class StoragePoolTagsDaoImpl extends GenericDaoBase<StoragePoolTagVO, Long> implements StoragePoolTagsDao {
|
||||||
|
|
||||||
@ -178,4 +179,15 @@ public class StoragePoolTagsDaoImpl extends GenericDaoBase<StoragePoolTagVO, Lon
|
|||||||
return search(sc, null);
|
return search(sc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> listPoolIdsByTag(String tag) {
|
||||||
|
SearchBuilder<StoragePoolTagVO> sb = createSearchBuilder();
|
||||||
|
sb.and("tag", sb.entity().getTag(), SearchCriteria.Op.EQ);
|
||||||
|
sb.done();
|
||||||
|
SearchCriteria<StoragePoolTagVO> sc = sb.create();
|
||||||
|
sc.setParameters("tag", tag);
|
||||||
|
List<StoragePoolTagVO> poolRefs = search(sc, null);
|
||||||
|
return poolRefs.stream().map(StoragePoolTagVO::getPoolId).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,4 +90,7 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
|
|||||||
List<VMTemplateVO> findTemplatesLinkedToUserdata(long userdataId);
|
List<VMTemplateVO> findTemplatesLinkedToUserdata(long userdataId);
|
||||||
|
|
||||||
List<VMTemplateVO> listByIds(List<Long> ids);
|
List<VMTemplateVO> listByIds(List<Long> ids);
|
||||||
|
|
||||||
|
List<VMTemplateVO> listByTemplateTag(String tag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -686,6 +686,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<VMTemplateVO> listByTemplateTag(String tag) {
|
||||||
|
SearchBuilder<VMTemplateVO> sb = createSearchBuilder();
|
||||||
|
sb.and("tag", sb.entity().getTemplateTag(), SearchCriteria.Op.EQ);
|
||||||
|
sb.done();
|
||||||
|
SearchCriteria<VMTemplateVO> sc = sb.create();
|
||||||
|
sc.setParameters("tag", tag);
|
||||||
|
return listIncludingRemovedBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean updateState(
|
public boolean updateState(
|
||||||
com.cloud.template.VirtualMachineTemplate.State currentState,
|
com.cloud.template.VirtualMachineTemplate.State currentState,
|
||||||
|
|||||||
@ -155,4 +155,7 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
|
|||||||
VolumeVO findByPoolIdAndPath(long id, String path);
|
VolumeVO findByPoolIdAndPath(long id, String path);
|
||||||
|
|
||||||
List<VolumeVO> listByIds(List<Long> ids);
|
List<VolumeVO> listByIds(List<Long> ids);
|
||||||
|
|
||||||
|
List<VolumeVO> listAllocatedVolumesForAccountDiskOfferingIdsAndNotForVms(long accountId, List<Long> diskOfferingIds, List<Long> vmIds);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -839,4 +839,28 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||||||
sc.setParameters("idIN", ids.toArray());
|
sc.setParameters("idIN", ids.toArray());
|
||||||
return listBy(sc, null);
|
return listBy(sc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<VolumeVO> listAllocatedVolumesForAccountDiskOfferingIdsAndNotForVms(long accountId, List<Long> diskOfferingIds, List<Long> vmIds) {
|
||||||
|
SearchBuilder<VolumeVO> sb = createSearchBuilder();
|
||||||
|
sb.and("account", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
sb.and("state", sb.entity().getState(), SearchCriteria.Op.NIN);
|
||||||
|
sb.and("diskOfferingIds", sb.entity().getDiskOfferingId(), SearchCriteria.Op.IN);
|
||||||
|
sb.and("displayVolume", sb.entity().isDisplayVolume(), Op.EQ);
|
||||||
|
if (CollectionUtils.isNotEmpty(vmIds)) {
|
||||||
|
sb.and().op("instanceId", sb.entity().getInstanceId(), Op.NULL);
|
||||||
|
sb.or("notVmIds", sb.entity().getInstanceId(), Op.NIN);
|
||||||
|
sb.cp();
|
||||||
|
}
|
||||||
|
sb.done();
|
||||||
|
SearchCriteria<VolumeVO> sc = sb.create();
|
||||||
|
sc.setParameters("account", accountId);
|
||||||
|
sc.setParameters("state", Volume.State.Destroy, Volume.State.Expunged);
|
||||||
|
sc.setParameters("diskOfferingIds", diskOfferingIds.toArray());
|
||||||
|
sc.setParameters("displayVolume", 1);
|
||||||
|
if (CollectionUtils.isNotEmpty(vmIds)) {
|
||||||
|
sc.setParameters("notVmIds", vmIds.toArray());
|
||||||
|
}
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,10 +18,6 @@
|
|||||||
//
|
//
|
||||||
package org.apache.cloudstack.reservation;
|
package org.apache.cloudstack.reservation;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
|
||||||
import org.apache.cloudstack.user.ResourceReservation;
|
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
@ -29,6 +25,11 @@ import javax.persistence.GenerationType;
|
|||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.user.ResourceReservation;
|
||||||
|
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "resource_reservation")
|
@Table(name = "resource_reservation")
|
||||||
public class ReservationVO implements ResourceReservation {
|
public class ReservationVO implements ResourceReservation {
|
||||||
@ -47,22 +48,30 @@ public class ReservationVO implements ResourceReservation {
|
|||||||
@Column(name = "resource_type", nullable = false)
|
@Column(name = "resource_type", nullable = false)
|
||||||
Resource.ResourceType resourceType;
|
Resource.ResourceType resourceType;
|
||||||
|
|
||||||
|
@Column(name = "tag")
|
||||||
|
String tag;
|
||||||
|
|
||||||
@Column(name = "amount")
|
@Column(name = "amount")
|
||||||
long amount;
|
long amount;
|
||||||
|
|
||||||
protected ReservationVO()
|
protected ReservationVO() {
|
||||||
{}
|
}
|
||||||
|
|
||||||
public ReservationVO(Long accountId, Long domainId, Resource.ResourceType resourceType, Long delta) {
|
public ReservationVO(Long accountId, Long domainId, Resource.ResourceType resourceType, String tag, Long delta) {
|
||||||
if (delta == null || delta <= 0) {
|
if (delta == null || delta <= 0) {
|
||||||
throw new CloudRuntimeException("resource reservations can not be made for no resources");
|
throw new CloudRuntimeException("resource reservations can not be made for no resources");
|
||||||
}
|
}
|
||||||
this.accountId = accountId;
|
this.accountId = accountId;
|
||||||
this.domainId = domainId;
|
this.domainId = domainId;
|
||||||
this.resourceType = resourceType;
|
this.resourceType = resourceType;
|
||||||
|
this.tag = tag;
|
||||||
this.amount = delta;
|
this.amount = delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReservationVO(Long accountId, Long domainId, Resource.ResourceType resourceType, Long delta) {
|
||||||
|
this(accountId, domainId, resourceType, null, delta);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
@ -83,6 +92,11 @@ public class ReservationVO implements ResourceReservation {
|
|||||||
return resourceType;
|
return resourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getReservedAmount() {
|
public Long getReservedAmount() {
|
||||||
return amount;
|
return amount;
|
||||||
|
|||||||
@ -18,11 +18,12 @@
|
|||||||
//
|
//
|
||||||
package org.apache.cloudstack.reservation.dao;
|
package org.apache.cloudstack.reservation.dao;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
|
||||||
import org.apache.cloudstack.reservation.ReservationVO;
|
import org.apache.cloudstack.reservation.ReservationVO;
|
||||||
|
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
|
||||||
public interface ReservationDao extends GenericDao<ReservationVO, Long> {
|
public interface ReservationDao extends GenericDao<ReservationVO, Long> {
|
||||||
long getAccountReservation(Long account, Resource.ResourceType resourceType);
|
long getAccountReservation(Long account, Resource.ResourceType resourceType, String tag);
|
||||||
long getDomainReservation(Long domain, Resource.ResourceType resourceType);
|
long getDomainReservation(Long domain, Resource.ResourceType resourceType, String tag);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,41 +18,63 @@
|
|||||||
//
|
//
|
||||||
package org.apache.cloudstack.reservation.dao;
|
package org.apache.cloudstack.reservation.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.reservation.ReservationVO;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
import com.cloud.configuration.Resource;
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import org.apache.cloudstack.reservation.ReservationVO;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ReservationDaoImpl extends GenericDaoBase<ReservationVO, Long> implements ReservationDao {
|
public class ReservationDaoImpl extends GenericDaoBase<ReservationVO, Long> implements ReservationDao {
|
||||||
|
|
||||||
private static final String RESOURCE_TYPE = "resourceType";
|
private static final String RESOURCE_TYPE = "resourceType";
|
||||||
|
private static final String RESOURCE_TAG = "resourceTag";
|
||||||
private static final String ACCOUNT_ID = "accountId";
|
private static final String ACCOUNT_ID = "accountId";
|
||||||
private static final String DOMAIN_ID = "domainId";
|
private static final String DOMAIN_ID = "domainId";
|
||||||
private final SearchBuilder<ReservationVO> listAccountAndTypeSearch;
|
private final SearchBuilder<ReservationVO> listAccountAndTypeSearch;
|
||||||
|
private final SearchBuilder<ReservationVO> listAccountAndTypeAndNoTagSearch;
|
||||||
|
|
||||||
private final SearchBuilder<ReservationVO> listDomainAndTypeSearch;
|
private final SearchBuilder<ReservationVO> listDomainAndTypeSearch;
|
||||||
|
private final SearchBuilder<ReservationVO> listDomainAndTypeAndNoTagSearch;
|
||||||
|
|
||||||
public ReservationDaoImpl() {
|
public ReservationDaoImpl() {
|
||||||
listAccountAndTypeSearch = createSearchBuilder();
|
listAccountAndTypeSearch = createSearchBuilder();
|
||||||
listAccountAndTypeSearch.and(ACCOUNT_ID, listAccountAndTypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
listAccountAndTypeSearch.and(ACCOUNT_ID, listAccountAndTypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
listAccountAndTypeSearch.and(RESOURCE_TYPE, listAccountAndTypeSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
|
listAccountAndTypeSearch.and(RESOURCE_TYPE, listAccountAndTypeSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
|
||||||
|
listAccountAndTypeSearch.and(RESOURCE_TAG, listAccountAndTypeSearch.entity().getTag(), SearchCriteria.Op.EQ);
|
||||||
listAccountAndTypeSearch.done();
|
listAccountAndTypeSearch.done();
|
||||||
|
|
||||||
|
listAccountAndTypeAndNoTagSearch = createSearchBuilder();
|
||||||
|
listAccountAndTypeAndNoTagSearch.and(ACCOUNT_ID, listAccountAndTypeAndNoTagSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
listAccountAndTypeAndNoTagSearch.and(RESOURCE_TYPE, listAccountAndTypeAndNoTagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
|
||||||
|
listAccountAndTypeAndNoTagSearch.and(RESOURCE_TAG, listAccountAndTypeAndNoTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
|
||||||
|
listAccountAndTypeAndNoTagSearch.done();
|
||||||
|
|
||||||
listDomainAndTypeSearch = createSearchBuilder();
|
listDomainAndTypeSearch = createSearchBuilder();
|
||||||
listDomainAndTypeSearch.and(DOMAIN_ID, listDomainAndTypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
listDomainAndTypeSearch.and(DOMAIN_ID, listDomainAndTypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||||
listDomainAndTypeSearch.and(RESOURCE_TYPE, listDomainAndTypeSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
|
listDomainAndTypeSearch.and(RESOURCE_TYPE, listDomainAndTypeSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
|
||||||
|
listDomainAndTypeSearch.and(RESOURCE_TAG, listDomainAndTypeSearch.entity().getTag(), SearchCriteria.Op.EQ);
|
||||||
listDomainAndTypeSearch.done();
|
listDomainAndTypeSearch.done();
|
||||||
|
|
||||||
|
listDomainAndTypeAndNoTagSearch = createSearchBuilder();
|
||||||
|
listDomainAndTypeAndNoTagSearch.and(ACCOUNT_ID, listDomainAndTypeAndNoTagSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
listDomainAndTypeAndNoTagSearch.and(RESOURCE_TYPE, listDomainAndTypeAndNoTagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
|
||||||
|
listDomainAndTypeAndNoTagSearch.and(RESOURCE_TAG, listDomainAndTypeAndNoTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
|
||||||
|
listDomainAndTypeAndNoTagSearch.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getAccountReservation(Long accountId, Resource.ResourceType resourceType) {
|
public long getAccountReservation(Long accountId, Resource.ResourceType resourceType, String tag) {
|
||||||
long total = 0;
|
long total = 0;
|
||||||
SearchCriteria<ReservationVO> sc = listAccountAndTypeSearch.create();
|
SearchCriteria<ReservationVO> sc = tag == null ?
|
||||||
|
listAccountAndTypeAndNoTagSearch.create() : listAccountAndTypeSearch.create();
|
||||||
sc.setParameters(ACCOUNT_ID, accountId);
|
sc.setParameters(ACCOUNT_ID, accountId);
|
||||||
sc.setParameters(RESOURCE_TYPE, resourceType);
|
sc.setParameters(RESOURCE_TYPE, resourceType);
|
||||||
|
if (tag != null) {
|
||||||
|
sc.setParameters(RESOURCE_TAG, tag);
|
||||||
|
}
|
||||||
List<ReservationVO> reservations = listBy(sc);
|
List<ReservationVO> reservations = listBy(sc);
|
||||||
for (ReservationVO reservation : reservations) {
|
for (ReservationVO reservation : reservations) {
|
||||||
total += reservation.getReservedAmount();
|
total += reservation.getReservedAmount();
|
||||||
@ -61,11 +83,15 @@ public class ReservationDaoImpl extends GenericDaoBase<ReservationVO, Long> impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDomainReservation(Long domainId, Resource.ResourceType resourceType) {
|
public long getDomainReservation(Long domainId, Resource.ResourceType resourceType, String tag) {
|
||||||
long total = 0;
|
long total = 0;
|
||||||
SearchCriteria<ReservationVO> sc = listDomainAndTypeSearch.create();
|
SearchCriteria<ReservationVO> sc = tag == null ?
|
||||||
|
listDomainAndTypeAndNoTagSearch.create() : listDomainAndTypeSearch.create();
|
||||||
sc.setParameters(DOMAIN_ID, domainId);
|
sc.setParameters(DOMAIN_ID, domainId);
|
||||||
sc.setParameters(RESOURCE_TYPE, resourceType);
|
sc.setParameters(RESOURCE_TYPE, resourceType);
|
||||||
|
if (tag != null) {
|
||||||
|
sc.setParameters(RESOURCE_TAG, tag);
|
||||||
|
}
|
||||||
List<ReservationVO> reservations = listBy(sc);
|
List<ReservationVO> reservations = listBy(sc);
|
||||||
for (ReservationVO reservation : reservations) {
|
for (ReservationVO reservation : reservations) {
|
||||||
total += reservation.getReservedAmount();
|
total += reservation.getReservedAmount();
|
||||||
|
|||||||
@ -18,3 +18,13 @@
|
|||||||
--;
|
--;
|
||||||
-- Schema upgrade from 4.19.0.0 to 4.20.0.0
|
-- Schema upgrade from 4.19.0.0 to 4.20.0.0
|
||||||
--;
|
--;
|
||||||
|
|
||||||
|
-- Add tag column to tables
|
||||||
|
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.resource_limit', 'tag', 'varchar(64) DEFAULT NULL COMMENT "tag for the limit" ');
|
||||||
|
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.resource_count', 'tag', 'varchar(64) DEFAULT NULL COMMENT "tag for the resource count" ');
|
||||||
|
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.resource_reservation', 'tag', 'varchar(64) DEFAULT NULL COMMENT "tag for the resource reservation" ');
|
||||||
|
ALTER TABLE `resource_count`
|
||||||
|
DROP INDEX `i_resource_count__type_accountId`,
|
||||||
|
DROP INDEX `i_resource_count__type_domaintId`,
|
||||||
|
ADD UNIQUE INDEX `i_resource_count__type_tag_accountId` (`type`,`tag`,`account_id`),
|
||||||
|
ADD UNIQUE INDEX `i_resource_count__type_tag_domaintId` (`type`,`tag`,`domain_id`);
|
||||||
|
|||||||
@ -0,0 +1,164 @@
|
|||||||
|
-- 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.
|
||||||
|
|
||||||
|
-- VIEW `cloud`.`account_view`;
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS `cloud`.`account_view`;
|
||||||
|
CREATE VIEW `cloud`.`account_view` AS
|
||||||
|
select
|
||||||
|
`account`.`id` AS `id`,
|
||||||
|
`account`.`uuid` AS `uuid`,
|
||||||
|
`account`.`account_name` AS `account_name`,
|
||||||
|
`account`.`type` AS `type`,
|
||||||
|
`account`.`role_id` AS `role_id`,
|
||||||
|
`account`.`state` AS `state`,
|
||||||
|
`account`.`created` AS `created`,
|
||||||
|
`account`.`removed` AS `removed`,
|
||||||
|
`account`.`cleanup_needed` AS `cleanup_needed`,
|
||||||
|
`account`.`network_domain` AS `network_domain` ,
|
||||||
|
`account`.`default` AS `default`,
|
||||||
|
`domain`.`id` AS `domain_id`,
|
||||||
|
`domain`.`uuid` AS `domain_uuid`,
|
||||||
|
`domain`.`name` AS `domain_name`,
|
||||||
|
`domain`.`path` AS `domain_path`,
|
||||||
|
`data_center`.`id` AS `data_center_id`,
|
||||||
|
`data_center`.`uuid` AS `data_center_uuid`,
|
||||||
|
`data_center`.`name` AS `data_center_name`,
|
||||||
|
`account_netstats_view`.`bytesReceived` AS `bytesReceived`,
|
||||||
|
`account_netstats_view`.`bytesSent` AS `bytesSent`,
|
||||||
|
`vmlimit`.`max` AS `vmLimit`,
|
||||||
|
`vmcount`.`count` AS `vmTotal`,
|
||||||
|
`runningvm`.`vmcount` AS `runningVms`,
|
||||||
|
`stoppedvm`.`vmcount` AS `stoppedVms`,
|
||||||
|
`iplimit`.`max` AS `ipLimit`,
|
||||||
|
`ipcount`.`count` AS `ipTotal`,
|
||||||
|
`free_ip_view`.`free_ip` AS `ipFree`,
|
||||||
|
`volumelimit`.`max` AS `volumeLimit`,
|
||||||
|
`volumecount`.`count` AS `volumeTotal`,
|
||||||
|
`snapshotlimit`.`max` AS `snapshotLimit`,
|
||||||
|
`snapshotcount`.`count` AS `snapshotTotal`,
|
||||||
|
`templatelimit`.`max` AS `templateLimit`,
|
||||||
|
`templatecount`.`count` AS `templateTotal`,
|
||||||
|
`vpclimit`.`max` AS `vpcLimit`,
|
||||||
|
`vpccount`.`count` AS `vpcTotal`,
|
||||||
|
`projectlimit`.`max` AS `projectLimit`,
|
||||||
|
`projectcount`.`count` AS `projectTotal`,
|
||||||
|
`networklimit`.`max` AS `networkLimit`,
|
||||||
|
`networkcount`.`count` AS `networkTotal`,
|
||||||
|
`cpulimit`.`max` AS `cpuLimit`,
|
||||||
|
`cpucount`.`count` AS `cpuTotal`,
|
||||||
|
`memorylimit`.`max` AS `memoryLimit`,
|
||||||
|
`memorycount`.`count` AS `memoryTotal`,
|
||||||
|
`primary_storage_limit`.`max` AS `primaryStorageLimit`,
|
||||||
|
`primary_storage_count`.`count` AS `primaryStorageTotal`,
|
||||||
|
`secondary_storage_limit`.`max` AS `secondaryStorageLimit`,
|
||||||
|
`secondary_storage_count`.`count` AS `secondaryStorageTotal`,
|
||||||
|
`async_job`.`id` AS `job_id`,
|
||||||
|
`async_job`.`uuid` AS `job_uuid`,
|
||||||
|
`async_job`.`job_status` AS `job_status`,
|
||||||
|
`async_job`.`account_id` AS `job_account_id`
|
||||||
|
from
|
||||||
|
`cloud`.`free_ip_view`,
|
||||||
|
`cloud`.`account`
|
||||||
|
inner join
|
||||||
|
`cloud`.`domain` ON account.domain_id = domain.id
|
||||||
|
left join
|
||||||
|
`cloud`.`data_center` ON account.default_zone_id = data_center.id
|
||||||
|
left join
|
||||||
|
`cloud`.`account_netstats_view` ON account.id = account_netstats_view.account_id
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` vmlimit ON account.id = vmlimit.account_id
|
||||||
|
and vmlimit.type = 'user_vm' and vmlimit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` vmcount ON account.id = vmcount.account_id
|
||||||
|
and vmcount.type = 'user_vm' and vmcount.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`account_vmstats_view` runningvm ON account.id = runningvm.account_id
|
||||||
|
and runningvm.state = 'Running'
|
||||||
|
left join
|
||||||
|
`cloud`.`account_vmstats_view` stoppedvm ON account.id = stoppedvm.account_id
|
||||||
|
and stoppedvm.state = 'Stopped'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` iplimit ON account.id = iplimit.account_id
|
||||||
|
and iplimit.type = 'public_ip'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` ipcount ON account.id = ipcount.account_id
|
||||||
|
and ipcount.type = 'public_ip'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` volumelimit ON account.id = volumelimit.account_id
|
||||||
|
and volumelimit.type = 'volume' and volumelimit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` volumecount ON account.id = volumecount.account_id
|
||||||
|
and volumecount.type = 'volume' and volumecount.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` snapshotlimit ON account.id = snapshotlimit.account_id
|
||||||
|
and snapshotlimit.type = 'snapshot'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` snapshotcount ON account.id = snapshotcount.account_id
|
||||||
|
and snapshotcount.type = 'snapshot'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` templatelimit ON account.id = templatelimit.account_id
|
||||||
|
and templatelimit.type = 'template'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` templatecount ON account.id = templatecount.account_id
|
||||||
|
and templatecount.type = 'template'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` vpclimit ON account.id = vpclimit.account_id
|
||||||
|
and vpclimit.type = 'vpc'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` vpccount ON account.id = vpccount.account_id
|
||||||
|
and vpccount.type = 'vpc'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` projectlimit ON account.id = projectlimit.account_id
|
||||||
|
and projectlimit.type = 'project'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` projectcount ON account.id = projectcount.account_id
|
||||||
|
and projectcount.type = 'project'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` networklimit ON account.id = networklimit.account_id
|
||||||
|
and networklimit.type = 'network'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` networkcount ON account.id = networkcount.account_id
|
||||||
|
and networkcount.type = 'network'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` cpulimit ON account.id = cpulimit.account_id
|
||||||
|
and cpulimit.type = 'cpu' and cpulimit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` cpucount ON account.id = cpucount.account_id
|
||||||
|
and cpucount.type = 'cpu' and cpucount.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` memorylimit ON account.id = memorylimit.account_id
|
||||||
|
and memorylimit.type = 'memory' and memorylimit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` memorycount ON account.id = memorycount.account_id
|
||||||
|
and memorycount.type = 'memory' and memorycount.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` primary_storage_limit ON account.id = primary_storage_limit.account_id
|
||||||
|
and primary_storage_limit.type = 'primary_storage' and primary_storage_limit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` primary_storage_count ON account.id = primary_storage_count.account_id
|
||||||
|
and primary_storage_count.type = 'primary_storage' and primary_storage_count.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` secondary_storage_limit ON account.id = secondary_storage_limit.account_id
|
||||||
|
and secondary_storage_limit.type = 'secondary_storage'
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` secondary_storage_count ON account.id = secondary_storage_count.account_id
|
||||||
|
and secondary_storage_count.type = 'secondary_storage'
|
||||||
|
left join
|
||||||
|
`cloud`.`async_job` ON async_job.instance_id = account.id
|
||||||
|
and async_job.instance_type = 'Account'
|
||||||
|
and async_job.job_status = 0;
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
-- 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.
|
||||||
|
|
||||||
|
-- VIEW `cloud`.`domain_view`;
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS `cloud`.`domain_view`;
|
||||||
|
CREATE VIEW `cloud`.`domain_view` AS
|
||||||
|
select
|
||||||
|
`domain`.`id` AS `id`,
|
||||||
|
`domain`.`parent` AS `parent`,
|
||||||
|
`domain`.`name` AS `name`,
|
||||||
|
`domain`.`uuid` AS `uuid`,
|
||||||
|
`domain`.`owner` AS `owner`,
|
||||||
|
`domain`.`path` AS `path`,
|
||||||
|
`domain`.`level` AS `level`,
|
||||||
|
`domain`.`child_count` AS `child_count`,
|
||||||
|
`domain`.`next_child_seq` AS `next_child_seq`,
|
||||||
|
`domain`.`created` AS `created`,
|
||||||
|
`domain`.`removed` AS `removed`,
|
||||||
|
`domain`.`state` AS `state`,
|
||||||
|
`domain`.`network_domain` AS `network_domain`,
|
||||||
|
`domain`.`type` AS `type`,
|
||||||
|
`vmlimit`.`max` AS `vmLimit`,
|
||||||
|
`vmcount`.`count` AS `vmTotal`,
|
||||||
|
`iplimit`.`max` AS `ipLimit`,
|
||||||
|
`ipcount`.`count` AS `ipTotal`,
|
||||||
|
`volumelimit`.`max` AS `volumeLimit`,
|
||||||
|
`volumecount`.`count` AS `volumeTotal`,
|
||||||
|
`snapshotlimit`.`max` AS `snapshotLimit`,
|
||||||
|
`snapshotcount`.`count` AS `snapshotTotal`,
|
||||||
|
`templatelimit`.`max` AS `templateLimit`,
|
||||||
|
`templatecount`.`count` AS `templateTotal`,
|
||||||
|
`vpclimit`.`max` AS `vpcLimit`,
|
||||||
|
`vpccount`.`count` AS `vpcTotal`,
|
||||||
|
`projectlimit`.`max` AS `projectLimit`,
|
||||||
|
`projectcount`.`count` AS `projectTotal`,
|
||||||
|
`networklimit`.`max` AS `networkLimit`,
|
||||||
|
`networkcount`.`count` AS `networkTotal`,
|
||||||
|
`cpulimit`.`max` AS `cpuLimit`,
|
||||||
|
`cpucount`.`count` AS `cpuTotal`,
|
||||||
|
`memorylimit`.`max` AS `memoryLimit`,
|
||||||
|
`memorycount`.`count` AS `memoryTotal`,
|
||||||
|
`primary_storage_limit`.`max` AS `primaryStorageLimit`,
|
||||||
|
`primary_storage_count`.`count` AS `primaryStorageTotal`,
|
||||||
|
`secondary_storage_limit`.`max` AS `secondaryStorageLimit`,
|
||||||
|
`secondary_storage_count`.`count` AS `secondaryStorageTotal`
|
||||||
|
from
|
||||||
|
`cloud`.`domain`
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` vmlimit ON domain.id = vmlimit.domain_id
|
||||||
|
and vmlimit.type = 'user_vm' and vmlimit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` vmcount ON domain.id = vmcount.domain_id
|
||||||
|
and vmcount.type = 'user_vm' and vmcount.tag IS NULL
|
||||||
|
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' and volumelimit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` volumecount ON domain.id = volumecount.domain_id
|
||||||
|
and volumecount.type = 'volume' and volumecount.tag IS NULL
|
||||||
|
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' and cpulimit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` cpucount ON domain.id = cpucount.domain_id
|
||||||
|
and cpucount.type = 'cpu' and cpucount.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` memorylimit ON domain.id = memorylimit.domain_id
|
||||||
|
and memorylimit.type = 'memory' and memorylimit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` memorycount ON domain.id = memorycount.domain_id
|
||||||
|
and memorycount.type = 'memory' and memorycount.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_limit` primary_storage_limit ON domain.id = primary_storage_limit.domain_id
|
||||||
|
and primary_storage_limit.type = 'primary_storage' and primary_storage_limit.tag IS NULL
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_count` primary_storage_count ON domain.id = primary_storage_count.domain_id
|
||||||
|
and primary_storage_count.type = 'primary_storage' and primary_storage_count.tag IS NULL
|
||||||
|
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';
|
||||||
@ -1,84 +1,126 @@
|
|||||||
// Licensed to the Apache Software Foundation (ASF) under one
|
// Licensed to the Apache Software Foundation (ASF) under one
|
||||||
// or more contributor license agreements. See the NOTICE file
|
// or more contributor license agreements. See the NOTICE file
|
||||||
// distributed with this work for additional information
|
// distributed with this work for additional information
|
||||||
// regarding copyright ownership. The ASF licenses this file
|
// regarding copyright ownership. The ASF licenses this file
|
||||||
// to you under the Apache License, Version 2.0 (the
|
// to you under the Apache License, Version 2.0 (the
|
||||||
// "License"); you may not use this file except in compliance
|
// "License"); you may not use this file except in compliance
|
||||||
// with the License. You may obtain a copy of the License at
|
// with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing,
|
// Unless required by applicable law or agreed to in writing,
|
||||||
// software distributed under the License is distributed on an
|
// software distributed under the License is distributed on an
|
||||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
// KIND, either express or implied. See the License for the
|
// KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.host;
|
package com.cloud.host;
|
||||||
|
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.offering.ServiceOffering;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import java.util.Arrays;
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
import java.util.List;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
import java.util.Arrays;
|
||||||
import static org.junit.Assert.assertFalse;
|
import java.util.List;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import org.junit.Test;
|
import static org.junit.Assert.assertFalse;
|
||||||
import org.junit.Before;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.junit.Test;
|
||||||
public class HostVOTest {
|
import org.junit.Before;
|
||||||
HostVO host;
|
import org.mockito.Mockito;
|
||||||
ServiceOfferingVO offering;
|
|
||||||
|
public class HostVOTest {
|
||||||
@Before
|
HostVO host;
|
||||||
public void setUp() throws Exception {
|
ServiceOfferingVO offering;
|
||||||
host = new HostVO();
|
|
||||||
offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0,
|
@Before
|
||||||
false, "TestSO", false,VirtualMachine.Type.User,false);
|
public void setUp() throws Exception {
|
||||||
}
|
host = new HostVO();
|
||||||
|
offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0,
|
||||||
@Test
|
false, "TestSO", false,VirtualMachine.Type.User,false);
|
||||||
public void testNoSO() {
|
}
|
||||||
assertFalse(host.checkHostServiceOfferingTags(null));
|
|
||||||
}
|
@Test
|
||||||
|
public void testNoSO() {
|
||||||
@Test
|
assertFalse(host.checkHostServiceOfferingTags(null));
|
||||||
public void testNoTag() {
|
}
|
||||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
|
||||||
}
|
@Test
|
||||||
|
public void testNoTag() {
|
||||||
@Test
|
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||||
public void testRightTag() {
|
}
|
||||||
host.setHostTags(Arrays.asList("tag1","tag2"), false);
|
|
||||||
offering.setHostTag("tag2,tag1");
|
@Test
|
||||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
public void testRightTag() {
|
||||||
}
|
host.setHostTags(Arrays.asList("tag1","tag2"), false);
|
||||||
|
offering.setHostTag("tag2,tag1");
|
||||||
@Test
|
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||||
public void testWrongTag() {
|
}
|
||||||
host.setHostTags(Arrays.asList("tag1","tag2"), false);
|
|
||||||
offering.setHostTag("tag2,tag4");
|
@Test
|
||||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
public void testWrongTag() {
|
||||||
}
|
host.setHostTags(Arrays.asList("tag1","tag2"), false);
|
||||||
|
offering.setHostTag("tag2,tag4");
|
||||||
@Test
|
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||||
public void checkHostServiceOfferingTagsTestRuleTagWithServiceTagThatMatches() {
|
}
|
||||||
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
|
||||||
offering.setHostTag("A");
|
@Test
|
||||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
public void checkHostServiceOfferingTagsTestRuleTagWithServiceTagThatMatches() {
|
||||||
}
|
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
||||||
|
offering.setHostTag("A");
|
||||||
@Test
|
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||||
public void checkHostServiceOfferingTagsTestRuleTagWithServiceTagThatDoesNotMatch() {
|
}
|
||||||
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
|
||||||
offering.setHostTag("B");
|
@Test
|
||||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
public void checkHostServiceOfferingTagsTestRuleTagWithServiceTagThatDoesNotMatch() {
|
||||||
}
|
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
||||||
|
offering.setHostTag("B");
|
||||||
@Test
|
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||||
public void checkHostServiceOfferingTagsTestRuleTagWithNullServiceTag() {
|
}
|
||||||
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
|
||||||
offering.setHostTag(null);
|
@Test
|
||||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
public void checkHostServiceOfferingTagsTestRuleTagWithNullServiceTag() {
|
||||||
}
|
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
||||||
}
|
offering.setHostTag(null);
|
||||||
|
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEitherNoSOOrTemplate() {
|
||||||
|
assertFalse(host.checkHostServiceOfferingAndTemplateTags(null, Mockito.mock(VirtualMachineTemplate.class)));
|
||||||
|
assertFalse(host.checkHostServiceOfferingAndTemplateTags(Mockito.mock(ServiceOffering.class), null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNoTagOfferingTemplate() {
|
||||||
|
assertTrue(host.checkHostServiceOfferingAndTemplateTags(offering, Mockito.mock(VirtualMachineTemplate.class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRightTagOfferingTemplate() {
|
||||||
|
host.setHostTags(Arrays.asList("tag1", "tag2"), false);
|
||||||
|
offering.setHostTag("tag2,tag1");
|
||||||
|
assertTrue(host.checkHostServiceOfferingAndTemplateTags(offering, Mockito.mock(VirtualMachineTemplate.class)));
|
||||||
|
host.setHostTags(Arrays.asList("tag1", "tag2", "tag3"), false);
|
||||||
|
offering.setHostTag("tag2,tag1");
|
||||||
|
VirtualMachineTemplate template = Mockito.mock(VirtualMachineTemplate.class);
|
||||||
|
Mockito.when(template.getTemplateTag()).thenReturn("tag3");
|
||||||
|
assertTrue(host.checkHostServiceOfferingAndTemplateTags(offering, template));
|
||||||
|
host.setHostTags(List.of("tag3"), false);
|
||||||
|
offering.setHostTag(null);
|
||||||
|
assertTrue(host.checkHostServiceOfferingAndTemplateTags(offering, template));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrongOfferingTag() {
|
||||||
|
host.setHostTags(Arrays.asList("tag1","tag2"), false);
|
||||||
|
offering.setHostTag("tag2,tag4");
|
||||||
|
VirtualMachineTemplate template = Mockito.mock(VirtualMachineTemplate.class);
|
||||||
|
Mockito.when(template.getTemplateTag()).thenReturn("tag1");
|
||||||
|
assertFalse(host.checkHostServiceOfferingAndTemplateTags(offering, template));
|
||||||
|
offering.setHostTag("tag1,tag2");
|
||||||
|
template = Mockito.mock(VirtualMachineTemplate.class);
|
||||||
|
Mockito.when(template.getTemplateTag()).thenReturn("tag3");
|
||||||
|
assertFalse(host.checkHostServiceOfferingAndTemplateTags(offering, template));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -308,10 +308,14 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Volume volume = volumeDao.findById(dskCh.getVolumeId());
|
Volume volume = null;
|
||||||
if(!storageMgr.storagePoolCompatibleWithVolumePool(pool, volume)) {
|
boolean isTempVolume = dskCh.getVolumeId() == Volume.DISK_OFFERING_SUITABILITY_CHECK_VOLUME_ID;
|
||||||
logger.debug(String.format("Pool [%s] is not compatible with volume [%s], skipping it.", pool, volume));
|
if (!isTempVolume) {
|
||||||
return false;
|
volume = volumeDao.findById(dskCh.getVolumeId());
|
||||||
|
if (!storageMgr.storagePoolCompatibleWithVolumePool(pool, volume)) {
|
||||||
|
logger.debug(String.format("Pool [%s] is not compatible with volume [%s], skipping it.", pool, volume));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pool.isManaged() && !storageUtil.managedStoragePoolCanScale(pool, plan.getClusterId(), plan.getHostId())) {
|
if (pool.isManaged() && !storageUtil.managedStoragePoolCanScale(pool, plan.getClusterId(), plan.getHostId())) {
|
||||||
@ -336,8 +340,10 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolCompliantWithStoragePolicy(requestVolumeDiskProfilePairs, pool);
|
boolean isStoragePoolStoragePolicyCompliance = isTempVolume ?
|
||||||
if (!isStoragePoolStoragepolicyComplaince) {
|
storageMgr.isStoragePoolCompliantWithStoragePolicy(dskCh.getDiskOfferingId(), pool) :
|
||||||
|
storageMgr.isStoragePoolCompliantWithStoragePolicy(requestVolumeDiskProfilePairs, pool);
|
||||||
|
if (!isStoragePoolStoragePolicyCompliance) {
|
||||||
logger.debug(String.format("Skipping allocation of pool [%s] to volume [%s] because this pool is not compliant with the storage policy required by the volume.", pool, volume));
|
logger.debug(String.format("Skipping allocation of pool [%s] to volume [%s] because this pool is not compliant with the storage policy required by the volume.", pool, volume));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -346,7 +352,11 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return storageMgr.storagePoolHasEnoughIops(requestVolumeDiskProfilePairs, pool) && storageMgr.storagePoolHasEnoughSpace(requestVolumeDiskProfilePairs, pool, plan.getClusterId());
|
return isTempVolume ?
|
||||||
|
(storageMgr.storagePoolHasEnoughIops(dskCh.getMinIops(), pool) &&
|
||||||
|
storageMgr.storagePoolHasEnoughSpace(dskCh.getSize(), pool)):
|
||||||
|
(storageMgr.storagePoolHasEnoughIops(requestVolumeDiskProfilePairs, pool) &&
|
||||||
|
storageMgr.storagePoolHasEnoughSpace(requestVolumeDiskProfilePairs, pool, plan.getClusterId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkDiskProvisioningSupport(DiskProfile dskCh, StoragePool pool) {
|
private boolean checkDiskProvisioningSupport(DiskProfile dskCh, StoragePool pool) {
|
||||||
|
|||||||
@ -126,6 +126,7 @@ import com.cloud.storage.Volume;
|
|||||||
import com.cloud.storage.Volume.State;
|
import com.cloud.storage.Volume.State;
|
||||||
import com.cloud.storage.VolumeDetailVO;
|
import com.cloud.storage.VolumeDetailVO;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||||
import com.cloud.storage.dao.VolumeDao;
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
@ -206,6 +207,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
private SnapshotApiService snapshotApiService;
|
private SnapshotApiService snapshotApiService;
|
||||||
@Inject
|
@Inject
|
||||||
private PassphraseDao passphraseDao;
|
private PassphraseDao passphraseDao;
|
||||||
|
@Inject
|
||||||
|
private DiskOfferingDao diskOfferingDao;
|
||||||
|
|
||||||
public VolumeServiceImpl() {
|
public VolumeServiceImpl() {
|
||||||
}
|
}
|
||||||
@ -1610,8 +1613,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
|
|
||||||
if (vol.getAttachedVM() == null || vol.getAttachedVM().getType() == VirtualMachine.Type.User) {
|
if (vol.getAttachedVM() == null || vol.getAttachedVM().getType() == VirtualMachine.Type.User) {
|
||||||
// Decrement the resource count for volumes and primary storage belonging user VM's only
|
// Decrement the resource count for volumes and primary storage belonging user VM's only
|
||||||
_resourceLimitMgr.decrementResourceCount(vol.getAccountId(), ResourceType.volume, vol.isDisplay());
|
_resourceLimitMgr.decrementVolumeResourceCount(vol.getAccountId(), vol.isDisplay(), vol.getSize(), diskOfferingDao.findById(vol.getDiskOfferingId()));
|
||||||
_resourceLimitMgr.decrementResourceCount(vol.getAccountId(), ResourceType.primary_storage, vol.isDisplay(), new Long(vol.getSize()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,9 +22,10 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.ListUtils;
|
import org.apache.commons.collections.ListUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.agent.manager.allocator.HostAllocator;
|
import com.cloud.agent.manager.allocator.HostAllocator;
|
||||||
@ -39,8 +40,10 @@ import com.cloud.host.HostVO;
|
|||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
import com.cloud.resource.ResourceManager;
|
import com.cloud.resource.ResourceManager;
|
||||||
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.component.AdapterBase;
|
import com.cloud.utils.component.AdapterBase;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import com.cloud.vm.VirtualMachineProfile;
|
import com.cloud.vm.VirtualMachineProfile;
|
||||||
|
|
||||||
@ -57,6 +60,27 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
|
|||||||
@Inject
|
@Inject
|
||||||
private CapacityManager capacityManager;
|
private CapacityManager capacityManager;
|
||||||
|
|
||||||
|
protected List<HostVO> listHostsByTags(Host.Type type, long dcId, Long podId, Long clusterId, String offeringHostTag, String templateTag) {
|
||||||
|
List<HostVO> taggedHosts = new ArrayList<>();
|
||||||
|
if (offeringHostTag != null) {
|
||||||
|
taggedHosts.addAll(_hostDao.listByHostTag(type, clusterId, podId, dcId, offeringHostTag));
|
||||||
|
}
|
||||||
|
if (templateTag != null) {
|
||||||
|
List<HostVO> templateTaggedHosts = _hostDao.listByHostTag(type, clusterId, podId, dcId, templateTag);
|
||||||
|
if (taggedHosts.isEmpty()) {
|
||||||
|
taggedHosts = templateTaggedHosts;
|
||||||
|
} else {
|
||||||
|
taggedHosts.retainAll(templateTaggedHosts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(String.format("Found %d hosts %s with type: %s, zone ID: %d, pod ID: %d, cluster ID: %s, offering host tag(s): %s, template tag: %s",
|
||||||
|
taggedHosts.size(),
|
||||||
|
(taggedHosts.isEmpty() ? "" : String.format("(%s)", StringUtils.join(taggedHosts.stream().map(HostVO::getId).toArray(), ","))),
|
||||||
|
type.name(), dcId, podId, clusterId, offeringHostTag, templateTag));
|
||||||
|
}
|
||||||
|
return taggedHosts;
|
||||||
|
}
|
||||||
private List<Host> findSuitableHosts(VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type,
|
private List<Host> findSuitableHosts(VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type,
|
||||||
ExcludeList avoid, List<? extends Host> hosts, int returnUpTo,
|
ExcludeList avoid, List<? extends Host> hosts, int returnUpTo,
|
||||||
boolean considerReservedCapacity) {
|
boolean considerReservedCapacity) {
|
||||||
@ -70,30 +94,34 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
|
|||||||
if (type == Host.Type.Storage) {
|
if (type == Host.Type.Storage) {
|
||||||
return suitableHosts;
|
return suitableHosts;
|
||||||
}
|
}
|
||||||
String hostTag = offering.getHostTag();
|
String offeringHostTag = offering.getHostTag();
|
||||||
if (hostTag != null) {
|
VMTemplateVO template = (VMTemplateVO)vmProfile.getTemplate();
|
||||||
logger.debug(String.format("Looking for hosts in dc [%s], pod [%s], cluster [%s] and complying with host tag [%s].", dcId, podId, clusterId, hostTag));
|
String templateTag = template.getTemplateTag();
|
||||||
|
String hostTag = null;
|
||||||
|
if (ObjectUtils.anyNull(offeringHostTag, templateTag)) {
|
||||||
|
hostTag = offeringHostTag;
|
||||||
|
hostTag = hostTag == null ? templateTag : String.format("%s, %s", hostTag, templateTag);
|
||||||
|
logger.debug(String.format("Looking for hosts in dc [%s], pod [%s], cluster [%s] and complying with host tag(s): [%s]", dcId, podId, clusterId, hostTag));
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
||||||
}
|
}
|
||||||
if (hosts != null) {
|
if (hosts != null) {
|
||||||
// retain all computing hosts, regardless of whether they support routing...it's random after all
|
// retain all computing hosts, regardless of whether they support routing...it's random after all
|
||||||
hostsCopy = new ArrayList<Host>(hosts);
|
hostsCopy = new ArrayList<Host>(hosts);
|
||||||
if (hostTag != null) {
|
if (ObjectUtils.anyNotNull(offeringHostTag, templateTag)) {
|
||||||
hostsCopy.retainAll(_hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag));
|
hostsCopy.retainAll(listHostsByTags(type, dcId, podId, clusterId, offeringHostTag, templateTag));
|
||||||
} else {
|
} else {
|
||||||
hostsCopy.retainAll(_hostDao.listAllHostsThatHaveNoRuleTag(type, clusterId, podId, dcId));
|
hostsCopy.retainAll(_hostDao.listAllHostsThatHaveNoRuleTag(type, clusterId, podId, dcId));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// list all computing hosts, regardless of whether they support routing...it's random after all
|
// list all computing hosts, regardless of whether they support routing...it's random after all
|
||||||
hostsCopy = new ArrayList<HostVO>();
|
if (offeringHostTag != null) {
|
||||||
if (hostTag != null) {
|
hostsCopy = listHostsByTags(type, dcId, podId, clusterId, offeringHostTag, templateTag);
|
||||||
hostsCopy = _hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag);
|
|
||||||
} else {
|
} else {
|
||||||
hostsCopy = _hostDao.listAllHostsThatHaveNoRuleTag(type, clusterId, podId, dcId);
|
hostsCopy = _hostDao.listAllHostsThatHaveNoRuleTag(type, clusterId, podId, dcId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hostsCopy = ListUtils.union(hostsCopy, _hostDao.findHostsWithTagRuleThatMatchComputeOferringTags(hostTag));
|
hostsCopy = ListUtils.union(hostsCopy, _hostDao.findHostsWithTagRuleThatMatchComputeOferringTags(offeringHostTag));
|
||||||
|
|
||||||
if (hostsCopy.isEmpty()) {
|
if (hostsCopy.isEmpty()) {
|
||||||
logger.error(String.format("No suitable host found for vm [%s] with tags [%s].", vmProfile, hostTag));
|
logger.error(String.format("No suitable host found for vm [%s] with tags [%s].", vmProfile, hostTag));
|
||||||
|
|||||||
@ -0,0 +1,80 @@
|
|||||||
|
// 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.agent.manager.allocator.impl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import com.cloud.host.Host;
|
||||||
|
import com.cloud.host.HostVO;
|
||||||
|
import com.cloud.host.dao.HostDao;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class RandomAllocatorTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
HostDao hostDao;
|
||||||
|
@InjectMocks
|
||||||
|
RandomAllocator randomAllocator;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListHostsByTags() {
|
||||||
|
Host.Type type = Host.Type.Routing;
|
||||||
|
Long id = 1L;
|
||||||
|
String templateTag = "tag1";
|
||||||
|
String offeringTag = "tag2";
|
||||||
|
HostVO host1 = Mockito.mock(HostVO.class);
|
||||||
|
HostVO host2 = Mockito.mock(HostVO.class);
|
||||||
|
Mockito.when(hostDao.listByHostTag(type, id, id, id, offeringTag)).thenReturn(List.of(host1, host2));
|
||||||
|
|
||||||
|
// No template tagged host
|
||||||
|
Mockito.when(hostDao.listByHostTag(type, id, id, id, templateTag)).thenReturn(new ArrayList<>());
|
||||||
|
List<HostVO> result = randomAllocator.listHostsByTags(type, id, id, id, offeringTag, templateTag);
|
||||||
|
Assert.assertTrue(CollectionUtils.isEmpty(result));
|
||||||
|
|
||||||
|
// Different template tagged host
|
||||||
|
HostVO host3 = Mockito.mock(HostVO.class);
|
||||||
|
Mockito.when(hostDao.listByHostTag(type, id, id, id, templateTag)).thenReturn(List.of(host3));
|
||||||
|
result = randomAllocator.listHostsByTags(type, id, id, id, offeringTag, templateTag);
|
||||||
|
Assert.assertTrue(CollectionUtils.isEmpty(result));
|
||||||
|
|
||||||
|
// Matching template tagged host
|
||||||
|
Mockito.when(hostDao.listByHostTag(type, id, id, id, templateTag)).thenReturn(List.of(host1));
|
||||||
|
result = randomAllocator.listHostsByTags(type, id, id, id, offeringTag, templateTag);
|
||||||
|
Assert.assertFalse(CollectionUtils.isEmpty(result));
|
||||||
|
Assert.assertEquals(1, result.size());
|
||||||
|
|
||||||
|
// No template tag
|
||||||
|
result = randomAllocator.listHostsByTags(type, id, id, id, offeringTag, null);
|
||||||
|
Assert.assertFalse(CollectionUtils.isEmpty(result));
|
||||||
|
Assert.assertEquals(2, result.size());
|
||||||
|
|
||||||
|
// No offering tag
|
||||||
|
result = randomAllocator.listHostsByTags(type, id, id, id, null, templateTag);
|
||||||
|
Assert.assertFalse(CollectionUtils.isEmpty(result));
|
||||||
|
Assert.assertEquals(1, result.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -50,6 +50,7 @@ import com.cloud.agent.api.storage.ListTemplateCommand;
|
|||||||
import com.cloud.agent.api.storage.ListVolumeCommand;
|
import com.cloud.agent.api.storage.ListVolumeCommand;
|
||||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
||||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||||
|
import com.cloud.agent.api.storage.ResizeVolumeCommand;
|
||||||
import com.cloud.utils.component.Manager;
|
import com.cloud.utils.component.Manager;
|
||||||
|
|
||||||
public interface MockStorageManager extends Manager {
|
public interface MockStorageManager extends Manager {
|
||||||
@ -113,4 +114,6 @@ public interface MockStorageManager extends Manager {
|
|||||||
public UploadStatusAnswer getUploadStatus(UploadStatusCommand cmd);
|
public UploadStatusAnswer getUploadStatus(UploadStatusCommand cmd);
|
||||||
|
|
||||||
Answer handleConfigDriveIso(HandleConfigDriveIsoCommand cmd);
|
Answer handleConfigDriveIso(HandleConfigDriveIsoCommand cmd);
|
||||||
|
|
||||||
|
Answer handleResizeVolume(ResizeVolumeCommand cmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,6 +78,8 @@ import com.cloud.agent.api.storage.ListVolumeAnswer;
|
|||||||
import com.cloud.agent.api.storage.ListVolumeCommand;
|
import com.cloud.agent.api.storage.ListVolumeCommand;
|
||||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
||||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||||
|
import com.cloud.agent.api.storage.ResizeVolumeAnswer;
|
||||||
|
import com.cloud.agent.api.storage.ResizeVolumeCommand;
|
||||||
import com.cloud.agent.api.to.DataStoreTO;
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
import com.cloud.agent.api.to.NfsTO;
|
import com.cloud.agent.api.to.NfsTO;
|
||||||
import com.cloud.agent.api.to.StorageFilerTO;
|
import com.cloud.agent.api.to.StorageFilerTO;
|
||||||
@ -1307,4 +1309,32 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
|
|||||||
|
|
||||||
return new Answer(cmd);
|
return new Answer(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Answer handleResizeVolume(ResizeVolumeCommand cmd) {
|
||||||
|
Long currentSize = cmd.getCurrentSize();
|
||||||
|
Long newSize = cmd.getNewSize();
|
||||||
|
MockStoragePoolVO storagePool = null;
|
||||||
|
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
|
||||||
|
try {
|
||||||
|
txn.start();
|
||||||
|
storagePool = _mockStoragePoolDao.findByUuid(cmd.getPoolUuid());
|
||||||
|
txn.commit();
|
||||||
|
if (storagePool == null) {
|
||||||
|
return new ResizeVolumeAnswer(cmd, false, "Failed to find storage pool: " + cmd.getPoolUuid());
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
txn.rollback();
|
||||||
|
throw new CloudRuntimeException("Error when finding storage " + cmd.getPoolUuid(), ex);
|
||||||
|
} finally {
|
||||||
|
txn.close();
|
||||||
|
txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
|
||||||
|
txn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSize >= currentSize) {
|
||||||
|
return new ResizeVolumeAnswer(cmd, true, "", newSize);
|
||||||
|
}
|
||||||
|
return new ResizeVolumeAnswer(cmd, false, "Failed to resize");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -114,6 +114,7 @@ import com.cloud.agent.api.storage.DestroyCommand;
|
|||||||
import com.cloud.agent.api.storage.ListTemplateCommand;
|
import com.cloud.agent.api.storage.ListTemplateCommand;
|
||||||
import com.cloud.agent.api.storage.ListVolumeCommand;
|
import com.cloud.agent.api.storage.ListVolumeCommand;
|
||||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||||
|
import com.cloud.agent.api.storage.ResizeVolumeCommand;
|
||||||
import com.cloud.api.commands.CleanupSimulatorMockCmd;
|
import com.cloud.api.commands.CleanupSimulatorMockCmd;
|
||||||
import com.cloud.api.commands.ConfigureSimulatorCmd;
|
import com.cloud.api.commands.ConfigureSimulatorCmd;
|
||||||
import com.cloud.api.commands.ConfigureSimulatorHAProviderState;
|
import com.cloud.api.commands.ConfigureSimulatorHAProviderState;
|
||||||
@ -440,6 +441,8 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage
|
|||||||
answer = _mockVmMgr.fence((FenceCommand)cmd);
|
answer = _mockVmMgr.fence((FenceCommand)cmd);
|
||||||
} else if (cmd instanceof HandleConfigDriveIsoCommand) {
|
} else if (cmd instanceof HandleConfigDriveIsoCommand) {
|
||||||
answer = _mockStorageMgr.handleConfigDriveIso((HandleConfigDriveIsoCommand)cmd);
|
answer = _mockStorageMgr.handleConfigDriveIso((HandleConfigDriveIsoCommand)cmd);
|
||||||
|
} else if (cmd instanceof ResizeVolumeCommand) {
|
||||||
|
answer = _mockStorageMgr.handleResizeVolume((ResizeVolumeCommand)cmd);
|
||||||
} else if (cmd instanceof GetRouterAlertsCommand
|
} else if (cmd instanceof GetRouterAlertsCommand
|
||||||
|| cmd instanceof VpnUsersCfgCommand
|
|| cmd instanceof VpnUsersCfgCommand
|
||||||
|| cmd instanceof RemoteAccessVpnCfgCommand
|
|| cmd instanceof RemoteAccessVpnCfgCommand
|
||||||
|
|||||||
@ -25,15 +25,9 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import com.cloud.configuration.dao.ResourceCountDao;
|
|
||||||
import com.cloud.dc.DedicatedResourceVO;
|
|
||||||
import com.cloud.dc.dao.DedicatedResourceDao;
|
|
||||||
import com.cloud.host.HostStats;
|
|
||||||
import com.cloud.host.HostTagVO;
|
|
||||||
import com.cloud.user.Account;
|
|
||||||
import com.cloud.user.dao.AccountDao;
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.cloud.alert.AlertManager;
|
import com.cloud.alert.AlertManager;
|
||||||
import com.cloud.api.ApiDBUtils;
|
import com.cloud.api.ApiDBUtils;
|
||||||
@ -43,16 +37,21 @@ import com.cloud.api.query.vo.DomainJoinVO;
|
|||||||
import com.cloud.api.query.vo.StoragePoolJoinVO;
|
import com.cloud.api.query.vo.StoragePoolJoinVO;
|
||||||
import com.cloud.capacity.Capacity;
|
import com.cloud.capacity.Capacity;
|
||||||
import com.cloud.capacity.CapacityManager;
|
import com.cloud.capacity.CapacityManager;
|
||||||
import com.cloud.capacity.CapacityVO;
|
|
||||||
import com.cloud.capacity.CapacityState;
|
import com.cloud.capacity.CapacityState;
|
||||||
|
import com.cloud.capacity.CapacityVO;
|
||||||
import com.cloud.capacity.dao.CapacityDao;
|
import com.cloud.capacity.dao.CapacityDao;
|
||||||
import com.cloud.capacity.dao.CapacityDaoImpl;
|
import com.cloud.capacity.dao.CapacityDaoImpl;
|
||||||
import com.cloud.configuration.Resource;
|
import com.cloud.configuration.Resource;
|
||||||
|
import com.cloud.configuration.dao.ResourceCountDao;
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
|
import com.cloud.dc.DedicatedResourceVO;
|
||||||
import com.cloud.dc.Vlan;
|
import com.cloud.dc.Vlan;
|
||||||
import com.cloud.dc.dao.DataCenterDao;
|
import com.cloud.dc.dao.DataCenterDao;
|
||||||
import com.cloud.dc.dao.DataCenterIpAddressDao;
|
import com.cloud.dc.dao.DataCenterIpAddressDao;
|
||||||
|
import com.cloud.dc.dao.DedicatedResourceDao;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
|
import com.cloud.host.HostStats;
|
||||||
|
import com.cloud.host.HostTagVO;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
import com.cloud.host.Status;
|
import com.cloud.host.Status;
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
@ -63,7 +62,8 @@ import com.cloud.storage.StorageStats;
|
|||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
import com.cloud.storage.dao.VolumeDao;
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.user.dao.AccountDao;
|
||||||
import com.cloud.utils.Ternary;
|
import com.cloud.utils.Ternary;
|
||||||
import com.cloud.utils.component.Manager;
|
import com.cloud.utils.component.Manager;
|
||||||
import com.cloud.utils.component.ManagerBase;
|
import com.cloud.utils.component.ManagerBase;
|
||||||
@ -438,13 +438,13 @@ public class PrometheusExporterImpl extends ManagerBase implements PrometheusExp
|
|||||||
}
|
}
|
||||||
|
|
||||||
long memoryUsed = _resourceCountDao.getResourceCount(domain.getId(), Resource.ResourceOwnerType.Domain,
|
long memoryUsed = _resourceCountDao.getResourceCount(domain.getId(), Resource.ResourceOwnerType.Domain,
|
||||||
Resource.ResourceType.memory);
|
Resource.ResourceType.memory, null);
|
||||||
long cpuUsed = _resourceCountDao.getResourceCount(domain.getId(), Resource.ResourceOwnerType.Domain,
|
long cpuUsed = _resourceCountDao.getResourceCount(domain.getId(), Resource.ResourceOwnerType.Domain,
|
||||||
Resource.ResourceType.cpu);
|
Resource.ResourceType.cpu, null);
|
||||||
long primaryStorageUsed = _resourceCountDao.getResourceCount(domain.getId(), Resource.ResourceOwnerType.Domain,
|
long primaryStorageUsed = _resourceCountDao.getResourceCount(domain.getId(), Resource.ResourceOwnerType.Domain,
|
||||||
Resource.ResourceType.primary_storage);
|
Resource.ResourceType.primary_storage, null);
|
||||||
long secondaryStorageUsed = _resourceCountDao.getResourceCount(domain.getId(), Resource.ResourceOwnerType.Domain,
|
long secondaryStorageUsed = _resourceCountDao.getResourceCount(domain.getId(), Resource.ResourceOwnerType.Domain,
|
||||||
Resource.ResourceType.secondary_storage);
|
Resource.ResourceType.secondary_storage, null);
|
||||||
|
|
||||||
metricsList.add(new ItemPerDomainResourceCount(memoryUsed, domain.getPath(), Resource.ResourceType.memory.getName()));
|
metricsList.add(new ItemPerDomainResourceCount(memoryUsed, domain.getPath(), Resource.ResourceType.memory.getName()));
|
||||||
metricsList.add(new ItemPerDomainResourceCount(cpuUsed, domain.getPath(), Resource.ResourceType.cpu.getName()));
|
metricsList.add(new ItemPerDomainResourceCount(cpuUsed, domain.getPath(), Resource.ResourceType.cpu.getName()));
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import java.util.List;
|
|||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -53,6 +54,7 @@ import org.apache.cloudstack.api.response.HostTagResponse;
|
|||||||
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.InstanceGroupResponse;
|
import org.apache.cloudstack.api.response.InstanceGroupResponse;
|
||||||
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
|
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||||
@ -85,6 +87,8 @@ import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
|
|||||||
import org.apache.cloudstack.resourcedetail.SnapshotPolicyDetailVO;
|
import org.apache.cloudstack.resourcedetail.SnapshotPolicyDetailVO;
|
||||||
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
||||||
import org.apache.cloudstack.resourcedetail.dao.SnapshotPolicyDetailsDao;
|
import org.apache.cloudstack.resourcedetail.dao.SnapshotPolicyDetailsDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
|
|
||||||
@ -337,6 +341,7 @@ import com.cloud.vm.UserVmManager;
|
|||||||
import com.cloud.vm.UserVmVO;
|
import com.cloud.vm.UserVmVO;
|
||||||
import com.cloud.vm.VMInstanceVO;
|
import com.cloud.vm.VMInstanceVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
import com.cloud.vm.VirtualMachineManager;
|
||||||
import com.cloud.vm.VmDetailConstants;
|
import com.cloud.vm.VmDetailConstants;
|
||||||
import com.cloud.vm.VmStats;
|
import com.cloud.vm.VmStats;
|
||||||
import com.cloud.vm.dao.ConsoleProxyDao;
|
import com.cloud.vm.dao.ConsoleProxyDao;
|
||||||
@ -350,10 +355,6 @@ import com.cloud.vm.dao.VMInstanceDao;
|
|||||||
import com.cloud.vm.snapshot.VMSnapshot;
|
import com.cloud.vm.snapshot.VMSnapshot;
|
||||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
|
||||||
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
|
||||||
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
|
||||||
|
|
||||||
public class ApiDBUtils {
|
public class ApiDBUtils {
|
||||||
private static ManagementServer s_ms;
|
private static ManagementServer s_ms;
|
||||||
static AsyncJobManager s_asyncMgr;
|
static AsyncJobManager s_asyncMgr;
|
||||||
@ -489,6 +490,7 @@ public class ApiDBUtils {
|
|||||||
static ObjectStoreDao s_objectStoreDao;
|
static ObjectStoreDao s_objectStoreDao;
|
||||||
|
|
||||||
static BucketDao s_bucketDao;
|
static BucketDao s_bucketDao;
|
||||||
|
static VirtualMachineManager s_virtualMachineManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ManagementServer ms;
|
private ManagementServer ms;
|
||||||
@ -752,6 +754,8 @@ public class ApiDBUtils {
|
|||||||
private ObjectStoreDao objectStoreDao;
|
private ObjectStoreDao objectStoreDao;
|
||||||
@Inject
|
@Inject
|
||||||
private BucketDao bucketDao;
|
private BucketDao bucketDao;
|
||||||
|
@Inject
|
||||||
|
private VirtualMachineManager virtualMachineManager;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
void init() {
|
void init() {
|
||||||
@ -886,6 +890,7 @@ public class ApiDBUtils {
|
|||||||
s_resourceManagerUtil = resourceManagerUtil;
|
s_resourceManagerUtil = resourceManagerUtil;
|
||||||
s_objectStoreDao = objectStoreDao;
|
s_objectStoreDao = objectStoreDao;
|
||||||
s_bucketDao = bucketDao;
|
s_bucketDao = bucketDao;
|
||||||
|
s_virtualMachineManager = virtualMachineManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////
|
||||||
@ -937,7 +942,7 @@ public class ApiDBUtils {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s_resourceLimitMgr.findCorrectResourceLimitForDomain(domain, type);
|
return s_resourceLimitMgr.findCorrectResourceLimitForDomain(domain, type, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long findCorrectResourceLimitForDomain(Long limit, boolean isRootDomain, ResourceType type, long domainId) {
|
public static long findCorrectResourceLimitForDomain(Long limit, boolean isRootDomain, ResourceType type, long domainId) {
|
||||||
@ -954,16 +959,6 @@ public class ApiDBUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long findCorrectResourceLimit(ResourceType type, long accountId) {
|
|
||||||
AccountVO account = s_accountDao.findById(accountId);
|
|
||||||
|
|
||||||
if (account == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s_resourceLimitMgr.findCorrectResourceLimitForAccount(account, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long findCorrectResourceLimit(Long limit, long accountId, ResourceType type) {
|
public static long findCorrectResourceLimit(Long limit, long accountId, ResourceType type) {
|
||||||
return s_resourceLimitMgr.findCorrectResourceLimitForAccount(accountId, limit, type);
|
return s_resourceLimitMgr.findCorrectResourceLimitForAccount(accountId, limit, type);
|
||||||
}
|
}
|
||||||
@ -984,7 +979,7 @@ public class ApiDBUtils {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s_resourceLimitMgr.getResourceCount(account, type);
|
return s_resourceLimitMgr.getResourceCount(account, type, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSecurityGroupsNamesForVm(long vmId) {
|
public static String getSecurityGroupsNamesForVm(long vmId) {
|
||||||
@ -2098,6 +2093,22 @@ public class ApiDBUtils {
|
|||||||
return s_jobJoinDao.newAsyncJobView(e);
|
return s_jobJoinDao.newAsyncJobView(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<DiskOfferingResponse> newDiskOfferingResponses(Long vmId, List<DiskOfferingJoinVO> offerings) {
|
||||||
|
List<DiskOfferingResponse> list = new ArrayList<>();
|
||||||
|
Map<Long, Boolean> suitability = null;
|
||||||
|
if (vmId != null) {
|
||||||
|
suitability = s_virtualMachineManager.getDiskOfferingSuitabilityForVm(vmId, offerings.stream().map(DiskOfferingJoinVO::getId).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
for (DiskOfferingJoinVO offering : offerings) {
|
||||||
|
DiskOfferingResponse response = s_diskOfferingJoinDao.newDiskOfferingResponse(offering);
|
||||||
|
if (vmId != null) {
|
||||||
|
response.setSuitableForVm(suitability.get(offering.getId()));
|
||||||
|
}
|
||||||
|
list.add(response);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
public static DiskOfferingResponse newDiskOfferingResponse(DiskOfferingJoinVO offering) {
|
public static DiskOfferingResponse newDiskOfferingResponse(DiskOfferingJoinVO offering) {
|
||||||
return s_diskOfferingJoinDao.newDiskOfferingResponse(offering);
|
return s_diskOfferingJoinDao.newDiskOfferingResponse(offering);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -559,6 +559,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
resourceLimitResponse.setMax(limit.getMax());
|
resourceLimitResponse.setMax(limit.getMax());
|
||||||
}
|
}
|
||||||
|
resourceLimitResponse.setTag(limit.getTag());
|
||||||
resourceLimitResponse.setObjectName("resourcelimit");
|
resourceLimitResponse.setObjectName("resourcelimit");
|
||||||
|
|
||||||
return resourceLimitResponse;
|
return resourceLimitResponse;
|
||||||
@ -580,7 +581,10 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
|
|
||||||
resourceCountResponse.setResourceType(resourceCount.getType());
|
resourceCountResponse.setResourceType(resourceCount.getType());
|
||||||
resourceCountResponse.setResourceCount(resourceCount.getCount());
|
resourceCountResponse.setResourceCount(resourceCount.getCount());
|
||||||
resourceCountResponse.setObjectName("resourcecount");
|
resourceCountResponse.setObjectName(ApiConstants.RESOURCE_COUNT);
|
||||||
|
if (StringUtils.isNotEmpty(resourceCount.getTag())) {
|
||||||
|
resourceCountResponse.setTag(resourceCount.getTag());
|
||||||
|
}
|
||||||
return resourceCountResponse;
|
return resourceCountResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2007,6 +2011,21 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
return ApiDBUtils.newEventResponse(vEvent);
|
return ApiDBUtils.newEventResponse(vEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean capacityListingForSingleTag(List<? extends Capacity> capacities) {
|
||||||
|
String tag = capacities.get(0).getTag();
|
||||||
|
if (tag == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<? extends Capacity> taggedCapacities = capacities.stream().filter(x -> tag.equals(x.getTag())).collect(Collectors.toList());
|
||||||
|
return taggedCapacities.size() == capacities.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean capacityListingForSingleNonGpuType(List<? extends Capacity> capacities) {
|
||||||
|
short type = capacities.get(0).getCapacityType();
|
||||||
|
List<? extends Capacity> typeCapacities = capacities.stream().filter(x -> x.getCapacityType() == type).collect(Collectors.toList());
|
||||||
|
return typeCapacities.size() == capacities.size();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<CapacityResponse> createCapacityResponse(List<? extends Capacity> result, DecimalFormat format) {
|
public List<CapacityResponse> createCapacityResponse(List<? extends Capacity> result, DecimalFormat format) {
|
||||||
List<CapacityResponse> capacityResponses = new ArrayList<CapacityResponse>();
|
List<CapacityResponse> capacityResponses = new ArrayList<CapacityResponse>();
|
||||||
@ -2052,13 +2071,18 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
capacityResponse.setPercentUsed(format.format(0L));
|
capacityResponse.setPercentUsed(format.format(0L));
|
||||||
}
|
}
|
||||||
|
capacityResponse.setTag(summedCapacity.getTag());
|
||||||
|
|
||||||
capacityResponse.setObjectName("capacity");
|
capacityResponse.setObjectName("capacity");
|
||||||
capacityResponses.add(capacityResponse);
|
capacityResponses.add(capacityResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<VgpuTypesInfo> gpuCapacities;
|
List<VgpuTypesInfo> gpuCapacities;
|
||||||
if (result.size() > 1 && (gpuCapacities = ApiDBUtils.getGpuCapacites(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId())) != null) {
|
if (result.size() > 1 &&
|
||||||
|
!capacityListingForSingleTag(result) &&
|
||||||
|
!capacityListingForSingleNonGpuType(result) &&
|
||||||
|
(gpuCapacities = ApiDBUtils.getGpuCapacites(result.get(0).getDataCenterId(),
|
||||||
|
result.get(0).getPodId(), result.get(0).getClusterId())) != null) {
|
||||||
HashMap<String, Long> vgpuVMs = ApiDBUtils.getVgpuVmsCount(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId());
|
HashMap<String, Long> vgpuVMs = ApiDBUtils.getVgpuVmsCount(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId());
|
||||||
|
|
||||||
float capacityUsed = 0;
|
float capacityUsed = 0;
|
||||||
|
|||||||
@ -281,6 +281,7 @@ import com.cloud.storage.SnapshotVO;
|
|||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.Storage.TemplateType;
|
import com.cloud.storage.Storage.TemplateType;
|
||||||
|
import com.cloud.storage.StorageManager;
|
||||||
import com.cloud.storage.StoragePoolStatus;
|
import com.cloud.storage.StoragePoolStatus;
|
||||||
import com.cloud.storage.StoragePoolTagVO;
|
import com.cloud.storage.StoragePoolTagVO;
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
@ -521,6 +522,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceIconDao resourceIconDao;
|
private ResourceIconDao resourceIconDao;
|
||||||
|
@Inject
|
||||||
|
StorageManager storageManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ManagementServerHostDao msHostDao;
|
private ManagementServerHostDao msHostDao;
|
||||||
@ -3153,8 +3156,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<DiskOfferingResponse> searchForDiskOfferings(ListDiskOfferingsCmd cmd) {
|
public ListResponse<DiskOfferingResponse> searchForDiskOfferings(ListDiskOfferingsCmd cmd) {
|
||||||
Pair<List<DiskOfferingJoinVO>, Integer> result = searchForDiskOfferingsInternal(cmd);
|
Pair<List<DiskOfferingJoinVO>, Integer> result = searchForDiskOfferingsInternal(cmd);
|
||||||
ListResponse<DiskOfferingResponse> response = new ListResponse<DiskOfferingResponse>();
|
ListResponse<DiskOfferingResponse> response = new ListResponse<>();
|
||||||
List<DiskOfferingResponse> offeringResponses = ViewResponseHelper.createDiskOfferingResponse(result.first().toArray(new DiskOfferingJoinVO[result.first().size()]));
|
List<DiskOfferingResponse> offeringResponses = ViewResponseHelper.createDiskOfferingResponses(cmd.getVirtualMachineId(), result.first());
|
||||||
response.setResponses(offeringResponses, result.second());
|
response.setResponses(offeringResponses, result.second());
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@ -3189,6 +3192,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Long storagePoolId = cmd.getStoragePoolId();
|
Long storagePoolId = cmd.getStoragePoolId();
|
||||||
Boolean encrypt = cmd.getEncrypt();
|
Boolean encrypt = cmd.getEncrypt();
|
||||||
String storageType = cmd.getStorageType();
|
String storageType = cmd.getStorageType();
|
||||||
|
final Long vmId = cmd.getVirtualMachineId();
|
||||||
|
|
||||||
// Keeping this logic consistent with domain specific zones
|
// Keeping this logic consistent with domain specific zones
|
||||||
// if a domainId is provided, we just return the disk offering
|
// if a domainId is provided, we just return the disk offering
|
||||||
@ -3296,6 +3300,16 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sc.addAnd("domainId", SearchCriteria.Op.SC, scc);
|
sc.addAnd("domainId", SearchCriteria.Op.SC, scc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vmId != null) {
|
||||||
|
UserVmVO vm = userVmDao.findById(vmId);
|
||||||
|
if (vm == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find the VM instance with the specified ID");
|
||||||
|
}
|
||||||
|
if (!isRootAdmin) {
|
||||||
|
accountMgr.checkAccess(account, null, false, vm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Pair<List<DiskOfferingJoinVO>, Integer> result = _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
|
Pair<List<DiskOfferingJoinVO>, Integer> result = _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
|
||||||
String[] requiredTagsArray = new String[0];
|
String[] requiredTagsArray = new String[0];
|
||||||
if (CollectionUtils.isNotEmpty(result.first()) && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.valueIn(zoneId)) {
|
if (CollectionUtils.isNotEmpty(result.first()) && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.valueIn(zoneId)) {
|
||||||
@ -3354,6 +3368,24 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<String> getHostTagsFromTemplateForServiceOfferingsListing(Account caller, Long templateId) {
|
||||||
|
List<String> hostTags = new ArrayList<>();
|
||||||
|
if (templateId == null) {
|
||||||
|
return hostTags;
|
||||||
|
}
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(templateId);
|
||||||
|
if (template == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find template with the specified ID");
|
||||||
|
}
|
||||||
|
if (caller.getType() != Account.Type.ADMIN) {
|
||||||
|
accountMgr.checkAccess(caller, null, false, template);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(template.getTemplateTag())) {
|
||||||
|
hostTags.add(template.getTemplateTag());
|
||||||
|
}
|
||||||
|
return hostTags;
|
||||||
|
}
|
||||||
|
|
||||||
private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInternal(ListServiceOfferingsCmd cmd) {
|
private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInternal(ListServiceOfferingsCmd cmd) {
|
||||||
// Note
|
// Note
|
||||||
// The filteredOfferings method for offerings is being modified in accordance with
|
// The filteredOfferings method for offerings is being modified in accordance with
|
||||||
@ -3385,6 +3417,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Integer cpuSpeed = cmd.getCpuSpeed();
|
Integer cpuSpeed = cmd.getCpuSpeed();
|
||||||
Boolean encryptRoot = cmd.getEncryptRoot();
|
Boolean encryptRoot = cmd.getEncryptRoot();
|
||||||
String storageType = cmd.getStorageType();
|
String storageType = cmd.getStorageType();
|
||||||
|
final Long templateId = cmd.getTemplateId();
|
||||||
|
|
||||||
final Account owner = accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
|
final Account owner = accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
|
||||||
SearchCriteria<ServiceOfferingJoinVO> sc = _srvOfferingJoinDao.createSearchCriteria();
|
SearchCriteria<ServiceOfferingJoinVO> sc = _srvOfferingJoinDao.createSearchCriteria();
|
||||||
@ -3579,6 +3612,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sc.addAnd("domainId", SearchCriteria.Op.SC, scc);
|
sc.addAnd("domainId", SearchCriteria.Op.SC, scc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> hostTags = getHostTagsFromTemplateForServiceOfferingsListing(caller, templateId);
|
||||||
|
|
||||||
if (currentVmOffering != null) {
|
if (currentVmOffering != null) {
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(currentVmOffering.getDiskOfferingId());
|
DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(currentVmOffering.getDiskOfferingId());
|
||||||
List<String> storageTags = com.cloud.utils.StringUtils.csvTagsToList(diskOffering.getTags());
|
List<String> storageTags = com.cloud.utils.StringUtils.csvTagsToList(diskOffering.getTags());
|
||||||
@ -3596,26 +3631,29 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sc.addAnd("storageTags", SearchCriteria.Op.SC, scc);
|
sc.addAnd("storageTags", SearchCriteria.Op.SC, scc);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> hostTags = com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getHostTag());
|
List<String> offeringHostTags = com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getHostTag());
|
||||||
if (!hostTags.isEmpty()) {
|
if (!offeringHostTags.isEmpty()) {
|
||||||
SearchBuilder<ServiceOfferingJoinVO> hostTagsSearchBuilder = _srvOfferingJoinDao.createSearchBuilder();
|
hostTags.addAll(offeringHostTags);
|
||||||
for(String tag : hostTags) {
|
|
||||||
hostTagsSearchBuilder.and(tag, hostTagsSearchBuilder.entity().getHostTag(), Op.FIND_IN_SET);
|
|
||||||
}
|
|
||||||
hostTagsSearchBuilder.done();
|
|
||||||
|
|
||||||
SearchCriteria<ServiceOfferingJoinVO> hostTagsSearchCriteria = hostTagsSearchBuilder.create();
|
|
||||||
for(String tag : hostTags) {
|
|
||||||
hostTagsSearchCriteria.setParameters(tag, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchCriteria<ServiceOfferingJoinVO> finalHostTagsSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
|
|
||||||
finalHostTagsSearchCriteria.addOr("hostTag", Op.NULL);
|
|
||||||
finalHostTagsSearchCriteria.addOr("hostTag", Op.SC, hostTagsSearchCriteria);
|
|
||||||
|
|
||||||
sc.addAnd("hostTagsConstraint", SearchCriteria.Op.SC, finalHostTagsSearchCriteria);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(hostTags)) {
|
||||||
|
SearchBuilder<ServiceOfferingJoinVO> hostTagsSearchBuilder = _srvOfferingJoinDao.createSearchBuilder();
|
||||||
|
for(String tag : hostTags) {
|
||||||
|
hostTagsSearchBuilder.and(tag, hostTagsSearchBuilder.entity().getHostTag(), Op.FIND_IN_SET);
|
||||||
|
}
|
||||||
|
hostTagsSearchBuilder.done();
|
||||||
|
|
||||||
|
SearchCriteria<ServiceOfferingJoinVO> hostTagsSearchCriteria = hostTagsSearchBuilder.create();
|
||||||
|
for(String tag : hostTags) {
|
||||||
|
hostTagsSearchCriteria.setParameters(tag, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchCriteria<ServiceOfferingJoinVO> finalHostTagsSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
|
||||||
|
finalHostTagsSearchCriteria.addOr("hostTag", Op.NULL);
|
||||||
|
finalHostTagsSearchCriteria.addOr("hostTag", Op.SC, hostTagsSearchCriteria);
|
||||||
|
|
||||||
|
sc.addAnd("hostTagsConstraint", SearchCriteria.Op.SC, finalHostTagsSearchCriteria);
|
||||||
|
}
|
||||||
|
|
||||||
return _srvOfferingJoinDao.searchAndCount(sc, searchFilter);
|
return _srvOfferingJoinDao.searchAndCount(sc, searchFilter);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -557,12 +557,8 @@ public class ViewResponseHelper {
|
|||||||
return respList;
|
return respList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<DiskOfferingResponse> createDiskOfferingResponse(DiskOfferingJoinVO... offerings) {
|
public static List<DiskOfferingResponse> createDiskOfferingResponses(Long vmId, List<DiskOfferingJoinVO> offerings) {
|
||||||
List<DiskOfferingResponse> respList = new ArrayList<DiskOfferingResponse>();
|
return ApiDBUtils.newDiskOfferingResponses(vmId, offerings);
|
||||||
for (DiskOfferingJoinVO vt : offerings) {
|
|
||||||
respList.add(ApiDBUtils.newDiskOfferingResponse(vt));
|
|
||||||
}
|
|
||||||
return respList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ServiceOfferingResponse> createServiceOfferingResponse(ServiceOfferingJoinVO... offerings) {
|
public static List<ServiceOfferingResponse> createServiceOfferingResponse(ServiceOfferingJoinVO... offerings) {
|
||||||
|
|||||||
@ -19,7 +19,6 @@ package com.cloud.api.query.dao;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.cloud.vm.VirtualMachine;
|
|
||||||
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
||||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||||
@ -28,6 +27,7 @@ import com.cloud.api.query.vo.UserVmJoinVO;
|
|||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.uservm.UserVm;
|
import com.cloud.uservm.UserVm;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
|
||||||
public interface UserVmJoinDao extends GenericDao<UserVmJoinVO, Long> {
|
public interface UserVmJoinDao extends GenericDao<UserVmJoinVO, Long> {
|
||||||
|
|
||||||
@ -43,4 +43,7 @@ public interface UserVmJoinDao extends GenericDao<UserVmJoinVO, Long> {
|
|||||||
List<UserVmJoinVO> searchByIds(Long... ids);
|
List<UserVmJoinVO> searchByIds(Long... ids);
|
||||||
|
|
||||||
List<UserVmJoinVO> listActiveByIsoId(Long isoId);
|
List<UserVmJoinVO> listActiveByIsoId(Long isoId);
|
||||||
|
|
||||||
|
List<UserVmJoinVO> listByAccountServiceOfferingTemplateAndNotInState(long accountId, List<VirtualMachine.State> states,
|
||||||
|
List<Long> offeringIds, List<Long> templateIds);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,7 @@ import org.apache.cloudstack.api.response.VnfNicResponse;
|
|||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.query.QueryService;
|
import org.apache.cloudstack.query.QueryService;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -679,4 +680,30 @@ public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJo
|
|||||||
return searchByIds(vmIdSet.toArray(new Long[vmIdSet.size()]));
|
return searchByIds(vmIdSet.toArray(new Long[vmIdSet.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserVmJoinVO> listByAccountServiceOfferingTemplateAndNotInState(long accountId, List<State> states,
|
||||||
|
List<Long> offeringIds, List<Long> templateIds) {
|
||||||
|
SearchBuilder<UserVmJoinVO> userVmSearch = createSearchBuilder();
|
||||||
|
userVmSearch.and("accountId", userVmSearch.entity().getAccountId(), Op.EQ);
|
||||||
|
userVmSearch.and("serviceOfferingId", userVmSearch.entity().getServiceOfferingId(), Op.IN);
|
||||||
|
userVmSearch.and("templateId", userVmSearch.entity().getTemplateId(), Op.IN);
|
||||||
|
userVmSearch.and("state", userVmSearch.entity().getState(), SearchCriteria.Op.NIN);
|
||||||
|
userVmSearch.and("displayVm", userVmSearch.entity().isDisplayVm(), Op.EQ);
|
||||||
|
userVmSearch.groupBy(userVmSearch.entity().getId()); // select distinct
|
||||||
|
userVmSearch.done();
|
||||||
|
|
||||||
|
SearchCriteria<UserVmJoinVO> sc = userVmSearch.create();
|
||||||
|
sc.setParameters("accountId", accountId);
|
||||||
|
if (CollectionUtils.isNotEmpty(offeringIds)) {
|
||||||
|
sc.setParameters("serviceOfferingId", offeringIds.toArray());
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(templateIds)) {
|
||||||
|
sc.setParameters("templateId", templateIds.toArray());
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(states)) {
|
||||||
|
sc.setParameters("state", states.toArray());
|
||||||
|
}
|
||||||
|
sc.setParameters("displayVm", 1);
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,6 +125,7 @@ import com.cloud.storage.dao.GuestOSCategoryDao;
|
|||||||
import com.cloud.storage.dao.GuestOSDao;
|
import com.cloud.storage.dao.GuestOSDao;
|
||||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||||
import com.cloud.storage.dao.VolumeDao;
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
import com.cloud.utils.DateUtil;
|
import com.cloud.utils.DateUtil;
|
||||||
import com.cloud.utils.NumbersUtil;
|
import com.cloud.utils.NumbersUtil;
|
||||||
@ -730,10 +731,11 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
|
|
||||||
protected boolean checkVmProfileAndHost(final VirtualMachineProfile vmProfile, final HostVO host) {
|
protected boolean checkVmProfileAndHost(final VirtualMachineProfile vmProfile, final HostVO host) {
|
||||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||||
if (offering.getHostTag() != null) {
|
VirtualMachineTemplate template = vmProfile.getTemplate();
|
||||||
|
if (offering.getHostTag() != null || template.getTemplateTag() != null) {
|
||||||
_hostDao.loadHostTags(host);
|
_hostDao.loadHostTags(host);
|
||||||
if (!host.checkHostServiceOfferingTags(offering)) {
|
if (!host.checkHostServiceOfferingAndTemplateTags(offering, template)) {
|
||||||
logger.debug("Service Offering host tag does not match the last host of this VM");
|
logger.debug("Service Offering host tag or template tag does not match the last host of this VM");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,10 +18,16 @@
|
|||||||
//
|
//
|
||||||
package com.cloud.resourcelimit;
|
package com.cloud.resourcelimit;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
import org.apache.cloudstack.reservation.ReservationVO;
|
import org.apache.cloudstack.reservation.ReservationVO;
|
||||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||||
import org.apache.cloudstack.user.ResourceReservation;
|
import org.apache.cloudstack.user.ResourceReservation;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -34,19 +40,33 @@ import com.cloud.utils.db.GlobalLock;
|
|||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
|
|
||||||
public class CheckedReservation implements AutoCloseable, ResourceReservation {
|
public class CheckedReservation implements AutoCloseable {
|
||||||
protected Logger logger = LogManager.getLogger(getClass());
|
protected Logger logger = LogManager.getLogger(getClass());
|
||||||
|
|
||||||
private static final int TRY_TO_GET_LOCK_TIME = 120;
|
private static final int TRY_TO_GET_LOCK_TIME = 120;
|
||||||
private GlobalLock quotaLimitLock;
|
private GlobalLock quotaLimitLock;
|
||||||
ReservationDao reservationDao;
|
ReservationDao reservationDao;
|
||||||
|
|
||||||
|
ResourceLimitService resourceLimitService;
|
||||||
private final Account account;
|
private final Account account;
|
||||||
private final ResourceType resourceType;
|
private final ResourceType resourceType;
|
||||||
private Long amount;
|
private Long amount;
|
||||||
private ResourceReservation reservation;
|
private List<ResourceReservation> reservations;
|
||||||
|
private List<String> resourceLimitTags;
|
||||||
|
|
||||||
private String getContextParameterKey() {
|
private String getContextParameterKey() {
|
||||||
return String.format("%s-%s", ResourceReservation.class.getSimpleName(), resourceType.getName());
|
return getResourceReservationContextParameterKey(resourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getResourceReservationContextParameterKey(final ResourceType type) {
|
||||||
|
return String.format("%s-%s", ResourceReservation.class.getSimpleName(), type.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkLimitAndPersistReservation(Account account, ResourceType resourceType, String tag, Long amount) throws ResourceAllocationException {
|
||||||
|
resourceLimitService.checkResourceLimitWithTag(account, resourceType, tag, amount);
|
||||||
|
ReservationVO reservationVO = new ReservationVO(account.getAccountId(), account.getDomainId(), resourceType, tag, amount);
|
||||||
|
ResourceReservation reservation = reservationDao.persist(reservationVO);
|
||||||
|
this.reservations.add(reservation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,13 +77,16 @@ public class CheckedReservation implements AutoCloseable, ResourceReservation {
|
|||||||
* @param amount positive number of the resource type to reserve
|
* @param amount positive number of the resource type to reserve
|
||||||
* @throws ResourceAllocationException
|
* @throws ResourceAllocationException
|
||||||
*/
|
*/
|
||||||
public CheckedReservation(Account account, ResourceType resourceType, Long amount, ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
public CheckedReservation(Account account, ResourceType resourceType, List<String> resourceLimitTags, Long amount,
|
||||||
|
ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||||
this.reservationDao = reservationDao;
|
this.reservationDao = reservationDao;
|
||||||
|
this.resourceLimitService = resourceLimitService;
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.resourceType = resourceType;
|
this.resourceType = resourceType;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.reservation = null;
|
this.reservations = new ArrayList<>();
|
||||||
setGlobalLock(account, resourceType);
|
this.resourceLimitTags = resourceLimitTags;
|
||||||
|
setGlobalLock();
|
||||||
if (this.amount != null && this.amount <= 0) {
|
if (this.amount != null && this.amount <= 0) {
|
||||||
if(logger.isDebugEnabled()){
|
if(logger.isDebugEnabled()){
|
||||||
logger.debug(String.format("not reserving no amount of resources for %s in domain %d, type: %s, %s ", account.getAccountName(), account.getDomainId(), resourceType, amount));
|
logger.debug(String.format("not reserving no amount of resources for %s in domain %d, type: %s, %s ", account.getAccountName(), account.getDomainId(), resourceType, amount));
|
||||||
@ -74,10 +97,13 @@ public class CheckedReservation implements AutoCloseable, ResourceReservation {
|
|||||||
if (this.amount != null) {
|
if (this.amount != null) {
|
||||||
if(quotaLimitLock.lock(TRY_TO_GET_LOCK_TIME)) {
|
if(quotaLimitLock.lock(TRY_TO_GET_LOCK_TIME)) {
|
||||||
try {
|
try {
|
||||||
resourceLimitService.checkResourceLimit(account,resourceType,amount);
|
checkLimitAndPersistReservation(account, resourceType, null, amount);
|
||||||
ReservationVO reservationVO = new ReservationVO(account.getAccountId(), account.getDomainId(), resourceType, amount);
|
if (CollectionUtils.isNotEmpty(resourceLimitTags)) {
|
||||||
this.reservation = reservationDao.persist(reservationVO);
|
for (String tag: resourceLimitTags) {
|
||||||
CallContext.current().putContextParameter(getContextParameterKey(), reservation.getId());
|
checkLimitAndPersistReservation(account, resourceType, tag, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CallContext.current().putContextParameter(getContextParameterKey(), getIds());
|
||||||
} catch (NullPointerException npe) {
|
} catch (NullPointerException npe) {
|
||||||
throw new CloudRuntimeException("not enough means to check limits", npe);
|
throw new CloudRuntimeException("not enough means to check limits", npe);
|
||||||
} finally {
|
} finally {
|
||||||
@ -87,14 +113,19 @@ public class CheckedReservation implements AutoCloseable, ResourceReservation {
|
|||||||
throw new ResourceAllocationException(String.format("unable to acquire resource reservation \"%s\"", quotaLimitLock.getName()), resourceType);
|
throw new ResourceAllocationException(String.format("unable to acquire resource reservation \"%s\"", quotaLimitLock.getName()), resourceType);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(logger.isDebugEnabled()){
|
if(logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("not reserving no amount of resources for %s in domain %d, type: %s ", account.getAccountName(), account.getDomainId(), resourceType));
|
logger.debug(String.format("not reserving no amount of resources for %s in domain %d, type: %s, tag: %s", account.getAccountName(), account.getDomainId(), resourceType, getResourceLimitTagsAsString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CheckedReservation(Account account, ResourceType resourceType, Long amount, ReservationDao reservationDao,
|
||||||
|
ResourceLimitService resourceLimitService) throws ResourceAllocationException {
|
||||||
|
this(account, resourceType, null, amount, reservationDao, resourceLimitService);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private void setGlobalLock(Account account, ResourceType resourceType) {
|
private void setGlobalLock() {
|
||||||
String lockName = String.format("CheckedReservation-%s/%d", account.getDomainId(), resourceType.getOrdinal());
|
String lockName = String.format("CheckedReservation-%s/%d", account.getDomainId(), resourceType.getOrdinal());
|
||||||
setQuotaLimitLock(GlobalLock.getInternLock(lockName));
|
setQuotaLimitLock(GlobalLock.getInternLock(lockName));
|
||||||
}
|
}
|
||||||
@ -105,39 +136,36 @@ public class CheckedReservation implements AutoCloseable, ResourceReservation {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
if (this.reservation != null) {
|
if (CollectionUtils.isEmpty(reservations)) {
|
||||||
CallContext.current().removeContextParameter(getContextParameterKey());
|
return;
|
||||||
reservationDao.remove(reservation.getId());
|
|
||||||
reservation = null;
|
|
||||||
}
|
}
|
||||||
|
CallContext.current().removeContextParameter(getContextParameterKey());
|
||||||
|
for (ResourceReservation reservation : reservations) {
|
||||||
|
reservationDao.remove(reservation.getId());
|
||||||
|
}
|
||||||
|
reservations = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account getAccount() {
|
public Account getAccount() {
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public String getResourceLimitTagsAsString() {
|
||||||
public Long getAccountId() {
|
return CollectionUtils.isNotEmpty(resourceLimitTags) ? StringUtils.join(resourceLimitTags) : null;
|
||||||
return account.getId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long getDomainId() {
|
|
||||||
return account.getDomainId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceType getResourceType() {
|
|
||||||
return resourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long getReservedAmount() {
|
public Long getReservedAmount() {
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public List<ResourceReservation> getReservations() {
|
||||||
public long getId() {
|
return reservations;
|
||||||
return this.reservation.getId();
|
}
|
||||||
|
|
||||||
|
public List<Long> getIds() {
|
||||||
|
if (CollectionUtils.isEmpty(reservations)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
return reservations.stream().map(ResourceReservation::getId).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -43,8 +43,6 @@ import javax.crypto.spec.SecretKeySpec;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import com.cloud.network.dao.PublicIpQuarantineDao;
|
|
||||||
import com.cloud.hypervisor.HypervisorGuru;
|
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
||||||
@ -225,8 +223,8 @@ import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStore
|
|||||||
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.MigrateSecondaryStorageDataCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.storage.MigrateResourcesToAnotherSecondaryStorageCmd;
|
import org.apache.cloudstack.api.command.admin.storage.MigrateResourcesToAnotherSecondaryStorageCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.MigrateSecondaryStorageDataCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.PreparePrimaryStorageForMaintenanceCmd;
|
import org.apache.cloudstack.api.command.admin.storage.PreparePrimaryStorageForMaintenanceCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.UpdateCloudToUseObjectStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.UpdateCloudToUseObjectStoreCmd;
|
||||||
@ -716,6 +714,7 @@ import com.cloud.host.dao.HostTagsDao;
|
|||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.hypervisor.HypervisorCapabilities;
|
import com.cloud.hypervisor.HypervisorCapabilities;
|
||||||
import com.cloud.hypervisor.HypervisorCapabilitiesVO;
|
import com.cloud.hypervisor.HypervisorCapabilitiesVO;
|
||||||
|
import com.cloud.hypervisor.HypervisorGuru;
|
||||||
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
|
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
|
||||||
import com.cloud.hypervisor.kvm.dpdk.DpdkHelper;
|
import com.cloud.hypervisor.kvm.dpdk.DpdkHelper;
|
||||||
import com.cloud.info.ConsoleProxyInfo;
|
import com.cloud.info.ConsoleProxyInfo;
|
||||||
@ -735,6 +734,7 @@ import com.cloud.network.dao.NetworkDao;
|
|||||||
import com.cloud.network.dao.NetworkDomainDao;
|
import com.cloud.network.dao.NetworkDomainDao;
|
||||||
import com.cloud.network.dao.NetworkDomainVO;
|
import com.cloud.network.dao.NetworkDomainVO;
|
||||||
import com.cloud.network.dao.NetworkVO;
|
import com.cloud.network.dao.NetworkVO;
|
||||||
|
import com.cloud.network.dao.PublicIpQuarantineDao;
|
||||||
import com.cloud.network.vpc.dao.VpcDao;
|
import com.cloud.network.vpc.dao.VpcDao;
|
||||||
import com.cloud.org.Cluster;
|
import com.cloud.org.Cluster;
|
||||||
import com.cloud.org.Grouping.AllocationState;
|
import com.cloud.org.Grouping.AllocationState;
|
||||||
@ -766,6 +766,7 @@ import com.cloud.storage.dao.DiskOfferingDao;
|
|||||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||||
import com.cloud.storage.dao.GuestOSDao;
|
import com.cloud.storage.dao.GuestOSDao;
|
||||||
import com.cloud.storage.dao.GuestOSHypervisorDao;
|
import com.cloud.storage.dao.GuestOSHypervisorDao;
|
||||||
|
import com.cloud.storage.dao.StoragePoolTagsDao;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import com.cloud.storage.dao.VolumeDao;
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
||||||
@ -775,6 +776,7 @@ import com.cloud.template.TemplateManager;
|
|||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
import com.cloud.user.AccountService;
|
import com.cloud.user.AccountService;
|
||||||
|
import com.cloud.user.ResourceLimitService;
|
||||||
import com.cloud.user.SSHKeyPair;
|
import com.cloud.user.SSHKeyPair;
|
||||||
import com.cloud.user.SSHKeyPairVO;
|
import com.cloud.user.SSHKeyPairVO;
|
||||||
import com.cloud.user.User;
|
import com.cloud.user.User;
|
||||||
@ -994,10 +996,20 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
protected AnnotationDao annotationDao;
|
protected AnnotationDao annotationDao;
|
||||||
@Inject
|
@Inject
|
||||||
UserDataManager userDataManager;
|
UserDataManager userDataManager;
|
||||||
|
@Inject
|
||||||
|
StoragePoolTagsDao storagePoolTagsDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private PublicIpQuarantineDao publicIpQuarantineDao;
|
private PublicIpQuarantineDao publicIpQuarantineDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ClusterManager _clusterMgr;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
|
||||||
|
@Inject
|
||||||
|
ResourceLimitService resourceLimitService;
|
||||||
|
|
||||||
private LockControllerListener _lockControllerListener;
|
private LockControllerListener _lockControllerListener;
|
||||||
private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
|
private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
|
||||||
private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker"));
|
private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker"));
|
||||||
@ -1024,12 +1036,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
_planners = planners;
|
_planners = planners;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
|
||||||
ClusterManager _clusterMgr;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
|
|
||||||
|
|
||||||
protected List<AffinityGroupProcessor> _affinityProcessors;
|
protected List<AffinityGroupProcessor> _affinityProcessors;
|
||||||
|
|
||||||
public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
|
public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
|
||||||
@ -3198,6 +3204,77 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pair<Boolean, List<Long>> getHostIdsForCapacityListing(Long zoneId, Long podId, Long clusterId, Integer capacityType, String tag) {
|
||||||
|
if (StringUtils.isEmpty(tag)) {
|
||||||
|
return new Pair<>(true, null);
|
||||||
|
}
|
||||||
|
Short type = capacityType == null ? null : capacityType.shortValue();
|
||||||
|
if (type != null && Capacity.STORAGE_CAPACITY_TYPES.contains(type)) {
|
||||||
|
return new Pair<>(false, null);
|
||||||
|
}
|
||||||
|
List<Long> hostIds = null;
|
||||||
|
try {
|
||||||
|
List<HostVO> hosts = _hostDao.listByHostTag(Type.Routing, clusterId, podId, zoneId, tag);
|
||||||
|
hostIds = hosts.stream().map(HostVO::getId).collect(Collectors.toList());
|
||||||
|
} catch (CloudRuntimeException ignored) {}
|
||||||
|
return new Pair<>(CollectionUtils.isNotEmpty(hostIds), hostIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<String> getResourceLimitTagsForCapacityListing() {
|
||||||
|
List<String> tags = new ArrayList<>();
|
||||||
|
tags.add(null);
|
||||||
|
tags.addAll(resourceLimitService.getResourceLimitHostTags());
|
||||||
|
tags.addAll(resourceLimitService.getResourceLimitStorageTags());
|
||||||
|
tags = tags.stream().distinct().collect(Collectors.toList());
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Pair<Boolean, List<Long>> getStoragePoolIdsForCapacityListing(Integer capacityType, String tag) {
|
||||||
|
if (StringUtils.isEmpty(tag)) {
|
||||||
|
return new Pair<>(true, null);
|
||||||
|
}
|
||||||
|
Short type = capacityType == null ? null : capacityType.shortValue();
|
||||||
|
if (type != null && !Capacity.STORAGE_CAPACITY_TYPES.contains(type)) {
|
||||||
|
return new Pair<>(false, null);
|
||||||
|
}
|
||||||
|
List<Long> storagePoolIds = storagePoolTagsDao.listPoolIdsByTag(tag);
|
||||||
|
return new Pair<>(CollectionUtils.isNotEmpty(storagePoolIds), storagePoolIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<SummedCapacity> getCapacitiesWithDetails(final Long zoneId, final Long podId, Long clusterId,
|
||||||
|
final Integer capacityType, final String tag, int level, Long pageSize) {
|
||||||
|
List<String> tags = new ArrayList<>();
|
||||||
|
if (StringUtils.isNotEmpty(tag)) {
|
||||||
|
tags.add(tag);
|
||||||
|
} else {
|
||||||
|
tags = getResourceLimitTagsForCapacityListing();
|
||||||
|
}
|
||||||
|
List<SummedCapacity> summedCapacities = new ArrayList<>();
|
||||||
|
for (String t : tags) {
|
||||||
|
List<SummedCapacity> taggedSummedCapacities = new ArrayList<>();
|
||||||
|
Pair<Boolean, List<Long>> hostIdsForCapacity = getHostIdsForCapacityListing(zoneId, podId, clusterId, capacityType, t);
|
||||||
|
Pair<Boolean, List<Long>> storagePoolIdsForCapacity = getStoragePoolIdsForCapacityListing(capacityType, t);
|
||||||
|
if (hostIdsForCapacity.first() || storagePoolIdsForCapacity.first()) {
|
||||||
|
final List<SummedCapacity> summedHostCapacities = _capacityDao.listCapacitiesGroupedByLevelAndType(
|
||||||
|
capacityType, zoneId, podId, clusterId, level, hostIdsForCapacity.second(),
|
||||||
|
storagePoolIdsForCapacity.second(), pageSize);
|
||||||
|
if (summedHostCapacities != null) {
|
||||||
|
taggedSummedCapacities.addAll(summedHostCapacities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (storagePoolIdsForCapacity.first()) {
|
||||||
|
List<SummedCapacity> summedStorageCapacities = getStorageCapacities(clusterId, podId, zoneId,
|
||||||
|
storagePoolIdsForCapacity.second(), capacityType == null ? null : capacityType.shortValue());
|
||||||
|
if (summedStorageCapacities != null) {
|
||||||
|
taggedSummedCapacities.addAll(summedStorageCapacities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taggedSummedCapacities.forEach(x -> x.setTag(t));
|
||||||
|
summedCapacities.addAll(taggedSummedCapacities);
|
||||||
|
}
|
||||||
|
return summedCapacities;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<CapacityVO> listTopConsumedResources(final ListCapacityCmd cmd) {
|
public List<CapacityVO> listTopConsumedResources(final ListCapacityCmd cmd) {
|
||||||
|
|
||||||
@ -3206,53 +3283,37 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
final Long podId = cmd.getPodId();
|
final Long podId = cmd.getPodId();
|
||||||
final Long clusterId = cmd.getClusterId();
|
final Long clusterId = cmd.getClusterId();
|
||||||
final Boolean fetchLatest = cmd.getFetchLatest();
|
final Boolean fetchLatest = cmd.getFetchLatest();
|
||||||
|
final String tag = cmd.getTag();
|
||||||
|
|
||||||
if (clusterId != null) {
|
if (clusterId != null) {
|
||||||
throw new InvalidParameterValueException("Currently clusterId param is not suppoerted");
|
throw new InvalidParameterValueException("Currently clusterId param is not supported");
|
||||||
}
|
}
|
||||||
zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
|
zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
|
||||||
|
|
||||||
if (fetchLatest != null && fetchLatest) {
|
if (fetchLatest != null && fetchLatest) {
|
||||||
_alertMgr.recalculateCapacity();
|
_alertMgr.recalculateCapacity();
|
||||||
}
|
}
|
||||||
List<SummedCapacity> summedCapacities = new ArrayList<SummedCapacity>();
|
|
||||||
|
|
||||||
|
int level = 3;
|
||||||
if (zoneId == null && podId == null) {// Group by Zone, capacity type
|
if (zoneId == null && podId == null) {// Group by Zone, capacity type
|
||||||
final List<SummedCapacity> summedCapacitiesAtZone = _capacityDao.listCapacitiesGroupedByLevelAndType(capacityType, zoneId, podId, clusterId, 1, cmd.getPageSizeVal());
|
level = 1;
|
||||||
if (summedCapacitiesAtZone != null) {
|
|
||||||
summedCapacities.addAll(summedCapacitiesAtZone);
|
|
||||||
}
|
|
||||||
} else if (podId == null) {// Group by Pod, capacity type
|
} else if (podId == null) {// Group by Pod, capacity type
|
||||||
final List<SummedCapacity> summedCapacitiesAtPod = _capacityDao.listCapacitiesGroupedByLevelAndType(capacityType, zoneId, podId, clusterId, 2, cmd.getPageSizeVal());
|
level = 2;
|
||||||
if (summedCapacitiesAtPod != null) {
|
|
||||||
summedCapacities.addAll(summedCapacitiesAtPod);
|
|
||||||
}
|
|
||||||
} else { // Group by Cluster, capacity type
|
|
||||||
final List<SummedCapacity> summedCapacitiesAtCluster = _capacityDao.listCapacitiesGroupedByLevelAndType(capacityType, zoneId, podId, clusterId, 3, cmd.getPageSizeVal());
|
|
||||||
if (summedCapacitiesAtCluster != null) {
|
|
||||||
summedCapacities.addAll(summedCapacitiesAtCluster);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SummedCapacity> summedCapacitiesForSecStorage = getStorageUsed(clusterId, podId, zoneId, capacityType);
|
final List<CapacityVO> capacities = new ArrayList<>();
|
||||||
if (summedCapacitiesForSecStorage != null) {
|
List<SummedCapacity> summedCapacities = getCapacitiesWithDetails(zoneId, podId, clusterId, capacityType, tag, level, cmd.getPageSizeVal());
|
||||||
summedCapacities.addAll(summedCapacitiesForSecStorage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort Capacities
|
// Sort Capacities
|
||||||
Collections.sort(summedCapacities, new Comparator<SummedCapacity>() {
|
summedCapacities.sort((arg0, arg1) -> {
|
||||||
@Override
|
if (arg0.getPercentUsed() < arg1.getPercentUsed()) {
|
||||||
public int compare(final SummedCapacity arg0, final SummedCapacity arg1) {
|
return 1;
|
||||||
if (arg0.getPercentUsed() < arg1.getPercentUsed()) {
|
} else if (arg0.getPercentUsed().equals(arg1.getPercentUsed())) {
|
||||||
return 1;
|
return 0;
|
||||||
} else if (arg0.getPercentUsed().equals(arg1.getPercentUsed())) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
});
|
});
|
||||||
|
|
||||||
final List<CapacityVO> capacities = new ArrayList<CapacityVO>();
|
|
||||||
|
|
||||||
Integer pageSize = null;
|
Integer pageSize = null;
|
||||||
try {
|
try {
|
||||||
@ -3267,53 +3328,104 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
summedCapacity.getPercentUsed());
|
summedCapacity.getPercentUsed());
|
||||||
capacity.setUsedCapacity(summedCapacity.getUsedCapacity() + summedCapacity.getReservedCapacity());
|
capacity.setUsedCapacity(summedCapacity.getUsedCapacity() + summedCapacity.getReservedCapacity());
|
||||||
capacity.setTotalCapacity(summedCapacity.getTotalCapacity());
|
capacity.setTotalCapacity(summedCapacity.getTotalCapacity());
|
||||||
|
capacity.setTag(summedCapacity.getTag());
|
||||||
capacities.add(capacity);
|
capacities.add(capacity);
|
||||||
}
|
}
|
||||||
return capacities;
|
return capacities;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SummedCapacity> getStorageUsed(Long clusterId, Long podId, Long zoneId, Integer capacityType) {
|
List<SummedCapacity> getStorageCapacities(Long clusterId, Long podId, Long zoneId, List<Long> poolIds, Short capacityType) {
|
||||||
if (capacityType == null || capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) {
|
List<Short> capacityTypes = Arrays.asList(Capacity.CAPACITY_TYPE_STORAGE, Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
|
||||||
final List<SummedCapacity> list = new ArrayList<SummedCapacity>();
|
if (capacityType != null && !capacityTypes.contains(capacityType)) {
|
||||||
if (zoneId != null) {
|
return null;
|
||||||
final DataCenterVO zone = ApiDBUtils.findZoneById(zoneId);
|
|
||||||
if (zone == null || zone.getAllocationState() == AllocationState.Disabled) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
List<CapacityVO> capacities = new ArrayList<CapacityVO>();
|
|
||||||
capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, zoneId));
|
|
||||||
capacities.add(_storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId));
|
|
||||||
for (CapacityVO capacity : capacities) {
|
|
||||||
if (capacity.getTotalCapacity() != 0) {
|
|
||||||
capacity.setUsedPercentage((float)capacity.getUsedCapacity() / capacity.getTotalCapacity());
|
|
||||||
} else {
|
|
||||||
capacity.setUsedPercentage(0);
|
|
||||||
}
|
|
||||||
final SummedCapacity summedCapacity = new SummedCapacity(capacity.getUsedCapacity(), capacity.getTotalCapacity(), capacity.getUsedPercentage(), capacity.getCapacityType(),
|
|
||||||
capacity.getDataCenterId(), capacity.getPodId(), capacity.getClusterId());
|
|
||||||
list.add(summedCapacity);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
List<DataCenterVO> dcList = _dcDao.listEnabledZones();
|
|
||||||
for (DataCenterVO dc : dcList) {
|
|
||||||
List<CapacityVO> capacities = new ArrayList<CapacityVO>();
|
|
||||||
capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, dc.getId()));
|
|
||||||
capacities.add(_storageMgr.getStoragePoolUsedStats(null, null, null, dc.getId()));
|
|
||||||
for (CapacityVO capacity : capacities) {
|
|
||||||
if (capacity.getTotalCapacity() != 0) {
|
|
||||||
capacity.setUsedPercentage((float)capacity.getUsedCapacity() / capacity.getTotalCapacity());
|
|
||||||
} else {
|
|
||||||
capacity.setUsedPercentage(0);
|
|
||||||
}
|
|
||||||
SummedCapacity summedCapacity = new SummedCapacity(capacity.getUsedCapacity(), capacity.getTotalCapacity(), capacity.getUsedPercentage(), capacity.getCapacityType(),
|
|
||||||
capacity.getDataCenterId(), capacity.getPodId(), capacity.getClusterId());
|
|
||||||
list.add(summedCapacity);
|
|
||||||
}
|
|
||||||
}// End of for
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
return null;
|
if (capacityType != null) {
|
||||||
|
capacityTypes = capacityTypes.stream().filter(x -> x.equals(capacityType)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(poolIds)) {
|
||||||
|
capacityTypes = capacityTypes.stream().filter(x -> x != Capacity.CAPACITY_TYPE_SECONDARY_STORAGE).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isEmpty(capacityTypes)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final List<SummedCapacity> list = new ArrayList<>();
|
||||||
|
List<DataCenterVO> dcList = new ArrayList<>();
|
||||||
|
if (zoneId != null) {
|
||||||
|
final DataCenterVO zone = ApiDBUtils.findZoneById(zoneId);
|
||||||
|
if (zone == null || zone.getAllocationState() == AllocationState.Disabled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
dcList.add(zone);
|
||||||
|
} else {
|
||||||
|
dcList = _dcDao.listEnabledZones();
|
||||||
|
podId = null;
|
||||||
|
clusterId = null;
|
||||||
|
}
|
||||||
|
for (DataCenterVO dc : dcList) {
|
||||||
|
List<CapacityVO> capacities = new ArrayList<>();
|
||||||
|
if (capacityTypes.contains(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE)) {
|
||||||
|
capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, dc.getId()));
|
||||||
|
}
|
||||||
|
if (capacityTypes.contains(Capacity.CAPACITY_TYPE_STORAGE)) {
|
||||||
|
capacities.add(_storageMgr.getStoragePoolUsedStats(dc.getId(), podId, clusterId, poolIds));
|
||||||
|
}
|
||||||
|
for (CapacityVO capacity : capacities) {
|
||||||
|
if (capacity.getTotalCapacity() != 0) {
|
||||||
|
capacity.setUsedPercentage((float)capacity.getUsedCapacity() / capacity.getTotalCapacity());
|
||||||
|
} else {
|
||||||
|
capacity.setUsedPercentage(0);
|
||||||
|
}
|
||||||
|
SummedCapacity summedCapacity = new SummedCapacity(capacity.getUsedCapacity(), capacity.getTotalCapacity(), capacity.getUsedPercentage(), capacity.getCapacityType(),
|
||||||
|
capacity.getDataCenterId(), capacity.getPodId(), capacity.getClusterId());
|
||||||
|
list.add(summedCapacity);
|
||||||
|
}
|
||||||
|
}// End of for
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected List<CapacityVO> listCapacitiesWithDetails(final Long zoneId, final Long podId, Long clusterId,
|
||||||
|
final Integer capacityType, final String tag, List<Long> dcList) {
|
||||||
|
List<String> tags = new ArrayList<>();
|
||||||
|
if (StringUtils.isNotEmpty(tag)) {
|
||||||
|
tags.add(tag);
|
||||||
|
} else {
|
||||||
|
tags = getResourceLimitTagsForCapacityListing();
|
||||||
|
}
|
||||||
|
List<CapacityVO> capacities = new ArrayList<>();
|
||||||
|
for (String t : tags) {
|
||||||
|
List<CapacityVO> taggedCapacities = new ArrayList<>();
|
||||||
|
Pair<Boolean, List<Long>> hostIdsForCapacity = getHostIdsForCapacityListing(zoneId, podId, clusterId, capacityType, t);
|
||||||
|
Pair<Boolean, List<Long>> storagePoolIdsForCapacity = getStoragePoolIdsForCapacityListing(capacityType, t);
|
||||||
|
if (hostIdsForCapacity.first() || storagePoolIdsForCapacity.first()) {
|
||||||
|
final List<SummedCapacity> summedCapacities = _capacityDao.findFilteredCapacityBy(capacityType,
|
||||||
|
zoneId, podId, clusterId, hostIdsForCapacity.second(), storagePoolIdsForCapacity.second());
|
||||||
|
|
||||||
|
for (final SummedCapacity summedCapacity : summedCapacities) {
|
||||||
|
final CapacityVO capacity = new CapacityVO(null, summedCapacity.getDataCenterId(), summedCapacity.getPodId(), summedCapacity.getClusterId(),
|
||||||
|
summedCapacity.getUsedCapacity() + summedCapacity.getReservedCapacity(), summedCapacity.getTotalCapacity(), summedCapacity.getCapacityType());
|
||||||
|
capacity.setAllocatedCapacity(summedCapacity.getAllocatedCapacity());
|
||||||
|
taggedCapacities.add(capacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final Long zId : dcList) {
|
||||||
|
// op_host_Capacity contains only allocated stats and the real time
|
||||||
|
// stats are stored "in memory".
|
||||||
|
// List secondary storage capacity only when the api is invoked for the zone layer.
|
||||||
|
if ((capacityType == null || capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) &&
|
||||||
|
podId == null && clusterId == null &&
|
||||||
|
StringUtils.isEmpty(t)) {
|
||||||
|
taggedCapacities.add(_storageMgr.getSecondaryStorageUsedStats(null, zId));
|
||||||
|
}
|
||||||
|
if ((capacityType == null || capacityType == Capacity.CAPACITY_TYPE_STORAGE) && storagePoolIdsForCapacity.first()) {
|
||||||
|
taggedCapacities.add(_storageMgr.getStoragePoolUsedStats(zId, podId, clusterId, storagePoolIdsForCapacity.second()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taggedCapacities.forEach(x -> x.setTag(t));
|
||||||
|
capacities.addAll(taggedCapacities);
|
||||||
|
}
|
||||||
|
return capacities;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -3324,51 +3436,25 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
final Long podId = cmd.getPodId();
|
final Long podId = cmd.getPodId();
|
||||||
final Long clusterId = cmd.getClusterId();
|
final Long clusterId = cmd.getClusterId();
|
||||||
final Boolean fetchLatest = cmd.getFetchLatest();
|
final Boolean fetchLatest = cmd.getFetchLatest();
|
||||||
|
final String tag = cmd.getTag();
|
||||||
|
|
||||||
zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
|
zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
|
||||||
if (fetchLatest != null && fetchLatest) {
|
if (fetchLatest != null && fetchLatest) {
|
||||||
_alertMgr.recalculateCapacity();
|
_alertMgr.recalculateCapacity();
|
||||||
}
|
}
|
||||||
|
List<Long> dcList = new ArrayList<>();
|
||||||
final List<SummedCapacity> summedCapacities = _capacityDao.findCapacityBy(capacityType, zoneId, podId, clusterId);
|
if (zoneId != null) {
|
||||||
final List<CapacityVO> capacities = new ArrayList<CapacityVO>();
|
dcList.add(zoneId);
|
||||||
|
|
||||||
for (final SummedCapacity summedCapacity : summedCapacities) {
|
|
||||||
final CapacityVO capacity = new CapacityVO(null, summedCapacity.getDataCenterId(), summedCapacity.getPodId(), summedCapacity.getClusterId(),
|
|
||||||
summedCapacity.getUsedCapacity() + summedCapacity.getReservedCapacity(), summedCapacity.getTotalCapacity(), summedCapacity.getCapacityType());
|
|
||||||
capacity.setAllocatedCapacity(summedCapacity.getAllocatedCapacity());
|
|
||||||
capacities.add(capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// op_host_Capacity contains only allocated stats and the real time
|
|
||||||
// stats are stored "in memory".
|
|
||||||
// Show Sec. Storage only when the api is invoked for the zone layer.
|
|
||||||
List<DataCenterVO> dcList = new ArrayList<DataCenterVO>();
|
|
||||||
if (zoneId == null && podId == null && clusterId == null) {
|
|
||||||
dcList = ApiDBUtils.listZones();
|
|
||||||
} else if (zoneId != null) {
|
|
||||||
dcList.add(ApiDBUtils.findZoneById(zoneId));
|
|
||||||
} else {
|
} else {
|
||||||
if (clusterId != null) {
|
if (podId == null && clusterId == null) {
|
||||||
zoneId = ApiDBUtils.findClusterById(clusterId).getDataCenterId();
|
dcList.addAll(ApiDBUtils.listZones().stream().map(DataCenterVO::getId).collect(Collectors.toList()));
|
||||||
} else {
|
} if (clusterId != null) {
|
||||||
zoneId = ApiDBUtils.findPodById(podId).getDataCenterId();
|
dcList.add(ApiDBUtils.findClusterById(clusterId).getDataCenterId());
|
||||||
}
|
} else if (podId != null) {
|
||||||
if (capacityType == null || capacityType == Capacity.CAPACITY_TYPE_STORAGE) {
|
dcList.add(ApiDBUtils.findPodById(podId).getDataCenterId());
|
||||||
capacities.add(_storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return listCapacitiesWithDetails(zoneId, podId, clusterId, capacityType, tag, dcList);
|
||||||
for (final DataCenterVO zone : dcList) {
|
|
||||||
zoneId = zone.getId();
|
|
||||||
if ((capacityType == null || capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) && podId == null && clusterId == null) {
|
|
||||||
capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, zoneId));
|
|
||||||
}
|
|
||||||
if (capacityType == null || capacityType == Capacity.CAPACITY_TYPE_STORAGE) {
|
|
||||||
capacities.add(_storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return capacities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -1600,7 +1600,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
if (_serverId == host.getManagementServerId().longValue()) {
|
if (_serverId == host.getManagementServerId().longValue()) {
|
||||||
volService.destroyVolume(volume.getId());
|
volService.destroyVolume(volume.getId());
|
||||||
// decrement volume resource count
|
// decrement volume resource count
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
|
_resourceLimitMgr.decrementVolumeResourceCount(volume.getAccountId(), volume.isDisplayVolume(),
|
||||||
|
null, _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId()));
|
||||||
// expunge volume from secondary if volume is on image store
|
// expunge volume from secondary if volume is on image store
|
||||||
VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
|
VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
|
||||||
if (volOnSecondary != null) {
|
if (volOnSecondary != null) {
|
||||||
@ -2414,25 +2415,24 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
return capacity;
|
return capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private CapacityVO getStoragePoolUsedStatsInternal(Long zoneId, Long podId, Long clusterId, List<Long> poolIds, Long poolId) {
|
||||||
public CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId) {
|
|
||||||
SearchCriteria<StoragePoolVO> sc = _storagePoolDao.createSearchCriteria();
|
SearchCriteria<StoragePoolVO> sc = _storagePoolDao.createSearchCriteria();
|
||||||
List<StoragePoolVO> pools = new ArrayList<StoragePoolVO>();
|
List<StoragePoolVO> pools = new ArrayList<>();
|
||||||
|
|
||||||
if (zoneId != null) {
|
if (zoneId != null) {
|
||||||
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
|
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (podId != null) {
|
if (podId != null) {
|
||||||
sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
|
sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clusterId != null) {
|
if (clusterId != null) {
|
||||||
sc.addAnd("clusterId", SearchCriteria.Op.EQ, clusterId);
|
sc.addAnd("clusterId", SearchCriteria.Op.EQ, clusterId);
|
||||||
}
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(poolIds)) {
|
||||||
|
sc.addAnd("id", SearchCriteria.Op.IN, poolIds.toArray());
|
||||||
|
}
|
||||||
if (poolId != null) {
|
if (poolId != null) {
|
||||||
sc.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, poolId);
|
sc.addAnd("id", SearchCriteria.Op.EQ, poolId);
|
||||||
}
|
}
|
||||||
sc.addAnd("parent", SearchCriteria.Op.EQ, 0L);
|
sc.addAnd("parent", SearchCriteria.Op.EQ, 0L);
|
||||||
if (poolId != null) {
|
if (poolId != null) {
|
||||||
@ -2442,8 +2442,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
CapacityVO capacity = new CapacityVO(poolId, zoneId, podId, clusterId, 0, 0, Capacity.CAPACITY_TYPE_STORAGE);
|
CapacityVO capacity = new CapacityVO(poolId, zoneId, podId, clusterId, 0, 0, Capacity.CAPACITY_TYPE_STORAGE);
|
||||||
for (StoragePoolVO PrimaryDataStoreVO : pools) {
|
for (StoragePoolVO pool : pools) {
|
||||||
StorageStats stats = ApiDBUtils.getStoragePoolStatistics(PrimaryDataStoreVO.getId());
|
StorageStats stats = ApiDBUtils.getStoragePoolStatistics(pool.getId());
|
||||||
if (stats == null) {
|
if (stats == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2451,6 +2451,17 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
capacity.setTotalCapacity(stats.getCapacityBytes() + capacity.getTotalCapacity());
|
capacity.setTotalCapacity(stats.getCapacityBytes() + capacity.getTotalCapacity());
|
||||||
}
|
}
|
||||||
return capacity;
|
return capacity;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId) {
|
||||||
|
return getStoragePoolUsedStatsInternal(zoneId, podId, clusterId, null, poolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CapacityVO getStoragePoolUsedStats(Long zoneId, Long podId, Long clusterId, List<Long> poolIds) {
|
||||||
|
return getStoragePoolUsedStatsInternal(zoneId, podId, clusterId, poolIds, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -2663,13 +2674,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected boolean checkIfPoolIopsCapacityNull(StoragePool pool) {
|
||||||
public boolean storagePoolHasEnoughIops(List<Pair<Volume, DiskProfile>> requestedVolumes, StoragePool pool) {
|
|
||||||
if (requestedVolumes == null || requestedVolumes.isEmpty() || pool == null) {
|
|
||||||
logger.debug(String.format("Cannot check if storage [%s] has enough IOPS to allocate volumes [%s].", pool, requestedVolumes));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only IOPS-guaranteed primary storage like SolidFire is using/setting IOPS.
|
// Only IOPS-guaranteed primary storage like SolidFire is using/setting IOPS.
|
||||||
// This check returns true for storage that does not specify IOPS.
|
// This check returns true for storage that does not specify IOPS.
|
||||||
if (pool.getCapacityIops() == null) {
|
if (pool.getCapacityIops() == null) {
|
||||||
@ -2677,12 +2682,32 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean storagePoolHasEnoughIops(long requestedIops, List<Pair<Volume, DiskProfile>> requestedVolumes, StoragePool pool, boolean skipPoolNullIopsCheck) {
|
||||||
|
if (!skipPoolNullIopsCheck && checkIfPoolIopsCapacityNull(pool)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
StoragePoolVO storagePoolVo = _storagePoolDao.findById(pool.getId());
|
StoragePoolVO storagePoolVo = _storagePoolDao.findById(pool.getId());
|
||||||
long currentIops = _capacityMgr.getUsedIops(storagePoolVo);
|
long currentIops = _capacityMgr.getUsedIops(storagePoolVo);
|
||||||
|
long futureIops = currentIops + requestedIops;
|
||||||
|
boolean hasEnoughIops = futureIops <= pool.getCapacityIops();
|
||||||
|
String hasCapacity = hasEnoughIops ? "has" : "does not have";
|
||||||
|
logger.debug(String.format("Pool [%s] %s enough IOPS to allocate volumes [%s].", pool, hasCapacity, requestedVolumes));
|
||||||
|
return hasEnoughIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean storagePoolHasEnoughIops(List<Pair<Volume, DiskProfile>> requestedVolumes, StoragePool pool) {
|
||||||
|
if (requestedVolumes == null || requestedVolumes.isEmpty() || pool == null) {
|
||||||
|
logger.debug(String.format("Cannot check if storage [%s] has enough IOPS to allocate volumes [%s].", pool, requestedVolumes));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (checkIfPoolIopsCapacityNull(pool)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
long requestedIops = 0;
|
long requestedIops = 0;
|
||||||
|
|
||||||
for (Pair<Volume, DiskProfile> volumeDiskProfilePair : requestedVolumes) {
|
for (Pair<Volume, DiskProfile> volumeDiskProfilePair : requestedVolumes) {
|
||||||
Volume requestedVolume = volumeDiskProfilePair.first();
|
Volume requestedVolume = volumeDiskProfilePair.first();
|
||||||
DiskProfile diskProfile = volumeDiskProfilePair.second();
|
DiskProfile diskProfile = volumeDiskProfilePair.second();
|
||||||
@ -2695,12 +2720,28 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
requestedIops += minIops;
|
requestedIops += minIops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return storagePoolHasEnoughIops(requestedIops, requestedVolumes, pool, true);
|
||||||
|
}
|
||||||
|
|
||||||
long futureIops = currentIops + requestedIops;
|
@Override
|
||||||
boolean hasEnoughIops = futureIops <= pool.getCapacityIops();
|
public boolean storagePoolHasEnoughIops(Long requestedIops, StoragePool pool) {
|
||||||
String hasCapacity = hasEnoughIops ? "has" : "does not have";
|
if (pool == null) {
|
||||||
logger.debug(String.format("Pool [%s] %s enough IOPS to allocate volumes [%s].", pool, hasCapacity, requestedVolumes));
|
return false;
|
||||||
return hasEnoughIops;
|
}
|
||||||
|
if (requestedIops == null || requestedIops == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return storagePoolHasEnoughIops(requestedIops, new ArrayList<>(), pool, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean storagePoolHasEnoughSpace(Long size, StoragePool pool) {
|
||||||
|
if (size == null || size == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
final StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
|
||||||
|
long allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, null);
|
||||||
|
return checkPoolforSpace(pool, allocatedSizeWithTemplate, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -2790,6 +2831,38 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Answer getCheckDatastorePolicyComplianceAnswer(String storagePolicyId, StoragePool pool) throws StorageUnavailableException {
|
||||||
|
if (StringUtils.isEmpty(storagePolicyId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
VsphereStoragePolicyVO storagePolicyVO = _vsphereStoragePolicyDao.findById(Long.parseLong(storagePolicyId));
|
||||||
|
List<Long> hostIds = getUpHostsInPool(pool.getId());
|
||||||
|
Collections.shuffle(hostIds);
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(hostIds)) {
|
||||||
|
throw new StorageUnavailableException("Unable to send command to the pool " + pool.getName() + " due to there is no enabled hosts up in this cluster", pool.getId());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
StorageFilerTO storageFilerTO = new StorageFilerTO(pool);
|
||||||
|
CheckDataStoreStoragePolicyComplainceCommand cmd = new CheckDataStoreStoragePolicyComplainceCommand(storagePolicyVO.getPolicyId(), storageFilerTO);
|
||||||
|
long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostIds.get(0), cmd);
|
||||||
|
return _agentMgr.send(targetHostId, cmd);
|
||||||
|
} catch (AgentUnavailableException e) {
|
||||||
|
logger.debug("Unable to send storage pool command to " + pool + " via " + hostIds.get(0), e);
|
||||||
|
throw new StorageUnavailableException("Unable to send command to the pool ", pool.getId());
|
||||||
|
} catch (OperationTimedoutException e) {
|
||||||
|
logger.debug("Failed to process storage pool command to " + pool + " via " + hostIds.get(0), e);
|
||||||
|
throw new StorageUnavailableException("Failed to process storage command to the pool ", pool.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStoragePoolCompliantWithStoragePolicy(long diskOfferingId, StoragePool pool) throws StorageUnavailableException {
|
||||||
|
String storagePolicyId = _diskOfferingDetailsDao.getDetail(diskOfferingId, ApiConstants.STORAGE_POLICY);
|
||||||
|
Answer answer = getCheckDatastorePolicyComplianceAnswer(storagePolicyId, pool);
|
||||||
|
return answer == null || answer.getResult();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStoragePoolCompliantWithStoragePolicy(List<Pair<Volume, DiskProfile>> volumes, StoragePool pool) throws StorageUnavailableException {
|
public boolean isStoragePoolCompliantWithStoragePolicy(List<Pair<Volume, DiskProfile>> volumes, StoragePool pool) throws StorageUnavailableException {
|
||||||
if (CollectionUtils.isEmpty(volumes)) {
|
if (CollectionUtils.isEmpty(volumes)) {
|
||||||
@ -2810,27 +2883,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
} else {
|
} else {
|
||||||
storagePolicyId = _diskOfferingDetailsDao.getDetail(diskProfile.getDiskOfferingId(), ApiConstants.STORAGE_POLICY);
|
storagePolicyId = _diskOfferingDetailsDao.getDetail(diskProfile.getDiskOfferingId(), ApiConstants.STORAGE_POLICY);
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(storagePolicyId)) {
|
Answer answer = getCheckDatastorePolicyComplianceAnswer(storagePolicyId, pool);
|
||||||
VsphereStoragePolicyVO storagePolicyVO = _vsphereStoragePolicyDao.findById(Long.parseLong(storagePolicyId));
|
if (answer != null) {
|
||||||
List<Long> hostIds = getUpHostsInPool(pool.getId());
|
answers.add(new Pair<>(volume, answer));
|
||||||
Collections.shuffle(hostIds);
|
|
||||||
|
|
||||||
if (hostIds == null || hostIds.isEmpty()) {
|
|
||||||
throw new StorageUnavailableException("Unable to send command to the pool " + pool.getName() + " due to there is no enabled hosts up in this cluster", pool.getId());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
StorageFilerTO storageFilerTO = new StorageFilerTO(pool);
|
|
||||||
CheckDataStoreStoragePolicyComplainceCommand cmd = new CheckDataStoreStoragePolicyComplainceCommand(storagePolicyVO.getPolicyId(), storageFilerTO);
|
|
||||||
long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostIds.get(0), cmd);
|
|
||||||
Answer answer = _agentMgr.send(targetHostId, cmd);
|
|
||||||
answers.add(new Pair<>(volume, answer));
|
|
||||||
} catch (AgentUnavailableException e) {
|
|
||||||
logger.debug("Unable to send storage pool command to " + pool + " via " + hostIds.get(0), e);
|
|
||||||
throw new StorageUnavailableException("Unable to send command to the pool ", pool.getId());
|
|
||||||
} catch (OperationTimedoutException e) {
|
|
||||||
logger.debug("Failed to process storage pool command to " + pool + " via " + hostIds.get(0), e);
|
|
||||||
throw new StorageUnavailableException("Failed to process storage command to the pool ", pool.getId());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check cummilative result for all volumes
|
// check cummilative result for all volumes
|
||||||
@ -2843,7 +2898,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkPoolforSpace(StoragePool pool, long allocatedSizeWithTemplate, long totalAskingSize) {
|
protected boolean checkPoolforSpace(StoragePool pool, long allocatedSizeWithTemplate, long totalAskingSize) {
|
||||||
// allocated space includes templates
|
// allocated space includes templates
|
||||||
StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
|
StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
|
||||||
|
|
||||||
|
|||||||
@ -348,7 +348,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
protected Gson _gson;
|
protected Gson _gson;
|
||||||
|
|
||||||
private static final List<HypervisorType> SupportedHypervisorsForVolResize = Arrays.asList(HypervisorType.KVM, HypervisorType.XenServer,
|
private static final List<HypervisorType> SupportedHypervisorsForVolResize = Arrays.asList(HypervisorType.KVM, HypervisorType.XenServer,
|
||||||
HypervisorType.VMware, HypervisorType.Any, HypervisorType.None);
|
HypervisorType.VMware, HypervisorType.Simulator, HypervisorType.Any, HypervisorType.None);
|
||||||
private List<StoragePoolAllocator> _storagePoolAllocators;
|
private List<StoragePoolAllocator> _storagePoolAllocators;
|
||||||
|
|
||||||
private List<HypervisorType> supportingDefaultHV;
|
private List<HypervisorType> supportingDefaultHV;
|
||||||
@ -504,7 +504,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
Account account = _accountDao.findById(accountId);
|
Account account = _accountDao.findById(accountId);
|
||||||
Domain domain = domainDao.findById(account.getDomainId());
|
Domain domain = domainDao.findById(account.getDomainId());
|
||||||
|
|
||||||
command.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage));
|
command.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null));
|
||||||
command.setAccountId(accountId);
|
command.setAccountId(accountId);
|
||||||
Gson gson = new GsonBuilder().create();
|
Gson gson = new GsonBuilder().create();
|
||||||
String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
|
String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
|
||||||
@ -523,10 +523,14 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
// permission check
|
// permission check
|
||||||
Account volumeOwner = _accountMgr.getActiveAccountById(ownerId);
|
Account volumeOwner = _accountMgr.getActiveAccountById(ownerId);
|
||||||
|
DiskOfferingVO diskOffering = null;
|
||||||
|
if (diskOfferingId != null) {
|
||||||
|
diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
|
}
|
||||||
_accountMgr.checkAccess(caller, null, true, volumeOwner);
|
_accountMgr.checkAccess(caller, null, true, volumeOwner);
|
||||||
|
|
||||||
// Check that the resource limit for volumes won't be exceeded
|
// Check that the resource limit for volumes won't be exceeded
|
||||||
_resourceLimitMgr.checkResourceLimit(volumeOwner, ResourceType.volume);
|
_resourceLimitMgr.checkVolumeResourceLimit(volumeOwner, true, null, diskOffering);
|
||||||
|
|
||||||
// Verify that zone exists
|
// Verify that zone exists
|
||||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||||
@ -559,7 +563,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
// Check that the disk offering specified is valid
|
// Check that the disk offering specified is valid
|
||||||
if (diskOfferingId != null) {
|
if (diskOfferingId != null) {
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
|
||||||
if ((diskOffering == null) || diskOffering.getRemoved() != null || diskOffering.isComputeOnly()) {
|
if ((diskOffering == null) || diskOffering.getRemoved() != null || diskOffering.isComputeOnly()) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid disk offering.");
|
throw new InvalidParameterValueException("Please specify a valid disk offering.");
|
||||||
}
|
}
|
||||||
@ -649,7 +652,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
// Increment resource count during allocation; if actual creation fails,
|
// Increment resource count during allocation; if actual creation fails,
|
||||||
// decrement it
|
// decrement it
|
||||||
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume);
|
_resourceLimitMgr.incrementVolumeResourceCount(volume.getAccountId(), true, null, diskOfferingVO);
|
||||||
//url can be null incase of postupload
|
//url can be null incase of postupload
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
|
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
|
||||||
@ -706,9 +709,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the resource limit for volumes won't be exceeded
|
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, displayVolume);
|
|
||||||
|
|
||||||
Long zoneId = cmd.getZoneId();
|
Long zoneId = cmd.getZoneId();
|
||||||
Long diskOfferingId = null;
|
Long diskOfferingId = null;
|
||||||
DiskOfferingVO diskOffering = null;
|
DiskOfferingVO diskOffering = null;
|
||||||
@ -891,8 +891,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
Storage.ProvisioningType provisioningType = diskOffering.getProvisioningType();
|
Storage.ProvisioningType provisioningType = diskOffering.getProvisioningType();
|
||||||
|
|
||||||
// Check that the resource limit for primary storage won't be exceeded
|
// Check that the resource limit for volume & primary storage won't be exceeded
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, displayVolume, new Long(size));
|
_resourceLimitMgr.checkVolumeResourceLimit(owner,displayVolume, size, diskOffering);
|
||||||
|
|
||||||
// Verify that zone exists
|
// Verify that zone exists
|
||||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||||
@ -978,8 +978,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
CallContext.current().putContextParameter(Volume.class, volume.getId());
|
CallContext.current().putContextParameter(Volume.class, volume.getId());
|
||||||
// Increment resource count during allocation; if actual creation fails,
|
// Increment resource count during allocation; if actual creation fails,
|
||||||
// decrement it
|
// decrement it
|
||||||
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume, displayVolume);
|
_resourceLimitMgr.incrementVolumeResourceCount(volume.getAccountId(), displayVolume, volume.getSize(),
|
||||||
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolume, new Long(volume.getSize()));
|
_diskOfferingDao.findById(volume.getDiskOfferingId()));
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1038,8 +1038,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
} finally {
|
} finally {
|
||||||
if (!created) {
|
if (!created) {
|
||||||
logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend");
|
logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend");
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, cmd.getDisplayVolume());
|
_resourceLimitMgr.decrementVolumeResourceCount(volume.getAccountId(), cmd.getDisplayVolume(),
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, cmd.getDisplayVolume(), new Long(volume.getSize()));
|
volume.getSize(), _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1527,10 +1527,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Update resource count for the account on primary storage resource */
|
/* Update resource count for the account on primary storage resource */
|
||||||
|
DiskOffering diskOffering = _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId());
|
||||||
if (!shrinkOk) {
|
if (!shrinkOk) {
|
||||||
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), newSize - currentSize);
|
_resourceLimitMgr.incrementVolumePrimaryStorageResourceCount(volume.getAccountId(), volume.isDisplayVolume(), newSize - currentSize, diskOffering);
|
||||||
} else {
|
} else {
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), currentSize - newSize);
|
_resourceLimitMgr.decrementVolumePrimaryStorageResourceCount(volume.getAccountId(), volume.isDisplayVolume(), currentSize - newSize, diskOffering);
|
||||||
}
|
}
|
||||||
|
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||||
@ -1732,8 +1733,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
logger.debug("Failed to destroy volume" + volume.getId(), e);
|
logger.debug("Failed to destroy volume" + volume.getId(), e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplay());
|
_resourceLimitMgr.decrementVolumeResourceCount(volume.getAccountId(), volume.isDisplay(),
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplay(), new Long(volume.getSize()));
|
volume.getSize(), _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId()));
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
if (!deleteVolumeFromStorage(volume, caller)) {
|
if (!deleteVolumeFromStorage(volume, caller)) {
|
||||||
@ -1790,8 +1791,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
logger.debug("Failed to recover volume" + volume.getId(), e);
|
logger.debug("Failed to recover volume" + volume.getId(), e);
|
||||||
throw new CloudRuntimeException("Failed to recover volume" + volume.getId(), e);
|
throw new CloudRuntimeException("Failed to recover volume" + volume.getId(), e);
|
||||||
}
|
}
|
||||||
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplay());
|
_resourceLimitMgr.incrementVolumeResourceCount(volume.getAccountId(), volume.isDisplay(),
|
||||||
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplay(), new Long(volume.getSize()));
|
volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()));
|
||||||
|
|
||||||
|
|
||||||
publishVolumeCreationUsageEvent(volume);
|
publishVolumeCreationUsageEvent(volume);
|
||||||
@ -2023,9 +2024,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
/* Only works for KVM/XenServer/VMware (or "Any") for now, and volumes with 'None' since they're just allocated in DB */
|
/* Only works for KVM/XenServer/VMware (or "Any") for now, and volumes with 'None' since they're just allocated in DB */
|
||||||
HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
|
HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
|
||||||
|
|
||||||
if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer
|
if (!SupportedHypervisorsForVolResize.contains(hypervisorType)) {
|
||||||
&& hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Any
|
|
||||||
&& hypervisorType != HypervisorType.None) {
|
|
||||||
throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support volume resize");
|
throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support volume resize");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2648,8 +2647,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
private void updateResourceCount(Volume volume, Boolean displayVolume) {
|
private void updateResourceCount(Volume volume, Boolean displayVolume) {
|
||||||
// Update only when the flag has changed.
|
// Update only when the flag has changed.
|
||||||
if (displayVolume != null && displayVolume != volume.isDisplayVolume()) {
|
if (displayVolume != null && displayVolume != volume.isDisplayVolume()) {
|
||||||
_resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.volume, displayVolume);
|
if (Boolean.FALSE.equals(displayVolume)) {
|
||||||
_resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolume, new Long(volume.getSize()));
|
_resourceLimitMgr.decrementVolumeResourceCount(volume.getAccountId(), true, volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()));
|
||||||
|
} else {
|
||||||
|
_resourceLimitMgr.incrementVolumeResourceCount(volume.getAccountId(), true, volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3868,8 +3870,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
_accountMgr.checkAccess(caller, null, true, oldAccount);
|
_accountMgr.checkAccess(caller, null, true, oldAccount);
|
||||||
_accountMgr.checkAccess(caller, null, true, newAccount);
|
_accountMgr.checkAccess(caller, null, true, newAccount);
|
||||||
|
|
||||||
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume);
|
_resourceLimitMgr.checkVolumeResourceLimit(newAccount, true, volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()));
|
||||||
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.primary_storage, volume.getSize());
|
|
||||||
|
|
||||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||||
@Override
|
@Override
|
||||||
@ -3884,16 +3885,15 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
protected void updateVolumeAccount(Account oldAccount, VolumeVO volume, Account newAccount) {
|
protected void updateVolumeAccount(Account oldAccount, VolumeVO volume, Account newAccount) {
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||||
Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
|
Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
|
||||||
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
|
DiskOfferingVO diskOfferingVO = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
||||||
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, volume.getSize());
|
_resourceLimitMgr.decrementVolumeResourceCount(oldAccount.getAccountId(), true, volume.getSize(),
|
||||||
|
diskOfferingVO);
|
||||||
|
|
||||||
volume.setAccountId(newAccount.getAccountId());
|
volume.setAccountId(newAccount.getAccountId());
|
||||||
volume.setDomainId(newAccount.getDomainId());
|
volume.setDomainId(newAccount.getDomainId());
|
||||||
_volsDao.persist(volume);
|
_volsDao.persist(volume);
|
||||||
|
_resourceLimitMgr.incrementVolumeResourceCount(newAccount.getAccountId(), true, volume.getSize(),
|
||||||
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
|
diskOfferingVO);
|
||||||
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, volume.getSize());
|
|
||||||
|
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||||
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),
|
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),
|
||||||
volume.getUuid(), volume.isDisplayVolume());
|
volume.getUuid(), volume.isDisplayVolume());
|
||||||
|
|||||||
@ -1036,8 +1036,8 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
|
|||||||
|
|
||||||
// Verify that max doesn't exceed domain and account snapshot limits in case display is on
|
// Verify that max doesn't exceed domain and account snapshot limits in case display is on
|
||||||
if (display) {
|
if (display) {
|
||||||
long accountLimit = _resourceLimitMgr.findCorrectResourceLimitForAccount(owner, ResourceType.snapshot);
|
long accountLimit = _resourceLimitMgr.findCorrectResourceLimitForAccount(owner, ResourceType.snapshot, null);
|
||||||
long domainLimit = _resourceLimitMgr.findCorrectResourceLimitForDomain(_domainMgr.getDomain(owner.getDomainId()), ResourceType.snapshot);
|
long domainLimit = _resourceLimitMgr.findCorrectResourceLimitForDomain(_domainMgr.getDomain(owner.getDomainId()), ResourceType.snapshot, null);
|
||||||
if (!_accountMgr.isRootAdmin(owner.getId()) && ((accountLimit != -1 && maxSnaps > accountLimit) || (domainLimit != -1 && maxSnaps > domainLimit))) {
|
if (!_accountMgr.isRootAdmin(owner.getId()) && ((accountLimit != -1 && maxSnaps > accountLimit) || (domainLimit != -1 && maxSnaps > domainLimit))) {
|
||||||
String message = "domain/account";
|
String message = "domain/account";
|
||||||
if (owner.getType() == Account.Type.PROJECT) {
|
if (owner.getType() == Account.Type.PROJECT) {
|
||||||
|
|||||||
@ -421,7 +421,6 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
|
|||||||
postUploadAllocation(imageStores, template, payloads);
|
postUploadAllocation(imageStores, template, payloads);
|
||||||
} else {
|
} else {
|
||||||
postUploadAllocation(List.of(imageStore), template, payloads);
|
postUploadAllocation(List.of(imageStore), template, payloads);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(payloads.isEmpty()) {
|
if(payloads.isEmpty()) {
|
||||||
@ -470,7 +469,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
|
|||||||
Account account = _accountDao.findById(accountId);
|
Account account = _accountDao.findById(accountId);
|
||||||
Domain domain = _domainDao.findById(account.getDomainId());
|
Domain domain = _domainDao.findById(account.getDomainId());
|
||||||
|
|
||||||
payload.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage));
|
payload.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null));
|
||||||
payload.setAccountId(accountId);
|
payload.setAccountId(accountId);
|
||||||
payload.setRemoteEndPoint(ep.getPublicAddr());
|
payload.setRemoteEndPoint(ep.getPublicAddr());
|
||||||
payload.setRequiresHvm(template.requiresHvm());
|
payload.setRequiresHvm(template.requiresHvm());
|
||||||
|
|||||||
@ -2135,6 +2135,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
|
|
||||||
// update template type
|
// update template type
|
||||||
TemplateType templateType = null;
|
TemplateType templateType = null;
|
||||||
|
String templateTag = null;
|
||||||
if (cmd instanceof UpdateTemplateCmd) {
|
if (cmd instanceof UpdateTemplateCmd) {
|
||||||
boolean isAdmin = _accountMgr.isAdmin(account.getId());
|
boolean isAdmin = _accountMgr.isAdmin(account.getId());
|
||||||
templateType = validateTemplateType(cmd, isAdmin, template.isCrossZones());
|
templateType = validateTemplateType(cmd, isAdmin, template.isCrossZones());
|
||||||
@ -2142,6 +2143,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
VnfTemplateUtils.validateApiCommandParams(cmd, template);
|
VnfTemplateUtils.validateApiCommandParams(cmd, template);
|
||||||
vnfTemplateManager.updateVnfTemplate(template.getId(), (UpdateVnfTemplateCmd) cmd);
|
vnfTemplateManager.updateVnfTemplate(template.getId(), (UpdateVnfTemplateCmd) cmd);
|
||||||
}
|
}
|
||||||
|
templateTag = ((UpdateTemplateCmd)cmd).getTemplateTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
// update is needed if any of the fields below got filled by the user
|
// update is needed if any of the fields below got filled by the user
|
||||||
@ -2158,6 +2160,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
isDynamicallyScalable == null &&
|
isDynamicallyScalable == null &&
|
||||||
isRoutingTemplate == null &&
|
isRoutingTemplate == null &&
|
||||||
templateType == null &&
|
templateType == null &&
|
||||||
|
templateTag == null &&
|
||||||
(! cleanupDetails && details == null) //update details in every case except this one
|
(! cleanupDetails && details == null) //update details in every case except this one
|
||||||
);
|
);
|
||||||
if (!updateNeeded) {
|
if (!updateNeeded) {
|
||||||
@ -2243,6 +2246,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
} else if (templateType != null) {
|
} else if (templateType != null) {
|
||||||
template.setTemplateType(templateType);
|
template.setTemplateType(templateType);
|
||||||
}
|
}
|
||||||
|
if (templateTag != null) {
|
||||||
|
template.setTemplateTag(org.apache.commons.lang3.StringUtils.trimToNull(templateTag));
|
||||||
|
}
|
||||||
|
|
||||||
validateDetails(template, details);
|
validateDetails(template, details);
|
||||||
|
|
||||||
|
|||||||
@ -982,25 +982,43 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
|
|||||||
return domainToBeMoved;
|
return domainToBeMoved;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void validateNewParentDomainResourceLimits(DomainVO domainToBeMoved, DomainVO newParentDomain) throws ResourceAllocationException {
|
protected void validateNewParentDomainResourceLimit(DomainVO domainToBeMoved, DomainVO newParentDomain,
|
||||||
|
Resource.ResourceType resourceType, String tag) throws ResourceAllocationException {
|
||||||
long domainToBeMovedId = domainToBeMoved.getId();
|
long domainToBeMovedId = domainToBeMoved.getId();
|
||||||
long newParentDomainId = newParentDomain.getId();
|
long newParentDomainId = newParentDomain.getId();
|
||||||
|
long currentDomainResourceCount = _resourceCountDao.getResourceCount(domainToBeMovedId, ResourceOwnerType.Domain, resourceType, tag);
|
||||||
|
long newParentDomainResourceCount = _resourceCountDao.getResourceCount(newParentDomainId, ResourceOwnerType.Domain, resourceType, tag);
|
||||||
|
long newParentDomainResourceLimit = resourceLimitService.findCorrectResourceLimitForDomain(newParentDomain, resourceType, tag);
|
||||||
|
|
||||||
|
if (newParentDomainResourceLimit == Resource.RESOURCE_UNLIMITED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDomainResourceCount + newParentDomainResourceCount > newParentDomainResourceLimit) {
|
||||||
|
String message = String.format("Cannot move domain [%s] to parent domain [%s] as maximum domain resource limit of type [%s] would be exceeded. The current resource "
|
||||||
|
+ "count for domain [%s] is [%s], the resource count for the new parent domain [%s] is [%s], and the limit is [%s].", domainToBeMoved.getUuid(),
|
||||||
|
newParentDomain.getUuid(), resourceType, domainToBeMoved.getUuid(), currentDomainResourceCount, newParentDomain.getUuid(), newParentDomainResourceCount,
|
||||||
|
newParentDomainResourceLimit);
|
||||||
|
logger.error(message);
|
||||||
|
throw new ResourceAllocationException(message, resourceType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void validateNewParentDomainResourceLimits(DomainVO domainToBeMoved, DomainVO newParentDomain) throws ResourceAllocationException {
|
||||||
|
List<String> hostTags = resourceLimitService.getResourceLimitHostTags();
|
||||||
|
List<String> storageTags = resourceLimitService.getResourceLimitStorageTags();
|
||||||
for (Resource.ResourceType resourceType : Resource.ResourceType.values()) {
|
for (Resource.ResourceType resourceType : Resource.ResourceType.values()) {
|
||||||
long currentDomainResourceCount = _resourceCountDao.getResourceCount(domainToBeMovedId, ResourceOwnerType.Domain, resourceType);
|
validateNewParentDomainResourceLimit(domainToBeMoved, newParentDomain, resourceType, null);
|
||||||
long newParentDomainResourceCount = _resourceCountDao.getResourceCount(newParentDomainId, ResourceOwnerType.Domain, resourceType);
|
if (ResourceLimitService.HostTagsSupportingTypes.contains(resourceType)) {
|
||||||
long newParentDomainResourceLimit = resourceLimitService.findCorrectResourceLimitForDomain(newParentDomain, resourceType);
|
for (String tag : hostTags) {
|
||||||
|
validateNewParentDomainResourceLimit(domainToBeMoved, newParentDomain, resourceType, tag);
|
||||||
if (newParentDomainResourceLimit == Resource.RESOURCE_UNLIMITED) {
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (ResourceLimitService.StorageTagsSupportingTypes.contains(resourceType)) {
|
||||||
if (currentDomainResourceCount + newParentDomainResourceCount > newParentDomainResourceLimit) {
|
for (String tag : storageTags) {
|
||||||
String message = String.format("Cannot move domain [%s] to parent domain [%s] as maximum domain resource limit of type [%s] would be exceeded. The current resource "
|
validateNewParentDomainResourceLimit(domainToBeMoved, newParentDomain, resourceType, tag);
|
||||||
+ "count for domain [%s] is [%s], the resource count for the new parent domain [%s] is [%s], and the limit is [%s].", domainToBeMoved.getUuid(),
|
}
|
||||||
newParentDomain.getUuid(), resourceType, domainToBeMoved.getUuid(), currentDomainResourceCount, newParentDomain.getUuid(), newParentDomainResourceCount,
|
|
||||||
newParentDomainResourceLimit);
|
|
||||||
logger.error(message);
|
|
||||||
throw new ResourceAllocationException(message, resourceType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -682,25 +682,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
return _vmDao.listByHostId(hostId);
|
return _vmDao.listByHostId(hostId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resourceLimitCheck(Account owner, Boolean displayVm, Long cpu, Long memory) throws ResourceAllocationException {
|
protected void resourceCountIncrement(long accountId, Boolean displayVm, ServiceOffering serviceOffering, VirtualMachineTemplate template) {
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.user_vm, displayVm);
|
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, displayVm, cpu);
|
_resourceLimitMgr.incrementVmResourceCount(accountId, displayVm, serviceOffering, template);
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, displayVm, memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void resourceCountIncrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
|
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
|
||||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm, displayVm);
|
|
||||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
|
|
||||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void resourceCountDecrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
|
protected void resourceCountDecrement(long accountId, Boolean displayVm, ServiceOffering serviceOffering, VirtualMachineTemplate template) {
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm, displayVm);
|
_resourceLimitMgr.decrementVmResourceCount(accountId, displayVm, serviceOffering, template);
|
||||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
|
|
||||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1339,12 +1329,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
int currentMemory = currentServiceOffering.getRamSize();
|
int currentMemory = currentServiceOffering.getRamSize();
|
||||||
|
|
||||||
Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId());
|
Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId());
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||||
if (newCpu > currentCpu) {
|
if (newCpu > currentCpu) {
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, newCpu - currentCpu);
|
_resourceLimitMgr.checkVmCpuResourceLimit(owner, vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||||
}
|
}
|
||||||
if (newMemory > currentMemory) {
|
if (newMemory > currentMemory) {
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, newMemory - currentMemory);
|
_resourceLimitMgr.checkVmMemoryResourceLimit(owner, vmInstance.isDisplay(), newServiceOffering, template, (long)(newMemory - currentMemory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1363,14 +1354,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
// Increment or decrement CPU and Memory count accordingly.
|
// Increment or decrement CPU and Memory count accordingly.
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||||
if (newCpu > currentCpu) {
|
if (newCpu > currentCpu) {
|
||||||
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
|
_resourceLimitMgr.incrementVmCpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||||
} else if (currentCpu > newCpu) {
|
} else if (currentCpu > newCpu) {
|
||||||
_resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu));
|
_resourceLimitMgr.decrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(currentCpu - newCpu));
|
||||||
}
|
}
|
||||||
if (newMemory > currentMemory) {
|
if (newMemory > currentMemory) {
|
||||||
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory));
|
_resourceLimitMgr.incrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(newMemory - currentMemory));
|
||||||
} else if (currentMemory > newMemory) {
|
} else if (currentMemory > newMemory) {
|
||||||
_resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory));
|
_resourceLimitMgr.decrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(currentMemory - newMemory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1960,10 +1951,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
if (State.Running.equals(vmInstance.getState())) {
|
if (State.Running.equals(vmInstance.getState())) {
|
||||||
ServiceOfferingVO newServiceOfferingVO = serviceOfferingDao.findById(newServiceOfferingId);
|
ServiceOfferingVO newServiceOfferingVO = serviceOfferingDao.findById(newServiceOfferingId);
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||||
HostVO instanceHost = _hostDao.findById(vmInstance.getHostId());
|
HostVO instanceHost = _hostDao.findById(vmInstance.getHostId());
|
||||||
_hostDao.loadHostTags(instanceHost);
|
_hostDao.loadHostTags(instanceHost);
|
||||||
|
|
||||||
if (!instanceHost.checkHostServiceOfferingTags(newServiceOfferingVO)) {
|
if (!instanceHost.checkHostServiceOfferingAndTemplateTags(newServiceOfferingVO, template)) {
|
||||||
logger.error(String.format("Cannot upgrade VM [%s] as the new service offering [%s] does not have the required host tags %s.", vmInstance, newServiceOfferingVO,
|
logger.error(String.format("Cannot upgrade VM [%s] as the new service offering [%s] does not have the required host tags %s.", vmInstance, newServiceOfferingVO,
|
||||||
instanceHost.getHostTags()));
|
instanceHost.getHostTags()));
|
||||||
return false;
|
return false;
|
||||||
@ -1977,6 +1969,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
|
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
|
||||||
|
Account owner = _accountDao.findById(vmInstance.getAccountId());
|
||||||
|
|
||||||
Set<HypervisorType> supportedHypervisorTypes = new HashSet<>();
|
Set<HypervisorType> supportedHypervisorTypes = new HashSet<>();
|
||||||
supportedHypervisorTypes.add(HypervisorType.XenServer);
|
supportedHypervisorTypes.add(HypervisorType.XenServer);
|
||||||
@ -2048,13 +2041,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
throw new InvalidParameterValueException(String.format("Dynamic scaling of vGPU type is not supported. VM has vGPU Type: [%s].", currentVgpuType));
|
throw new InvalidParameterValueException(String.format("Dynamic scaling of vGPU type is not supported. VM has vGPU Type: [%s].", currentVgpuType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||||
|
|
||||||
// Check resource limits
|
// Check resource limits
|
||||||
if (newCpu > currentCpu) {
|
if (newCpu > currentCpu) {
|
||||||
_resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, newCpu - currentCpu);
|
_resourceLimitMgr.checkVmCpuResourceLimit(owner, vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newMemory > currentMemory) {
|
if (newMemory > currentMemory) {
|
||||||
_resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, memoryDiff);
|
_resourceLimitMgr.checkVmMemoryResourceLimit(caller, vmInstance.isDisplay(), newServiceOffering, template, (long)memoryDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamically upgrade the running vms
|
// Dynamically upgrade the running vms
|
||||||
@ -2086,11 +2081,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
// Increment CPU and Memory count accordingly.
|
// Increment CPU and Memory count accordingly.
|
||||||
if (newCpu > currentCpu) {
|
if (newCpu > currentCpu) {
|
||||||
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
|
_resourceLimitMgr.incrementVmCpuResourceCount(caller.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memoryDiff > 0) {
|
if (memoryDiff > 0) {
|
||||||
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
|
_resourceLimitMgr.incrementVmMemoryResourceCount(caller.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)memoryDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #1 Check existing host has capacity
|
// #1 Check existing host has capacity
|
||||||
@ -2122,11 +2117,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
// Decrement CPU and Memory count accordingly.
|
// Decrement CPU and Memory count accordingly.
|
||||||
if (newCpu > currentCpu) {
|
if (newCpu > currentCpu) {
|
||||||
_resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
|
_resourceLimitMgr.decrementVmCpuResourceCount(caller.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)(newCpu - currentCpu));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memoryDiff > 0) {
|
if (memoryDiff > 0) {
|
||||||
_resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
|
_resourceLimitMgr.decrementVmMemoryResourceCount(caller.getAccountId(), vmInstance.isDisplay(), newServiceOffering, template, (long)memoryDiff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2315,11 +2310,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
// Get serviceOffering for Virtual Machine
|
// Get serviceOffering for Virtual Machine
|
||||||
ServiceOfferingVO serviceOffering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
ServiceOfferingVO serviceOffering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||||
|
|
||||||
// First check that the maximum number of UserVMs, CPU and Memory limit for the given
|
// First check that the maximum number of UserVMs, CPU and Memory limit for the given
|
||||||
// accountId will not be exceeded
|
// accountId will not be exceeded
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||||
resourceLimitCheck(account, vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
|
resourceLimitService.checkVmResourceLimit(account, vm.isDisplayVm(), serviceOffering, template);
|
||||||
}
|
}
|
||||||
|
|
||||||
_haMgr.cancelDestroy(vm, vm.getHostId());
|
_haMgr.cancelDestroy(vm, vm.getHostId());
|
||||||
@ -2343,7 +2339,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Update Resource Count for the given account
|
//Update Resource Count for the given account
|
||||||
resourceCountIncrement(account.getId(), vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
|
resourceCountIncrement(account.getId(), vm.isDisplayVm(), serviceOffering, template);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2632,11 +2628,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
String msg = "Failed to deploy Vm with Id: " + vmId + ", on Host with Id: " + hostId;
|
String msg = "Failed to deploy Vm with Id: " + vmId + ", on Host with Id: " + hostId;
|
||||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||||
|
|
||||||
// Get serviceOffering for Virtual Machine
|
// Get serviceOffering and template for Virtual Machine
|
||||||
ServiceOfferingVO offering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
ServiceOfferingVO offering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||||
|
|
||||||
// Update Resource Count for the given account
|
// Update Resource Count for the given account
|
||||||
resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), offering, template);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2758,13 +2755,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
long currentCpu = currentServiceOffering.getCpu();
|
long currentCpu = currentServiceOffering.getCpu();
|
||||||
long currentMemory = currentServiceOffering.getRamSize();
|
long currentMemory = currentServiceOffering.getRamSize();
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||||
try {
|
try {
|
||||||
if (newCpu > currentCpu) {
|
if (newCpu > currentCpu) {
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, newCpu - currentCpu);
|
_resourceLimitMgr.checkVmCpuResourceLimit(owner, vmInstance.isDisplay(), svcOffering, template, newCpu - currentCpu);
|
||||||
}
|
}
|
||||||
if (newMemory > currentMemory) {
|
if (newMemory > currentMemory) {
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, newMemory - currentMemory);
|
_resourceLimitMgr.checkVmMemoryResourceLimit(owner, vmInstance.isDisplay(), svcOffering, template, newMemory - currentMemory);
|
||||||
}
|
}
|
||||||
} catch (ResourceAllocationException e) {
|
} catch (ResourceAllocationException e) {
|
||||||
logger.error(String.format("Failed to updated VM due to: %s", e.getLocalizedMessage()));
|
logger.error(String.format("Failed to updated VM due to: %s", e.getLocalizedMessage()));
|
||||||
@ -2772,14 +2769,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (newCpu > currentCpu) {
|
if (newCpu > currentCpu) {
|
||||||
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.cpu, newCpu - currentCpu);
|
_resourceLimitMgr.incrementVmCpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, newCpu - currentCpu);
|
||||||
} else if (newCpu > 0 && currentCpu > newCpu){
|
} else if (newCpu > 0 && currentCpu > newCpu){
|
||||||
_resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.cpu, currentCpu - newCpu);
|
_resourceLimitMgr.decrementVmCpuResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, currentCpu - newCpu);
|
||||||
}
|
}
|
||||||
if (newMemory > currentMemory) {
|
if (newMemory > currentMemory) {
|
||||||
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.memory, newMemory - currentMemory);
|
_resourceLimitMgr.incrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, newMemory - currentMemory);
|
||||||
} else if (newMemory > 0 && currentMemory > newMemory){
|
} else if (newMemory > 0 && currentMemory > newMemory){
|
||||||
_resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.memory, currentMemory - newMemory);
|
_resourceLimitMgr.decrementVmMemoryResourceCount(owner.getAccountId(), vmInstance.isDisplay(), svcOffering, template, currentMemory - newMemory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2900,10 +2897,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
// Resource limit changes
|
// Resource limit changes
|
||||||
ServiceOffering offering = serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
|
ServiceOffering offering = serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||||
if (isDisplayVm) {
|
if (isDisplayVm) {
|
||||||
resourceCountIncrement(vmInstance.getAccountId(), true, Long.valueOf(offering.getCpu()), Long.valueOf(offering.getRamSize()));
|
resourceCountIncrement(vmInstance.getAccountId(), true, offering, template);
|
||||||
} else {
|
} else {
|
||||||
resourceCountDecrement(vmInstance.getAccountId(), true, Long.valueOf(offering.getCpu()), Long.valueOf(offering.getRamSize()));
|
resourceCountDecrement(vmInstance.getAccountId(), true, offering, template);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Usage
|
// Usage
|
||||||
@ -4035,11 +4033,22 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid());
|
CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid());
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
private UserVm getCheckedUserVmResource(DataCenter zone, String hostName, String displayName, Account owner, Long diskOfferingId, Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard, List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap, Map<String, String> userVmOVFPropertiesMap, boolean dynamicScalingEnabled, String vmType, VMTemplateVO template, HypervisorType hypervisorType, long accountId, ServiceOfferingVO offering, boolean isIso, Long rootDiskOfferingId, long volumesSize) throws ResourceAllocationException, StorageUnavailableException, InsufficientCapacityException {
|
|
||||||
|
private UserVm getCheckedUserVmResource(DataCenter zone, String hostName, String displayName, Account owner,
|
||||||
|
Long diskOfferingId, Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group,
|
||||||
|
HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs,
|
||||||
|
Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean isDisplayVm,
|
||||||
|
String keyboard, List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId,
|
||||||
|
Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap,
|
||||||
|
Map<String, String> userVmOVFPropertiesMap, boolean dynamicScalingEnabled, String vmType, VMTemplateVO template,
|
||||||
|
HypervisorType hypervisorType, long accountId, ServiceOfferingVO offering, boolean isIso,
|
||||||
|
Long rootDiskOfferingId, long volumesSize) throws ResourceAllocationException, StorageUnavailableException,
|
||||||
|
InsufficientCapacityException {
|
||||||
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||||
try (CheckedReservation vmReservation = new CheckedReservation(owner, ResourceType.user_vm, 1l, reservationDao, resourceLimitService);
|
List<String> resourceLimitHostTags = resourceLimitService.getResourceLimitHostTags(offering, template);
|
||||||
CheckedReservation cpuReservation = new CheckedReservation(owner, ResourceType.cpu, Long.valueOf(offering.getCpu()), reservationDao, resourceLimitService);
|
try (CheckedReservation vmReservation = new CheckedReservation(owner, ResourceType.user_vm, resourceLimitHostTags, 1l, reservationDao, resourceLimitService);
|
||||||
CheckedReservation memReservation = new CheckedReservation(owner, ResourceType.memory, Long.valueOf(offering.getRamSize()), reservationDao, resourceLimitService);
|
CheckedReservation cpuReservation = new CheckedReservation(owner, ResourceType.cpu, resourceLimitHostTags, Long.valueOf(offering.getCpu()), reservationDao, resourceLimitService);
|
||||||
|
CheckedReservation memReservation = new CheckedReservation(owner, ResourceType.memory, resourceLimitHostTags, Long.valueOf(offering.getRamSize()), reservationDao, resourceLimitService);
|
||||||
) {
|
) {
|
||||||
return getUncheckedUserVmResource(zone, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod, userData, userDataId, userDataDetails, sshKeyPairs, caller, requestedIps, defaultIps, isDisplayVm, keyboard, affinityGroupIdList, customParameters, customId, dhcpOptionMap, datadiskTemplateToDiskOfferringMap, userVmOVFPropertiesMap, dynamicScalingEnabled, vmType, template, hypervisorType, accountId, offering, isIso, rootDiskOfferingId, volumesSize);
|
return getUncheckedUserVmResource(zone, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod, userData, userDataId, userDataDetails, sshKeyPairs, caller, requestedIps, defaultIps, isDisplayVm, keyboard, affinityGroupIdList, customParameters, customId, dhcpOptionMap, datadiskTemplateToDiskOfferringMap, userVmOVFPropertiesMap, dynamicScalingEnabled, vmType, template, hypervisorType, accountId, offering, isIso, rootDiskOfferingId, volumesSize);
|
||||||
} catch (ResourceAllocationException | CloudRuntimeException e) {
|
} catch (ResourceAllocationException | CloudRuntimeException e) {
|
||||||
@ -4054,9 +4063,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, String displayName, Account owner, Long diskOfferingId, Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard, List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap, Map<String, String> userVmOVFPropertiesMap, boolean dynamicScalingEnabled, String vmType, VMTemplateVO template, HypervisorType hypervisorType, long accountId, ServiceOfferingVO offering, boolean isIso, Long rootDiskOfferingId, long volumesSize) throws ResourceAllocationException, StorageUnavailableException, InsufficientCapacityException {
|
protected List<String> getResourceLimitStorageTags(long diskOfferingId) {
|
||||||
try (CheckedReservation volumeReservation = new CheckedReservation(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1l : 2), reservationDao, resourceLimitService);
|
DiskOfferingVO diskOfferingVO = _diskOfferingDao.findById(diskOfferingId);
|
||||||
CheckedReservation primaryStorageReservation = new CheckedReservation(owner, ResourceType.primary_storage, volumesSize, reservationDao, resourceLimitService)) {
|
return resourceLimitService.getResourceLimitStorageTags(diskOfferingVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, String displayName, Account owner,
|
||||||
|
Long diskOfferingId, Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group,
|
||||||
|
HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs,
|
||||||
|
Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean isDisplayVm,
|
||||||
|
String keyboard, List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId,
|
||||||
|
Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap,
|
||||||
|
Map<String, String> userVmOVFPropertiesMap, boolean dynamicScalingEnabled, String vmType, VMTemplateVO template,
|
||||||
|
HypervisorType hypervisorType, long accountId, ServiceOfferingVO offering, boolean isIso,
|
||||||
|
Long rootDiskOfferingId, long volumesSize) throws ResourceAllocationException, StorageUnavailableException,
|
||||||
|
InsufficientCapacityException {
|
||||||
|
List<String> resourceLimitStorageTags = getResourceLimitStorageTags(diskOfferingId != null ? diskOfferingId : offering.getDiskOfferingId());
|
||||||
|
try (CheckedReservation volumeReservation = new CheckedReservation(owner, ResourceType.volume, resourceLimitStorageTags, (isIso || diskOfferingId == null ? 1l : 2), reservationDao, resourceLimitService);
|
||||||
|
CheckedReservation primaryStorageReservation = new CheckedReservation(owner, ResourceType.primary_storage, resourceLimitStorageTags, volumesSize, reservationDao, resourceLimitService)) {
|
||||||
|
|
||||||
// verify security group ids
|
// verify security group ids
|
||||||
if (securityGroupIdList != null) {
|
if (securityGroupIdList != null) {
|
||||||
@ -4098,8 +4122,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
dataDiskTemplateId + ". Disk offering size should be greater than or equal to the template size");
|
dataDiskTemplateId + ". Disk offering size should be greater than or equal to the template size");
|
||||||
}
|
}
|
||||||
_templateDao.loadDetails(dataDiskTemplate);
|
_templateDao.loadDetails(dataDiskTemplate);
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, 1);
|
resourceLimitService.checkVolumeResourceLimit(owner, true, dataDiskOffering.getDiskSize(), dataDiskOffering);
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, dataDiskOffering.getDiskSize());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4603,7 +4626,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
//Update Resource Count for the given account
|
//Update Resource Count for the given account
|
||||||
resourceCountIncrement(accountId, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
resourceCountIncrement(accountId, isDisplayVm, offering, template);
|
||||||
} catch (CloudRuntimeException cre) {
|
} catch (CloudRuntimeException cre) {
|
||||||
ArrayList<ExceptionProxyObject> epoList = cre.getIdProxyList();
|
ArrayList<ExceptionProxyObject> epoList = cre.getIdProxyList();
|
||||||
if (epoList == null || !epoList.stream().anyMatch( e -> e.getUuid().equals(vm.getUuid()))) {
|
if (epoList == null || !epoList.stream().anyMatch( e -> e.getUuid().equals(vm.getUuid()))) {
|
||||||
@ -5420,10 +5443,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
if (owner.getState() == Account.State.DISABLED) {
|
if (owner.getState() == Account.State.DISABLED) {
|
||||||
throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId());
|
throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId());
|
||||||
}
|
}
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||||
if (VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
if (VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||||
// check if account/domain is with in resource limits to start a new vm
|
// check if account/domain is with in resource limits to start a new vm
|
||||||
ServiceOfferingVO offering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
ServiceOfferingVO offering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
||||||
resourceLimitCheck(owner, vm.isDisplayVm(), Long.valueOf(offering.getCpu()), Long.valueOf(offering.getRamSize()));
|
resourceLimitService.checkVmResourceLimit(owner, vm.isDisplayVm(), offering, template);
|
||||||
}
|
}
|
||||||
// check if vm is security group enabled
|
// check if vm is security group enabled
|
||||||
if (_securityGroupMgr.isVmSecurityGroupEnabled(vmId) && _securityGroupMgr.getSecurityGroupsForVm(vmId).isEmpty()
|
if (_securityGroupMgr.isVmSecurityGroupEnabled(vmId) && _securityGroupMgr.getSecurityGroupsForVm(vmId).isEmpty()
|
||||||
@ -5481,11 +5505,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
// Set parameters
|
// Set parameters
|
||||||
Map<VirtualMachineProfile.Param, Object> params = null;
|
Map<VirtualMachineProfile.Param, Object> params = null;
|
||||||
VMTemplateVO template = null;
|
|
||||||
if (vm.isUpdateParameters()) {
|
if (vm.isUpdateParameters()) {
|
||||||
_vmDao.loadDetails(vm);
|
_vmDao.loadDetails(vm);
|
||||||
// Check that the password was passed in and is valid
|
|
||||||
template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
|
||||||
|
|
||||||
String password = getCurrentVmPasswordOrDefineNewPassword(String.valueOf(additionalParams.getOrDefault(VirtualMachineProfile.Param.VmPassword, "")), vm, template);
|
String password = getCurrentVmPasswordOrDefineNewPassword(String.valueOf(additionalParams.getOrDefault(VirtualMachineProfile.Param.VmPassword, "")), vm, template);
|
||||||
|
|
||||||
@ -5680,11 +5701,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vmState != State.Error) {
|
if (vmState != State.Error) {
|
||||||
// Get serviceOffering for Virtual Machine
|
// Get serviceOffering and template for Virtual Machine
|
||||||
ServiceOfferingVO offering = serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
|
ServiceOfferingVO offering = serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
|
||||||
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||||
//Update Resource Count for the given account
|
//Update Resource Count for the given account
|
||||||
resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(),offering, template);
|
||||||
}
|
}
|
||||||
return _vmDao.findById(vmId);
|
return _vmDao.findById(vmId);
|
||||||
} else {
|
} else {
|
||||||
@ -7179,6 +7200,41 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
return findMigratedVm(vm.getId(), vm.getType());
|
return findMigratedVm(vm.getId(), vm.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void checkVolumesLimits(Account account, List<VolumeVO> volumes) throws ResourceAllocationException {
|
||||||
|
Long totalVolumes = 0L;
|
||||||
|
Long totalVolumesSize = 0L;
|
||||||
|
Map<Long, List<String>> diskOfferingTagsMap = new HashMap<>();
|
||||||
|
Map<String, Long> tagVolumeCountMap = new HashMap<>();
|
||||||
|
Map<String, Long> tagSizeMap = new HashMap<>();
|
||||||
|
for (VolumeVO volume : volumes) {
|
||||||
|
if (!volume.isDisplay()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
totalVolumes++;
|
||||||
|
totalVolumesSize += volume.getSize();
|
||||||
|
if (!diskOfferingTagsMap.containsKey(volume.getDiskOfferingId())) {
|
||||||
|
diskOfferingTagsMap.put(volume.getDiskOfferingId(), _resourceLimitMgr.getResourceLimitStorageTags(
|
||||||
|
_diskOfferingDao.findById(volume.getDiskOfferingId())));
|
||||||
|
}
|
||||||
|
List<String> tags = diskOfferingTagsMap.get(volume.getDiskOfferingId());
|
||||||
|
for (String tag : tags) {
|
||||||
|
if (tagVolumeCountMap.containsKey(tag)) {
|
||||||
|
tagVolumeCountMap.put(tag, tagVolumeCountMap.get(tag) + 1);
|
||||||
|
tagSizeMap.put(tag, tagSizeMap.get(tag) + volume.getSize());
|
||||||
|
} else {
|
||||||
|
tagVolumeCountMap.put(tag, 1L);
|
||||||
|
tagSizeMap.put(tag, volume.getSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_resourceLimitMgr.checkResourceLimit(account, ResourceType.volume, totalVolumes);
|
||||||
|
_resourceLimitMgr.checkResourceLimit(account, ResourceType.primary_storage, totalVolumesSize);
|
||||||
|
for (String tag : tagVolumeCountMap.keySet()) {
|
||||||
|
resourceLimitService.checkResourceLimitWithTag(account, ResourceType.volume, tag, tagVolumeCountMap.get(tag));
|
||||||
|
resourceLimitService.checkResourceLimitWithTag(account, ResourceType.primary_storage, tag, tagSizeMap.get(tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@DB
|
@DB
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_VM_MOVE, eventDescription = "move VM to another user", async = false)
|
@ActionEvent(eventType = EventTypes.EVENT_VM_MOVE, eventDescription = "move VM to another user", async = false)
|
||||||
@ -7271,6 +7327,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
|
DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
|
||||||
|
|
||||||
|
VirtualMachineTemplate template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||||
// Get serviceOffering and Volumes for Virtual Machine
|
// Get serviceOffering and Volumes for Virtual Machine
|
||||||
final ServiceOfferingVO offering = serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
|
final ServiceOfferingVO offering = serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
|
||||||
|
|
||||||
@ -7278,20 +7335,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
removeInstanceFromInstanceGroup(cmd.getVmId());
|
removeInstanceFromInstanceGroup(cmd.getVmId());
|
||||||
|
|
||||||
// VV 2: check if account/domain is with in resource limits to create a new vm
|
// VV 2: check if account/domain is with in resource limits to create a new vm
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||||
resourceLimitCheck(newAccount, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
resourceLimitService.checkVmResourceLimit(newAccount, vm.isDisplayVm(), offering, template);
|
||||||
}
|
}
|
||||||
|
|
||||||
// VV 3: check if volumes and primary storage space are with in resource limits
|
// VV 3: check if volumes and primary storage space are with in resource limits
|
||||||
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume, _volsDao.findByInstance(cmd.getVmId()).size());
|
checkVolumesLimits(newAccount, volumes);
|
||||||
Long totalVolumesSize = (long)0;
|
|
||||||
for (VolumeVO volume : volumes) {
|
|
||||||
totalVolumesSize += volume.getSize();
|
|
||||||
}
|
|
||||||
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.primary_storage, totalVolumesSize);
|
|
||||||
|
|
||||||
// VV 4: Check if new owner can use the vm template
|
// VV 4: Check if new owner can use the vm template
|
||||||
VirtualMachineTemplate template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
throw new InvalidParameterValueException(String.format("Template for VM: %s cannot be found", vm.getUuid()));
|
throw new InvalidParameterValueException(String.format("Template for VM: %s cannot be found", vm.getUuid()));
|
||||||
}
|
}
|
||||||
@ -7312,7 +7363,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
|
vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
|
||||||
vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
|
vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
|
||||||
// update resource counts for old account
|
// update resource counts for old account
|
||||||
resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), offering, template);
|
||||||
|
|
||||||
// OWNERSHIP STEP 1: update the vm owner
|
// OWNERSHIP STEP 1: update the vm owner
|
||||||
vm.setAccountId(newAccount.getAccountId());
|
vm.setAccountId(newAccount.getAccountId());
|
||||||
@ -7323,22 +7374,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
for (VolumeVO volume : volumes) {
|
for (VolumeVO volume : volumes) {
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||||
Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
|
Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
|
||||||
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
|
DiskOfferingVO diskOfferingVO = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
||||||
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
|
_resourceLimitMgr.decrementVolumeResourceCount(oldAccount.getAccountId(), volume.isDisplay(), volume.getSize(), diskOfferingVO);
|
||||||
volume.setAccountId(newAccount.getAccountId());
|
volume.setAccountId(newAccount.getAccountId());
|
||||||
volume.setDomainId(newAccount.getDomainId());
|
volume.setDomainId(newAccount.getDomainId());
|
||||||
_volsDao.persist(volume);
|
_volsDao.persist(volume);
|
||||||
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
|
_resourceLimitMgr.incrementVolumeResourceCount(newAccount.getAccountId(), volume.isDisplay(), volume.getSize(), diskOfferingVO);
|
||||||
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
|
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||||
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),
|
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),
|
||||||
volume.getUuid(), volume.isDisplayVolume());
|
volume.getUuid(), volume.isDisplayVolume());
|
||||||
}
|
}
|
||||||
|
|
||||||
//update resource count of new account
|
//update resource count of new account
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
resourceCountIncrement(newAccount.getAccountId(), vm.isDisplayVm(), offering, template);
|
||||||
resourceCountIncrement(newAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//generate usage events to account for this change
|
//generate usage events to account for this change
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
|
||||||
@ -7882,8 +7930,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
// 1. Save usage event and update resource count for user vm volumes
|
// 1. Save usage event and update resource count for user vm volumes
|
||||||
try {
|
try {
|
||||||
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.volume, newVol.isDisplay());
|
_resourceLimitMgr.incrementVolumeResourceCount(newVol.getAccountId(), newVol.isDisplay(), newVol.getSize(), _diskOfferingDao.findById(newVol.getDiskOfferingId()));
|
||||||
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.primary_storage, newVol.isDisplay(), new Long(newVol.getSize()));
|
|
||||||
} catch (final CloudRuntimeException e) {
|
} catch (final CloudRuntimeException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
@ -8411,21 +8458,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
*/
|
*/
|
||||||
private void postProcessingUnmanageVM(UserVmVO vm) {
|
private void postProcessingUnmanageVM(UserVmVO vm) {
|
||||||
ServiceOfferingVO offering = serviceOfferingDao.findById(vm.getServiceOfferingId());
|
ServiceOfferingVO offering = serviceOfferingDao.findById(vm.getServiceOfferingId());
|
||||||
Long cpu = offering.getCpu() != null ? new Long(offering.getCpu()) : 0L;
|
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||||
Long ram = offering.getRamSize() != null ? new Long(offering.getRamSize()) : 0L;
|
|
||||||
// First generate a VM stop event if the VM was not stopped already
|
// First generate a VM stop event if the VM was not stopped already
|
||||||
|
boolean resourceNotDecremented = true;
|
||||||
if (vm.getState() != State.Stopped) {
|
if (vm.getState() != State.Stopped) {
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_STOP, vm.getAccountId(), vm.getDataCenterId(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_STOP, vm.getAccountId(), vm.getDataCenterId(),
|
||||||
vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
|
vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
|
||||||
vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
|
vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
|
||||||
resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), cpu, ram);
|
resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), offering, template);
|
||||||
|
resourceNotDecremented = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VM destroy usage event
|
// VM destroy usage event
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(),
|
||||||
vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
|
vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
|
||||||
vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
|
vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
|
||||||
resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), cpu, ram);
|
if (resourceNotDecremented) {
|
||||||
|
resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), offering, template);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8439,8 +8489,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||||
Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
|
Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
|
||||||
}
|
}
|
||||||
_resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.volume);
|
_resourceLimitMgr.decrementVolumeResourceCount(vm.getAccountId(), volume.isDisplayVolume(),
|
||||||
_resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
|
volume.getSize(), _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8524,7 +8574,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
return DestroyRootVolumeOnVmDestruction.valueIn(domainId);
|
return DestroyRootVolumeOnVmDestruction.valueIn(domainId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setVncPasswordForKvmIfAvailable(Map<String, String> customParameters, UserVmVO vm){
|
private void setVncPasswordForKvmIfAvailable(Map<String, String> customParameters, UserVmVO vm) {
|
||||||
if (customParameters.containsKey(VmDetailConstants.KVM_VNC_PASSWORD)
|
if (customParameters.containsKey(VmDetailConstants.KVM_VNC_PASSWORD)
|
||||||
&& StringUtils.isNotEmpty(customParameters.get(VmDetailConstants.KVM_VNC_PASSWORD))) {
|
&& StringUtils.isNotEmpty(customParameters.get(VmDetailConstants.KVM_VNC_PASSWORD))) {
|
||||||
vm.setVncPassword(customParameters.get(VmDetailConstants.KVM_VNC_PASSWORD));
|
vm.setVncPassword(customParameters.get(VmDetailConstants.KVM_VNC_PASSWORD));
|
||||||
|
|||||||
@ -439,9 +439,12 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
return managedVms;
|
return managedVms;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hostSupportsServiceOffering(HostVO host, ServiceOffering serviceOffering) {
|
private boolean hostSupportsServiceOfferingAndTemplate(HostVO host, ServiceOffering serviceOffering, VirtualMachineTemplate template) {
|
||||||
|
if (StringUtils.isAllEmpty(serviceOffering.getHostTag(), template.getTemplateTag())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
hostDao.loadHostTags(host);
|
hostDao.loadHostTags(host);
|
||||||
return host.checkHostServiceOfferingTags(serviceOffering);
|
return host.checkHostServiceOfferingAndTemplateTags(serviceOffering, template);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean storagePoolSupportsDiskOffering(StoragePool pool, DiskOffering diskOffering) {
|
private boolean storagePoolSupportsDiskOffering(StoragePool pool, DiskOffering diskOffering) {
|
||||||
@ -502,8 +505,6 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Service offering (%s) %dMHz CPU speed does not match VM CPU speed %dMHz and VM is not in powered off state (Power state: %s)", serviceOffering.getUuid(), serviceOffering.getSpeed(), cpuSpeed, instance.getPowerState()));
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Service offering (%s) %dMHz CPU speed does not match VM CPU speed %dMHz and VM is not in powered off state (Power state: %s)", serviceOffering.getUuid(), serviceOffering.getSpeed(), cpuSpeed, instance.getPowerState()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resourceLimitService.checkResourceLimit(owner, Resource.ResourceType.cpu, Long.valueOf(serviceOffering.getCpu()));
|
|
||||||
resourceLimitService.checkResourceLimit(owner, Resource.ResourceType.memory, Long.valueOf(serviceOffering.getRamSize()));
|
|
||||||
return serviceOffering;
|
return serviceOffering;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,7 +606,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
if (diskOffering != null) {
|
if (diskOffering != null) {
|
||||||
accountService.checkAccess(owner, diskOffering, zone);
|
accountService.checkAccess(owner, diskOffering, zone);
|
||||||
}
|
}
|
||||||
resourceLimitService.checkResourceLimit(owner, Resource.ResourceType.volume);
|
resourceLimitService.checkVolumeResourceLimit(owner, true, null, diskOffering);
|
||||||
if (disk.getCapacity() == null || disk.getCapacity() == 0) {
|
if (disk.getCapacity() == null || disk.getCapacity() == 0) {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Size of disk(ID: %s) is found invalid during VM import", disk.getDiskId()));
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Size of disk(ID: %s) is found invalid during VM import", disk.getDiskId()));
|
||||||
}
|
}
|
||||||
@ -893,7 +894,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
cleanupFailedImportVM(vm);
|
cleanupFailedImportVM(vm);
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to check migrations need during import, VM: %s", userVm.getInstanceName()));
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to check migrations need during import, VM: %s", userVm.getInstanceName()));
|
||||||
}
|
}
|
||||||
if (!hostSupportsServiceOffering(sourceHost, serviceOffering)) {
|
if (!hostSupportsServiceOfferingAndTemplate(sourceHost, serviceOffering, template)) {
|
||||||
logger.debug(String.format("VM %s needs to be migrated", vm.getUuid()));
|
logger.debug(String.format("VM %s needs to be migrated", vm.getUuid()));
|
||||||
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, template, serviceOffering, owner, null);
|
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, template, serviceOffering, owner, null);
|
||||||
DeploymentPlanner.ExcludeList excludeList = new DeploymentPlanner.ExcludeList();
|
DeploymentPlanner.ExcludeList excludeList = new DeploymentPlanner.ExcludeList();
|
||||||
@ -1010,7 +1011,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
return userVm;
|
return userVm;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void publishVMUsageUpdateResourceCount(final UserVm userVm, ServiceOfferingVO serviceOfferingVO) {
|
private void publishVMUsageUpdateResourceCount(final UserVm userVm, ServiceOfferingVO serviceOfferingVO, VirtualMachineTemplate templateVO) {
|
||||||
if (userVm == null || serviceOfferingVO == null) {
|
if (userVm == null || serviceOfferingVO == null) {
|
||||||
logger.error(String.format("Failed to publish usage records during VM import because VM [%s] or ServiceOffering [%s] is null.", userVm, serviceOfferingVO));
|
logger.error(String.format("Failed to publish usage records during VM import because VM [%s] or ServiceOffering [%s] is null.", userVm, serviceOfferingVO));
|
||||||
cleanupFailedImportVM(userVm);
|
cleanupFailedImportVM(userVm);
|
||||||
@ -1033,9 +1034,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
cleanupFailedImportVM(userVm);
|
cleanupFailedImportVM(userVm);
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM import failed for unmanaged vm %s during publishing usage records", userVm.getInstanceName()));
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM import failed for unmanaged vm %s during publishing usage records", userVm.getInstanceName()));
|
||||||
}
|
}
|
||||||
resourceLimitService.incrementResourceCount(userVm.getAccountId(), Resource.ResourceType.user_vm, userVm.isDisplayVm());
|
resourceLimitService.incrementVmResourceCount(userVm.getAccountId(), userVm.isDisplayVm(), serviceOfferingVO, templateVO);
|
||||||
resourceLimitService.incrementResourceCount(userVm.getAccountId(), Resource.ResourceType.cpu, userVm.isDisplayVm(), Long.valueOf(serviceOfferingVO.getCpu()));
|
|
||||||
resourceLimitService.incrementResourceCount(userVm.getAccountId(), Resource.ResourceType.memory, userVm.isDisplayVm(), Long.valueOf(serviceOfferingVO.getRamSize()));
|
|
||||||
// Save usage event and update resource count for user vm volumes
|
// Save usage event and update resource count for user vm volumes
|
||||||
List<VolumeVO> volumes = volumeDao.findByInstance(userVm.getId());
|
List<VolumeVO> volumes = volumeDao.findByInstance(userVm.getId());
|
||||||
for (VolumeVO volume : volumes) {
|
for (VolumeVO volume : volumes) {
|
||||||
@ -1045,8 +1044,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(String.format("Failed to publish volume ID: %s usage records during VM import", volume.getUuid()), e);
|
logger.error(String.format("Failed to publish volume ID: %s usage records during VM import", volume.getUuid()), e);
|
||||||
}
|
}
|
||||||
resourceLimitService.incrementResourceCount(userVm.getAccountId(), Resource.ResourceType.volume, volume.isDisplayVolume());
|
resourceLimitService.incrementVolumeResourceCount(userVm.getAccountId(), volume.isDisplayVolume(),
|
||||||
resourceLimitService.incrementResourceCount(userVm.getAccountId(), Resource.ResourceType.primary_storage, volume.isDisplayVolume(), volume.getSize());
|
volume.getSize(), diskOfferingDao.findById(volume.getDiskOfferingId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<NicVO> nics = nicDao.listByVmId(userVm.getId());
|
List<NicVO> nics = nicDao.listByVmId(userVm.getId());
|
||||||
@ -1061,6 +1060,40 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void checkUnmanagedDiskLimits(Account account, UnmanagedInstanceTO.Disk rootDisk, ServiceOffering serviceOffering,
|
||||||
|
List<UnmanagedInstanceTO.Disk> dataDisks, Map<String, Long> dataDiskOfferingMap) throws ResourceAllocationException {
|
||||||
|
Long totalVolumes = 0L;
|
||||||
|
Long totalVolumesSize = 0L;
|
||||||
|
List<UnmanagedInstanceTO.Disk> disks = new ArrayList<>();
|
||||||
|
disks.add(rootDisk);
|
||||||
|
disks.addAll(dataDisks);
|
||||||
|
Map<String, Long> diskOfferingMap = new HashMap<>(dataDiskOfferingMap);
|
||||||
|
diskOfferingMap.put(rootDisk.getDiskId(), serviceOffering.getDiskOfferingId());
|
||||||
|
Map<Long, Long> diskOfferingVolumeCountMap = new HashMap<>();
|
||||||
|
Map<Long, Long> diskOfferingSizeMap = new HashMap<>();
|
||||||
|
for (UnmanagedInstanceTO.Disk disk : disks) {
|
||||||
|
totalVolumes++;
|
||||||
|
totalVolumesSize += disk.getCapacity();
|
||||||
|
Long diskOfferingId = diskOfferingMap.get(disk.getDiskId());
|
||||||
|
if (diskOfferingVolumeCountMap.containsKey(diskOfferingId)) {
|
||||||
|
diskOfferingVolumeCountMap.put(diskOfferingId, diskOfferingVolumeCountMap.get(diskOfferingId) + 1);
|
||||||
|
diskOfferingSizeMap.put(diskOfferingId, diskOfferingSizeMap.get(diskOfferingId) + disk.getCapacity());
|
||||||
|
} else {
|
||||||
|
diskOfferingVolumeCountMap.put(diskOfferingId, 1L);
|
||||||
|
diskOfferingSizeMap.put(diskOfferingId, disk.getCapacity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resourceLimitService.checkResourceLimit(account, Resource.ResourceType.volume, totalVolumes);
|
||||||
|
resourceLimitService.checkResourceLimit(account, Resource.ResourceType.primary_storage, totalVolumesSize);
|
||||||
|
for (Long diskOfferingId : diskOfferingVolumeCountMap.keySet()) {
|
||||||
|
List<String> tags = resourceLimitService.getResourceLimitStorageTags(diskOfferingDao.findById(diskOfferingId));
|
||||||
|
for (String tag : tags) {
|
||||||
|
resourceLimitService.checkResourceLimitWithTag(account, Resource.ResourceType.volume, tag, diskOfferingVolumeCountMap.get(diskOfferingId));
|
||||||
|
resourceLimitService.checkResourceLimitWithTag(account, Resource.ResourceType.primary_storage, tag, diskOfferingSizeMap.get(diskOfferingId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private UserVm importVirtualMachineInternal(final UnmanagedInstanceTO unmanagedInstance, final String instanceName, final DataCenter zone, final Cluster cluster, final HostVO host,
|
private UserVm importVirtualMachineInternal(final UnmanagedInstanceTO unmanagedInstance, final String instanceName, final DataCenter zone, final Cluster cluster, final HostVO host,
|
||||||
final VirtualMachineTemplate template, final String displayName, final String hostName, final Account caller, final Account owner, final Long userId,
|
final VirtualMachineTemplate template, final String displayName, final String hostName, final Account caller, final Account owner, final Long userId,
|
||||||
final ServiceOfferingVO serviceOffering, final Map<String, Long> dataDiskOfferingMap,
|
final ServiceOfferingVO serviceOffering, final Map<String, Long> dataDiskOfferingMap,
|
||||||
@ -1091,8 +1124,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!migrateAllowed && host != null && !hostSupportsServiceOffering(host, validatedServiceOffering)) {
|
if (!migrateAllowed && host != null && !hostSupportsServiceOfferingAndTemplate(host, validatedServiceOffering, template)) {
|
||||||
throw new InvalidParameterValueException(String.format("Service offering: %s is not compatible with host: %s of unmanaged VM: %s", serviceOffering.getUuid(), host.getUuid(), instanceName));
|
throw new InvalidParameterValueException(String.format("Service offering: %s or template: %s is not compatible with host: %s of unmanaged VM: %s", serviceOffering.getUuid(), template.getUuid(), host.getUuid(), instanceName));
|
||||||
}
|
}
|
||||||
// Check disks and supplied disk offerings
|
// Check disks and supplied disk offerings
|
||||||
List<UnmanagedInstanceTO.Disk> unmanagedInstanceDisks = unmanagedInstance.getDisks();
|
List<UnmanagedInstanceTO.Disk> unmanagedInstanceDisks = unmanagedInstance.getDisks();
|
||||||
@ -1124,7 +1157,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
checkUnmanagedDiskAndOfferingForImport(unmanagedInstance.getName(), dataDisks, dataDiskOfferingMap, owner, zone, cluster, migrateAllowed);
|
checkUnmanagedDiskAndOfferingForImport(unmanagedInstance.getName(), dataDisks, dataDiskOfferingMap, owner, zone, cluster, migrateAllowed);
|
||||||
allDetails.put(VmDetailConstants.DATA_DISK_CONTROLLER, dataDisks.get(0).getController());
|
allDetails.put(VmDetailConstants.DATA_DISK_CONTROLLER, dataDisks.get(0).getController());
|
||||||
}
|
}
|
||||||
resourceLimitService.checkResourceLimit(owner, Resource.ResourceType.volume, unmanagedInstanceDisks.size());
|
checkUnmanagedDiskLimits(owner, rootDisk, serviceOffering, dataDisks, dataDiskOfferingMap);
|
||||||
} catch (ResourceAllocationException e) {
|
} catch (ResourceAllocationException e) {
|
||||||
logger.error(String.format("Volume resource allocation error for owner: %s", owner.getUuid()), e);
|
logger.error(String.format("Volume resource allocation error for owner: %s", owner.getUuid()), e);
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume resource allocation error for owner: %s. %s", owner.getUuid(), StringUtils.defaultString(e.getMessage())));
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume resource allocation error for owner: %s. %s", owner.getUuid(), StringUtils.defaultString(e.getMessage())));
|
||||||
@ -1207,7 +1240,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
if (migrateAllowed) {
|
if (migrateAllowed) {
|
||||||
userVm = migrateImportedVM(host, template, validatedServiceOffering, userVm, owner, diskProfileStoragePoolList);
|
userVm = migrateImportedVM(host, template, validatedServiceOffering, userVm, owner, diskProfileStoragePoolList);
|
||||||
}
|
}
|
||||||
publishVMUsageUpdateResourceCount(userVm, validatedServiceOffering);
|
publishVMUsageUpdateResourceCount(userVm, validatedServiceOffering, template);
|
||||||
return userVm;
|
return userVm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1309,7 +1342,6 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
String hostName = getHostNameForImportInstance(cmd.getHostName(), cluster.getHypervisorType(), instanceName, displayName);
|
String hostName = getHostNameForImportInstance(cmd.getHostName(), cluster.getHypervisorType(), instanceName, displayName);
|
||||||
|
|
||||||
checkVmwareInstanceNameForImportInstance(cluster.getHypervisorType(), instanceName, hostName, zone);
|
checkVmwareInstanceNameForImportInstance(cluster.getHypervisorType(), instanceName, hostName, zone);
|
||||||
|
|
||||||
final Map<String, Long> nicNetworkMap = cmd.getNicNetworkList();
|
final Map<String, Long> nicNetworkMap = cmd.getNicNetworkList();
|
||||||
final Map<String, Network.IpAddresses> nicIpAddressMap = cmd.getNicIpAddressList();
|
final Map<String, Network.IpAddresses> nicIpAddressMap = cmd.getNicIpAddressList();
|
||||||
final Map<String, Long> dataDiskOfferingMap = cmd.getDataDiskToDiskOfferingList();
|
final Map<String, Long> dataDiskOfferingMap = cmd.getDataDiskToDiskOfferingList();
|
||||||
@ -2240,7 +2272,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
cleanupFailedImportVM(userVm);
|
cleanupFailedImportVM(userVm);
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import NICs while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import NICs while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
|
||||||
}
|
}
|
||||||
publishVMUsageUpdateResourceCount(userVm, serviceOffering);
|
publishVMUsageUpdateResourceCount(userVm, serviceOffering, template);
|
||||||
return userVm;
|
return userVm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2373,8 +2405,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
cleanupFailedImportVM(userVm);
|
cleanupFailedImportVM(userVm);
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import volumes while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import volumes while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
|
||||||
}
|
}
|
||||||
networkOrchestrationService.importNic(macAddress,0,network, true, userVm, requestedIpPair, zone, true);
|
networkOrchestrationService.importNic(macAddress, 0, network, true, userVm, requestedIpPair, zone, true);
|
||||||
publishVMUsageUpdateResourceCount(userVm, serviceOffering);
|
publishVMUsageUpdateResourceCount(userVm, serviceOffering, template);
|
||||||
return userVm;
|
return userVm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.api;
|
package com.cloud.api;
|
||||||
|
|
||||||
|
import com.cloud.capacity.Capacity;
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
import com.cloud.domain.DomainVO;
|
import com.cloud.domain.DomainVO;
|
||||||
import com.cloud.network.PublicIpQuarantine;
|
import com.cloud.network.PublicIpQuarantine;
|
||||||
import com.cloud.network.as.AutoScaleVmGroup;
|
import com.cloud.network.as.AutoScaleVmGroup;
|
||||||
@ -452,4 +454,31 @@ public class ApiResponseHelperTest {
|
|||||||
Assert.assertEquals(removerAccountUuid, result.getRemoverAccountId());
|
Assert.assertEquals(removerAccountUuid, result.getRemoverAccountId());
|
||||||
Assert.assertEquals("quarantinedip", result.getResponseName());
|
Assert.assertEquals("quarantinedip", result.getResponseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCapacityListingForSingleTag() {
|
||||||
|
Capacity c1 = Mockito.mock(Capacity.class);
|
||||||
|
Mockito.when(c1.getTag()).thenReturn("tag1");
|
||||||
|
Capacity c2 = Mockito.mock(Capacity.class);
|
||||||
|
Mockito.when(c2.getTag()).thenReturn("tag1");
|
||||||
|
Capacity c3 = Mockito.mock(Capacity.class);
|
||||||
|
Mockito.when(c3.getTag()).thenReturn("tag2");
|
||||||
|
Capacity c4 = Mockito.mock(Capacity.class);
|
||||||
|
Assert.assertTrue(apiResponseHelper.capacityListingForSingleTag(List.of(c1, c2)));
|
||||||
|
Assert.assertFalse(apiResponseHelper.capacityListingForSingleTag(List.of(c1, c2, c3)));
|
||||||
|
Assert.assertFalse(apiResponseHelper.capacityListingForSingleTag(List.of(c4, c2, c3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCapacityListingForSingleNonGpuType() {
|
||||||
|
Capacity c1 = Mockito.mock(Capacity.class);
|
||||||
|
Mockito.when(c1.getCapacityType()).thenReturn((short)Resource.ResourceType.user_vm.getOrdinal());
|
||||||
|
Capacity c2 = Mockito.mock(Capacity.class);
|
||||||
|
Mockito.when(c2.getCapacityType()).thenReturn((short)Resource.ResourceType.user_vm.getOrdinal());
|
||||||
|
Capacity c3 = Mockito.mock(Capacity.class);
|
||||||
|
Mockito.when(c3.getCapacityType()).thenReturn((short)Resource.ResourceType.volume.getOrdinal());
|
||||||
|
Capacity c4 = Mockito.mock(Capacity.class);
|
||||||
|
Assert.assertTrue(apiResponseHelper.capacityListingForSingleNonGpuType(List.of(c1, c2)));
|
||||||
|
Assert.assertFalse(apiResponseHelper.capacityListingForSingleNonGpuType(List.of(c1, c2, c3)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,9 @@ import com.cloud.network.VNF;
|
|||||||
import com.cloud.network.dao.NetworkVO;
|
import com.cloud.network.dao.NetworkVO;
|
||||||
import com.cloud.server.ResourceTag;
|
import com.cloud.server.ResourceTag;
|
||||||
import com.cloud.storage.BucketVO;
|
import com.cloud.storage.BucketVO;
|
||||||
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.dao.BucketDao;
|
import com.cloud.storage.dao.BucketDao;
|
||||||
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
import com.cloud.user.AccountVO;
|
import com.cloud.user.AccountVO;
|
||||||
@ -53,6 +55,7 @@ import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
|||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -109,6 +112,8 @@ public class QueryManagerImplTest {
|
|||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
BucketDao bucketDao;
|
BucketDao bucketDao;
|
||||||
|
@Mock
|
||||||
|
VMTemplateDao templateDao;
|
||||||
|
|
||||||
private AccountVO account;
|
private AccountVO account;
|
||||||
private UserVO user;
|
private UserVO user;
|
||||||
@ -340,4 +345,53 @@ public class QueryManagerImplTest {
|
|||||||
when(bucketDao.searchAndCount(any(), any())).thenReturn(new Pair<>(buckets, 2));
|
when(bucketDao.searchAndCount(any(), any())).thenReturn(new Pair<>(buckets, 2));
|
||||||
queryManagerImplSpy.searchForBuckets(listBucketsCmd);
|
queryManagerImplSpy.searchForBuckets(listBucketsCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetHostTagsFromTemplateForServiceOfferingsListingNoTemplateId() {
|
||||||
|
CollectionUtils.isEmpty(queryManager.getHostTagsFromTemplateForServiceOfferingsListing(Mockito.mock(AccountVO.class), null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testGetHostTagsFromTemplateForServiceOfferingsListingException() {
|
||||||
|
queryManager.getHostTagsFromTemplateForServiceOfferingsListing(Mockito.mock(AccountVO.class), 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = PermissionDeniedException.class)
|
||||||
|
public void testGetHostTagsForServiceOfferingsListingNoAccess() {
|
||||||
|
long templateId = 1L;
|
||||||
|
Account account = Mockito.mock(Account.class);
|
||||||
|
Mockito.when(account.getType()).thenReturn(Account.Type.NORMAL);
|
||||||
|
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
|
||||||
|
Mockito.when(templateDao.findByIdIncludingRemoved(templateId)).thenReturn(template);
|
||||||
|
Mockito.lenient().doThrow(PermissionDeniedException.class).when(accountManager).checkAccess(account, null, false, template);
|
||||||
|
queryManager.getHostTagsFromTemplateForServiceOfferingsListing(account, templateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetHostTagsFromTemplateForServiceOfferingsListingAdmin() {
|
||||||
|
long templateId = 1L;
|
||||||
|
Account account = Mockito.mock(Account.class);
|
||||||
|
Mockito.when(account.getType()).thenReturn(Account.Type.ADMIN);
|
||||||
|
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
|
||||||
|
Mockito.when(template.getTemplateTag()).thenReturn("tag");
|
||||||
|
Mockito.when(templateDao.findByIdIncludingRemoved(templateId)).thenReturn(template);
|
||||||
|
Mockito.lenient().doThrow(PermissionDeniedException.class).when(accountManager).checkAccess(account, null, false, template);
|
||||||
|
List<String> result = queryManager.getHostTagsFromTemplateForServiceOfferingsListing(account, templateId);
|
||||||
|
Assert.assertTrue(CollectionUtils.isNotEmpty(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetHostTagsForServiceOfferingsListingSuccess() {
|
||||||
|
long templateId = 1L;
|
||||||
|
Account account = Mockito.mock(Account.class);
|
||||||
|
Mockito.when(account.getType()).thenReturn(Account.Type.NORMAL);
|
||||||
|
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
|
||||||
|
Mockito.when(templateDao.findByIdIncludingRemoved(templateId)).thenReturn(template);
|
||||||
|
Mockito.lenient().doNothing().when(accountManager).checkAccess(account, null, false, template);
|
||||||
|
List<String> result = queryManager.getHostTagsFromTemplateForServiceOfferingsListing(account, templateId);
|
||||||
|
Assert.assertTrue(CollectionUtils.isEmpty(result));
|
||||||
|
Mockito.when(template.getTemplateTag()).thenReturn("tag");
|
||||||
|
result = queryManager.getHostTagsFromTemplateForServiceOfferingsListing(account, templateId);
|
||||||
|
Assert.assertTrue(CollectionUtils.isNotEmpty(result));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,28 +18,37 @@
|
|||||||
//
|
//
|
||||||
package com.cloud.resourcelimit;
|
package com.cloud.resourcelimit;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.Mockito.lenient;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.cloudstack.reservation.ReservationVO;
|
||||||
|
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import com.cloud.configuration.Resource;
|
import com.cloud.configuration.Resource;
|
||||||
import com.cloud.exception.ResourceAllocationException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.ResourceLimitService;
|
import com.cloud.user.ResourceLimitService;
|
||||||
import com.cloud.utils.db.GlobalLock;
|
import com.cloud.utils.db.GlobalLock;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import org.apache.cloudstack.reservation.ReservationVO;
|
|
||||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
import static org.mockito.Mockito.lenient;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class CheckedReservationTest {
|
public class CheckedReservationTest {
|
||||||
@ -58,14 +67,19 @@ public class CheckedReservationTest {
|
|||||||
GlobalLock quotaLimitLock;
|
GlobalLock quotaLimitLock;
|
||||||
|
|
||||||
private AutoCloseable closeable;
|
private AutoCloseable closeable;
|
||||||
|
private MockedStatic<GlobalLock> globalLockMocked;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() throws Exception {
|
||||||
closeable = MockitoAnnotations.openMocks(this);
|
closeable = MockitoAnnotations.openMocks(this);
|
||||||
|
globalLockMocked = Mockito.mockStatic(GlobalLock.class);
|
||||||
|
Mockito.when(quotaLimitLock.lock(Mockito.anyInt())).thenReturn(true);
|
||||||
|
globalLockMocked.when(() -> GlobalLock.getInternLock(Mockito.anyString())).thenReturn(quotaLimitLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
|
globalLockMocked.close();
|
||||||
closeable.close();
|
closeable.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +90,9 @@ public class CheckedReservationTest {
|
|||||||
lenient().when(reservationDao.persist(Mockito.any())).thenReturn(reservation);
|
lenient().when(reservationDao.persist(Mockito.any())).thenReturn(reservation);
|
||||||
lenient().when(reservation.getId()).thenReturn(1L);
|
lenient().when(reservation.getId()).thenReturn(1L);
|
||||||
try (CheckedReservation cr = new CheckedReservation(account, Resource.ResourceType.user_vm,1l, reservationDao, resourceLimitService) ) {
|
try (CheckedReservation cr = new CheckedReservation(account, Resource.ResourceType.user_vm,1l, reservationDao, resourceLimitService) ) {
|
||||||
long id = cr.getId();
|
List<Long> ids = cr.getIds();
|
||||||
|
assertEquals(1, cr.getIds().size());
|
||||||
|
long id = ids.get(0);
|
||||||
assertEquals(1L, id);
|
assertEquals(1L, id);
|
||||||
} catch (NullPointerException npe) {
|
} catch (NullPointerException npe) {
|
||||||
fail("NPE caught");
|
fail("NPE caught");
|
||||||
@ -103,4 +119,28 @@ public class CheckedReservationTest {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReservationPersistAndCallContextParam() {
|
||||||
|
List<String> tags = List.of("abc", "xyz");
|
||||||
|
when(account.getAccountId()).thenReturn(1L);
|
||||||
|
when(account.getDomainId()).thenReturn(4L);
|
||||||
|
List<ReservationVO> persistedReservations = new ArrayList<>();
|
||||||
|
Mockito.when(reservationDao.persist(Mockito.any(ReservationVO.class))).thenAnswer((Answer<ReservationVO>) invocation -> {
|
||||||
|
ReservationVO reservationVO = (ReservationVO) invocation.getArguments()[0];
|
||||||
|
ReflectionTestUtils.setField(reservationVO, "id", (long) (persistedReservations.size() + 1));
|
||||||
|
persistedReservations.add(reservationVO);
|
||||||
|
return reservationVO;
|
||||||
|
});
|
||||||
|
Resource.ResourceType type = Resource.ResourceType.cpu;
|
||||||
|
try (CheckedReservation cr = new CheckedReservation(account, type, tags, 2L, reservationDao, resourceLimitService);) {
|
||||||
|
Assert.assertEquals(tags.size() + 1, persistedReservations.size()); // An extra for no tag
|
||||||
|
Object obj = CallContext.current().getContextParameter(CheckedReservation.getResourceReservationContextParameterKey(type));
|
||||||
|
Assert.assertTrue(obj instanceof List);
|
||||||
|
List<Long> list = (List<Long>) obj;
|
||||||
|
Assert.assertEquals(tags.size() + 1, list.size()); // An extra for no tag
|
||||||
|
} catch (Exception e) {
|
||||||
|
Assert.fail("Exception faced: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -16,13 +16,15 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.storage;
|
package com.cloud.storage;
|
||||||
|
|
||||||
import com.cloud.agent.api.StoragePoolInfo;
|
import java.util.ArrayList;
|
||||||
import com.cloud.exception.ConnectionException;
|
import java.util.Arrays;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import java.util.HashMap;
|
||||||
import com.cloud.host.Host;
|
import java.util.List;
|
||||||
import com.cloud.storage.dao.VolumeDao;
|
import java.util.Map;
|
||||||
import com.cloud.vm.VMInstanceVO;
|
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
||||||
|
import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
import org.apache.commons.collections.MapUtils;
|
import org.apache.commons.collections.MapUtils;
|
||||||
@ -34,11 +36,26 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.cloud.agent.AgentManager;
|
||||||
import java.util.HashMap;
|
import com.cloud.agent.api.Command;
|
||||||
import java.util.List;
|
import com.cloud.agent.api.StoragePoolInfo;
|
||||||
import java.util.Map;
|
import com.cloud.capacity.CapacityManager;
|
||||||
|
import com.cloud.dc.VsphereStoragePolicyVO;
|
||||||
|
import com.cloud.dc.dao.VsphereStoragePolicyDao;
|
||||||
|
import com.cloud.exception.AgentUnavailableException;
|
||||||
|
import com.cloud.exception.ConnectionException;
|
||||||
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
import com.cloud.exception.OperationTimedoutException;
|
||||||
|
import com.cloud.exception.StorageUnavailableException;
|
||||||
|
import com.cloud.host.Host;
|
||||||
|
import com.cloud.hypervisor.HypervisorGuruManager;
|
||||||
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
|
import com.cloud.vm.DiskProfile;
|
||||||
|
import com.cloud.vm.VMInstanceVO;
|
||||||
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class StorageManagerImplTest {
|
public class StorageManagerImplTest {
|
||||||
@ -48,6 +65,18 @@ public class StorageManagerImplTest {
|
|||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
VMInstanceDao vmInstanceDao;
|
VMInstanceDao vmInstanceDao;
|
||||||
|
@Mock
|
||||||
|
PrimaryDataStoreDao storagePoolDao;
|
||||||
|
@Mock
|
||||||
|
CapacityManager capacityManager;
|
||||||
|
@Mock
|
||||||
|
DiskOfferingDetailsDao diskOfferingDetailsDao;
|
||||||
|
@Mock
|
||||||
|
VsphereStoragePolicyDao vsphereStoragePolicyDao;
|
||||||
|
@Mock
|
||||||
|
HypervisorGuruManager hvGuruMgr;
|
||||||
|
@Mock
|
||||||
|
AgentManager agentManager;
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
@ -206,4 +235,224 @@ public class StorageManagerImplTest {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughIopsNullPoolIops() {
|
||||||
|
StoragePool pool = Mockito.mock(StoragePool.class);
|
||||||
|
Mockito.when(pool.getCapacityIops()).thenReturn(null);
|
||||||
|
List<Pair<Volume, DiskProfile>> list = List.of(new Pair<>(Mockito.mock(Volume.class), Mockito.mock(DiskProfile.class)));
|
||||||
|
Assert.assertTrue(storageManagerImpl.storagePoolHasEnoughIops(100L, list, pool, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughIopsSuccess() {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.when(pool.getId()).thenReturn(1L);
|
||||||
|
Mockito.when(pool.getCapacityIops()).thenReturn(1000L);
|
||||||
|
Mockito.when(storagePoolDao.findById(1L)).thenReturn(pool);
|
||||||
|
Mockito.when(capacityManager.getUsedIops(pool)).thenReturn(500L);
|
||||||
|
List<Pair<Volume, DiskProfile>> list = List.of(new Pair<>(Mockito.mock(Volume.class), Mockito.mock(DiskProfile.class)));
|
||||||
|
Assert.assertTrue(storageManagerImpl.storagePoolHasEnoughIops(100L, list, pool, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughIopsNegative() {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.when(pool.getId()).thenReturn(1L);
|
||||||
|
Mockito.when(pool.getCapacityIops()).thenReturn(550L);
|
||||||
|
Mockito.when(storagePoolDao.findById(1L)).thenReturn(pool);
|
||||||
|
Mockito.when(capacityManager.getUsedIops(pool)).thenReturn(500L);
|
||||||
|
List<Pair<Volume, DiskProfile>> list = List.of(new Pair<>(Mockito.mock(Volume.class), Mockito.mock(DiskProfile.class)));
|
||||||
|
Assert.assertFalse(storageManagerImpl.storagePoolHasEnoughIops(100L, list, pool, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughIopsNullPool() {
|
||||||
|
Assert.assertFalse(storageManagerImpl.storagePoolHasEnoughIops(100L, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughIopsNullRequestedIops() {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
List<Long> iopsList = Arrays.asList(null, 0L);
|
||||||
|
for (Long iops : iopsList) {
|
||||||
|
Assert.assertTrue(storageManagerImpl.storagePoolHasEnoughIops(iops, pool));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughIopsSuccess1() {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.doReturn(true).when(storageManagerImpl).storagePoolHasEnoughIops(
|
||||||
|
Mockito.eq(100L), Mockito.anyList(), Mockito.eq(pool), Mockito.eq(false));
|
||||||
|
Assert.assertTrue(storageManagerImpl.storagePoolHasEnoughIops(100L, pool));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughIopsNoVolumesOrPool() {
|
||||||
|
List<Pair<Volume, DiskProfile>> list = new ArrayList<>();
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Assert.assertFalse(storageManagerImpl.storagePoolHasEnoughIops(list, pool));
|
||||||
|
list = List.of(new Pair<>(Mockito.mock(Volume.class), Mockito.mock(DiskProfile.class)));
|
||||||
|
Assert.assertFalse(storageManagerImpl.storagePoolHasEnoughIops(list, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughIopsWithVolPoolNullIops() {
|
||||||
|
List<Pair<Volume, DiskProfile>> list = List.of(
|
||||||
|
new Pair<>(Mockito.mock(Volume.class), Mockito.mock(DiskProfile.class)));
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.when(pool.getCapacityIops()).thenReturn(null);
|
||||||
|
Assert.assertTrue(storageManagerImpl.storagePoolHasEnoughIops(list, pool));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughIopsWithVolPoolCompare() {
|
||||||
|
Volume volume = Mockito.mock(Volume.class);
|
||||||
|
Mockito.when(volume.getDiskOfferingId()).thenReturn(1L);
|
||||||
|
Mockito.when(volume.getMinIops()).thenReturn(100L);
|
||||||
|
DiskProfile profile = Mockito.mock(DiskProfile.class);
|
||||||
|
Mockito.when(profile.getDiskOfferingId()).thenReturn(1L);
|
||||||
|
List<Pair<Volume, DiskProfile>> list = List.of(new Pair<>(volume, profile));
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.doReturn(true).when(storageManagerImpl)
|
||||||
|
.storagePoolHasEnoughIops(100L, list, pool, true);
|
||||||
|
Assert.assertTrue(storageManagerImpl.storagePoolHasEnoughIops(list, pool));
|
||||||
|
|
||||||
|
Mockito.when(profile.getDiskOfferingId()).thenReturn(2L);
|
||||||
|
Mockito.when(profile.getMinIops()).thenReturn(200L);
|
||||||
|
Mockito.doReturn(false).when(storageManagerImpl)
|
||||||
|
.storagePoolHasEnoughIops(200L, list, pool, true);
|
||||||
|
Assert.assertFalse(storageManagerImpl.storagePoolHasEnoughIops(list, pool));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughSpaceNullSize() {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
List<Long> sizeList = Arrays.asList(null, 0L);
|
||||||
|
for (Long size : sizeList) {
|
||||||
|
Assert.assertTrue(storageManagerImpl.storagePoolHasEnoughSpace(size, pool));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoragePoolHasEnoughSpaceCompare() {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.when(pool.getId()).thenReturn(1L);
|
||||||
|
Mockito.when(storagePoolDao.findById(1L)).thenReturn(pool);
|
||||||
|
Mockito.when(capacityManager.getAllocatedPoolCapacity(pool, null)).thenReturn(2000L);
|
||||||
|
Mockito.doAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||||
|
long total = invocationOnMock.getArgument(1);
|
||||||
|
long asking = invocationOnMock.getArgument(2);
|
||||||
|
return total > asking;
|
||||||
|
}).when(storageManagerImpl).checkPoolforSpace(Mockito.any(StoragePool.class),
|
||||||
|
Mockito.anyLong(), Mockito.anyLong());
|
||||||
|
Assert.assertTrue(storageManagerImpl.storagePoolHasEnoughSpace(1000L, pool));
|
||||||
|
Assert.assertFalse(storageManagerImpl.storagePoolHasEnoughSpace(2200L, pool));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsStoragePoolCompliantWithStoragePolicy() {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.when(diskOfferingDetailsDao.getDetail(1L, ApiConstants.STORAGE_POLICY))
|
||||||
|
.thenReturn("policy");
|
||||||
|
try {
|
||||||
|
Mockito.doReturn(null)
|
||||||
|
.when(storageManagerImpl).getCheckDatastorePolicyComplianceAnswer("policy", pool);
|
||||||
|
Assert.assertTrue(storageManagerImpl.isStoragePoolCompliantWithStoragePolicy(1L, pool));
|
||||||
|
} catch (StorageUnavailableException e) {
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Mockito.doReturn(new com.cloud.agent.api.Answer(
|
||||||
|
Mockito.mock(CheckDataStoreStoragePolicyComplainceCommand.class)))
|
||||||
|
.when(storageManagerImpl).getCheckDatastorePolicyComplianceAnswer("policy", pool);
|
||||||
|
Assert.assertTrue(storageManagerImpl.isStoragePoolCompliantWithStoragePolicy(1L, pool));
|
||||||
|
} catch (StorageUnavailableException e) {
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
com.cloud.agent.api.Answer answer =
|
||||||
|
new com.cloud.agent.api.Answer(Mockito.mock(CheckDataStoreStoragePolicyComplainceCommand.class),
|
||||||
|
false, "");
|
||||||
|
Mockito.doReturn(answer)
|
||||||
|
.when(storageManagerImpl).getCheckDatastorePolicyComplianceAnswer("policy", pool);
|
||||||
|
Assert.assertFalse(storageManagerImpl.isStoragePoolCompliantWithStoragePolicy(1L, pool));
|
||||||
|
} catch (StorageUnavailableException e) {
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetCheckDatastorePolicyComplianceAnswerNullAnswer() {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
try {
|
||||||
|
Assert.assertNull(storageManagerImpl.getCheckDatastorePolicyComplianceAnswer(null, pool));
|
||||||
|
Assert.assertNull(storageManagerImpl.getCheckDatastorePolicyComplianceAnswer("", pool));
|
||||||
|
} catch (StorageUnavailableException e) {
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = StorageUnavailableException.class)
|
||||||
|
public void testGetCheckDatastorePolicyComplianceAnswerNoHost() throws StorageUnavailableException {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.when(pool.getId()).thenReturn(1L);
|
||||||
|
Mockito.when(vsphereStoragePolicyDao.findById(Mockito.anyLong()))
|
||||||
|
.thenReturn(Mockito.mock(VsphereStoragePolicyVO.class));
|
||||||
|
Mockito.doReturn(new ArrayList<>()).when(storageManagerImpl).getUpHostsInPool(Mockito.anyLong());
|
||||||
|
storageManagerImpl.getCheckDatastorePolicyComplianceAnswer("1", pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = StorageUnavailableException.class)
|
||||||
|
public void testGetCheckDatastorePolicyComplianceAnswerAgentException() throws StorageUnavailableException {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.when(pool.getId()).thenReturn(1L);
|
||||||
|
VsphereStoragePolicyVO policy = Mockito.mock(VsphereStoragePolicyVO.class);
|
||||||
|
Mockito.when(policy.getPolicyId()).thenReturn("some");
|
||||||
|
Mockito.when(vsphereStoragePolicyDao.findById(Mockito.anyLong()))
|
||||||
|
.thenReturn(policy);
|
||||||
|
Mockito.doReturn(new ArrayList<>(List.of(1L, 2L)))
|
||||||
|
.when(storageManagerImpl).getUpHostsInPool(Mockito.anyLong());
|
||||||
|
Mockito.when(hvGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(),
|
||||||
|
Mockito.any(CheckDataStoreStoragePolicyComplainceCommand.class))).thenReturn(1L);
|
||||||
|
try {
|
||||||
|
Mockito.when(agentManager.send(Mockito.anyLong(), Mockito.any(Command.class)))
|
||||||
|
.thenThrow(AgentUnavailableException.class);
|
||||||
|
} catch (AgentUnavailableException | OperationTimedoutException e) {
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
storageManagerImpl.getCheckDatastorePolicyComplianceAnswer("1", pool);
|
||||||
|
try {
|
||||||
|
Mockito.when(agentManager.send(Mockito.anyLong(), Mockito.any(Command.class)))
|
||||||
|
.thenThrow(OperationTimedoutException.class);
|
||||||
|
} catch (AgentUnavailableException | OperationTimedoutException e) {
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
storageManagerImpl.getCheckDatastorePolicyComplianceAnswer("1", pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetCheckDatastorePolicyComplianceAnswerSuccess() throws StorageUnavailableException {
|
||||||
|
StoragePoolVO pool = Mockito.mock(StoragePoolVO.class);
|
||||||
|
Mockito.when(pool.getId()).thenReturn(1L);
|
||||||
|
VsphereStoragePolicyVO policy = Mockito.mock(VsphereStoragePolicyVO.class);
|
||||||
|
Mockito.when(policy.getPolicyId()).thenReturn("some");
|
||||||
|
Mockito.when(vsphereStoragePolicyDao.findById(Mockito.anyLong()))
|
||||||
|
.thenReturn(policy);
|
||||||
|
Mockito.doReturn(new ArrayList<>(List.of(1L, 2L))).when(storageManagerImpl).getUpHostsInPool(Mockito.anyLong());
|
||||||
|
Mockito.when(hvGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(),
|
||||||
|
Mockito.any(CheckDataStoreStoragePolicyComplainceCommand.class))).thenReturn(1L);
|
||||||
|
try {
|
||||||
|
Mockito.when(agentManager.send(Mockito.anyLong(),
|
||||||
|
Mockito.any(CheckDataStoreStoragePolicyComplainceCommand.class)))
|
||||||
|
.thenReturn(new com.cloud.agent.api.Answer(
|
||||||
|
Mockito.mock(CheckDataStoreStoragePolicyComplainceCommand.class)));
|
||||||
|
} catch (AgentUnavailableException | OperationTimedoutException e) {
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
com.cloud.agent.api.Answer answer =
|
||||||
|
storageManagerImpl.getCheckDatastorePolicyComplianceAnswer("1", pool);
|
||||||
|
Assert.assertTrue(answer.getResult());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -893,8 +893,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
|
|
||||||
private void verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState() {
|
private void verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState() {
|
||||||
Mockito.verify(volumeServiceMock, Mockito.times(0)).destroyVolume(volumeMockId);
|
Mockito.verify(volumeServiceMock, Mockito.times(0)).destroyVolume(volumeMockId);
|
||||||
Mockito.verify(resourceLimitServiceMock, Mockito.times(0)).decrementResourceCount(accountMockId, ResourceType.volume, true);
|
Mockito.verify(resourceLimitServiceMock, Mockito.times(0)).decrementVolumeResourceCount(accountMockId, true, volumeSizeMock, newDiskOfferingMock);
|
||||||
Mockito.verify(resourceLimitServiceMock, Mockito.times(0)).decrementResourceCount(accountMockId, ResourceType.primary_storage, true, volumeSizeMock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureMocksForTestDestroyVolumeWhenVolume() {
|
private void configureMocksForTestDestroyVolumeWhenVolume() {
|
||||||
@ -902,8 +901,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
Mockito.lenient().doReturn(true).when(volumeVoMock).isDisplayVolume();
|
Mockito.lenient().doReturn(true).when(volumeVoMock).isDisplayVolume();
|
||||||
|
|
||||||
Mockito.lenient().doNothing().when(volumeServiceMock).destroyVolume(volumeMockId);
|
Mockito.lenient().doNothing().when(volumeServiceMock).destroyVolume(volumeMockId);
|
||||||
Mockito.lenient().doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.volume, true);
|
Mockito.lenient().doNothing().when(resourceLimitServiceMock).decrementVolumeResourceCount(accountMockId, true, volumeSizeMock, newDiskOfferingMock);
|
||||||
Mockito.lenient().doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.primary_storage, true, volumeSizeMock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1449,22 +1447,21 @@ public class VolumeApiServiceImplTest {
|
|||||||
Account newAccountMock = new AccountVO(accountMockId + 1);
|
Account newAccountMock = new AccountVO(accountMockId + 1);
|
||||||
|
|
||||||
Mockito.doReturn(volumeVoMock).when(volumeDaoMock).persist(volumeVoMock);
|
Mockito.doReturn(volumeVoMock).when(volumeDaoMock).persist(volumeVoMock);
|
||||||
|
Mockito.when(_diskOfferingDao.findById(Mockito.anyLong())).thenReturn(newDiskOfferingMock);
|
||||||
|
|
||||||
volumeApiServiceImpl.updateVolumeAccount(accountMock, volumeVoMock, newAccountMock);
|
volumeApiServiceImpl.updateVolumeAccount(accountMock, volumeVoMock, newAccountMock);
|
||||||
|
|
||||||
usageEventUtilsMocked.verify(() -> UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volumeVoMock.getAccountId(), volumeVoMock.getDataCenterId(), volumeVoMock.getId(),
|
usageEventUtilsMocked.verify(() -> UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volumeVoMock.getAccountId(), volumeVoMock.getDataCenterId(), volumeVoMock.getId(),
|
||||||
volumeVoMock.getName(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.isDisplayVolume()));
|
volumeVoMock.getName(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.isDisplayVolume()));
|
||||||
|
|
||||||
Mockito.verify(resourceLimitServiceMock).decrementResourceCount(accountMock.getAccountId(), ResourceType.volume);
|
Mockito.verify(resourceLimitServiceMock).decrementVolumeResourceCount(accountMock.getAccountId(), true, volumeVoMock.getSize(), newDiskOfferingMock);
|
||||||
Mockito.verify(resourceLimitServiceMock).decrementResourceCount(accountMock.getAccountId(), ResourceType.primary_storage, volumeVoMock.getSize());
|
|
||||||
|
|
||||||
Mockito.verify(volumeVoMock).setAccountId(newAccountMock.getAccountId());
|
Mockito.verify(volumeVoMock).setAccountId(newAccountMock.getAccountId());
|
||||||
Mockito.verify(volumeVoMock).setDomainId(newAccountMock.getDomainId());
|
Mockito.verify(volumeVoMock).setDomainId(newAccountMock.getDomainId());
|
||||||
|
|
||||||
Mockito.verify(volumeDaoMock).persist(volumeVoMock);
|
Mockito.verify(volumeDaoMock).persist(volumeVoMock);
|
||||||
|
|
||||||
Mockito.verify(resourceLimitServiceMock).incrementResourceCount(newAccountMock.getAccountId(), ResourceType.volume);
|
Mockito.verify(resourceLimitServiceMock).incrementVolumeResourceCount(newAccountMock.getAccountId(), true, volumeVoMock.getSize(), newDiskOfferingMock);
|
||||||
Mockito.verify(resourceLimitServiceMock).incrementResourceCount(newAccountMock.getAccountId(), ResourceType.primary_storage, volumeVoMock.getSize());
|
|
||||||
|
|
||||||
usageEventUtilsMocked.verify(() -> UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volumeVoMock.getAccountId(), volumeVoMock.getDataCenterId(), volumeVoMock.getId(),
|
usageEventUtilsMocked.verify(() -> UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volumeVoMock.getAccountId(), volumeVoMock.getDataCenterId(), volumeVoMock.getId(),
|
||||||
volumeVoMock.getName(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.isDisplayVolume()));
|
volumeVoMock.getName(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.isDisplayVolume()));
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user