mirror of https://github.com/apache/cloudstack.git
Merge branch 'main' into nsx-integration
This commit is contained in:
commit
4c36d56143
|
|
@ -179,7 +179,8 @@ jobs:
|
|||
"component/test_project_usage
|
||||
component/test_protocol_number_security_group
|
||||
component/test_public_ip
|
||||
component/test_resource_limits",
|
||||
component/test_resource_limits
|
||||
component/test_resource_limit_tags",
|
||||
"component/test_regions_accounts
|
||||
component/test_routers
|
||||
component/test_snapshots
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package com.cloud.capacity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
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 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 getDataCenterId();
|
||||
|
|
@ -54,4 +61,6 @@ public interface Capacity extends InternalIdentity, Identity {
|
|||
public Float getUsedPercentage();
|
||||
|
||||
public Long getAllocatedCapacity();
|
||||
|
||||
public String getTag();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,5 +85,6 @@ public interface Resource {
|
|||
long getOwnerId();
|
||||
|
||||
ResourceOwnerType getResourceOwnerType();
|
||||
String getTag();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -449,10 +449,11 @@ public interface ManagementService {
|
|||
* this method removes the child storage pools and adds the corresponding parent datastore cluster for API response listing
|
||||
*
|
||||
* @param Long volumeId
|
||||
* @param String keyword if passed, will only return storage pools that contain this keyword in the name
|
||||
* @return Pair<List<? extends StoragePool>, List<? extends StoragePool>> List of storage pools in cluster and list
|
||||
* of pools with enough capacity.
|
||||
*/
|
||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(Long volumeId);
|
||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(Long volumeId, String keyword);
|
||||
|
||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForSystemMigrationOfVolume(Long volumeId, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean keepSourceStoragePool, boolean bypassStorageTypeCheck);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import com.cloud.utils.fsm.StateObject;
|
|||
|
||||
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)
|
||||
String BANDWIDTH_LIMIT_IN_MBPS = "bandwidthLimitInMbps";
|
||||
String IOPS_LIMIT = "iopsLimit";
|
||||
|
|
|
|||
|
|
@ -18,13 +18,18 @@ package com.cloud.user;
|
|||
|
||||
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.ResourceCount;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.user.ResourceReservation;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
|
||||
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);
|
||||
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);
|
||||
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.
|
||||
|
|
@ -46,22 +58,27 @@ public interface ResourceLimitService {
|
|||
* TODO
|
||||
* @param max
|
||||
* TODO
|
||||
* @param tag
|
||||
* tag for the resource type
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @param accountId
|
||||
* TODO
|
||||
* Id of the account for which resource recalculation to be done
|
||||
* @param domainId
|
||||
* TODO
|
||||
* Id of the domain for which resource recalculation to be doneDO
|
||||
* @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
|
||||
*/
|
||||
List<? extends ResourceCount> recalculateResourceCount(Long accountId, Long domainId, Integer typeId, String tag);
|
||||
List<? extends ResourceCount> recalculateResourceCount(Long accountId, Long domainId, Integer typeId);
|
||||
|
||||
/**
|
||||
|
|
@ -77,7 +94,7 @@ public interface ResourceLimitService {
|
|||
* TODO
|
||||
* @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
|
||||
|
|
@ -85,9 +102,10 @@ public interface ResourceLimitService {
|
|||
*
|
||||
* @param account
|
||||
* @param type
|
||||
* @param tag
|
||||
* @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
|
||||
|
|
@ -105,9 +123,10 @@ public interface ResourceLimitService {
|
|||
*
|
||||
* @param domain
|
||||
* @param type
|
||||
* @param tag
|
||||
* @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.
|
||||
|
|
@ -122,9 +141,10 @@ public interface ResourceLimitService {
|
|||
*
|
||||
* @param domain
|
||||
* @param type
|
||||
* @param tag
|
||||
* @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
|
||||
|
|
@ -134,6 +154,7 @@ public interface ResourceLimitService {
|
|||
* @param 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
|
||||
|
|
@ -143,6 +164,7 @@ public interface ResourceLimitService {
|
|||
* @param 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
|
||||
|
|
@ -155,15 +177,17 @@ public interface ResourceLimitService {
|
|||
* @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
|
||||
*
|
||||
* @param account
|
||||
* @param type
|
||||
* @param tag
|
||||
* @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
|
||||
|
|
@ -208,15 +232,25 @@ public interface ResourceLimitService {
|
|||
*/
|
||||
void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta);
|
||||
|
||||
/**
|
||||
* Adds a reservation that will be counted in subsequent calls to {count}getResourceCount{code} until {code}this[code}
|
||||
* is closed. It will create a reservation record that will be counted when resource limits are checked.
|
||||
* @param account The account for which the reservation is.
|
||||
* @param displayResource whether this resource is shown to users at all (if not it is not counted to limits)
|
||||
* @param type resource type
|
||||
* @param delta amount to reserve (will not be <+ 0)
|
||||
* @return a {code}AutoClosable{Code} object representing the resource the user needs
|
||||
*/
|
||||
ResourceReservation getReservation(Account account, Boolean displayResource, ResourceType type, Long delta) throws ResourceAllocationException;
|
||||
List<String> getResourceLimitHostTags();
|
||||
List<String> getResourceLimitHostTags(ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||
List<String> getResourceLimitStorageTags();
|
||||
List<String> getResourceLimitStorageTags(DiskOffering diskOffering);
|
||||
void updateTaggedResourceLimitsAndCountsForAccounts(List<AccountResponse> responses, String tag);
|
||||
void updateTaggedResourceLimitsAndCountsForDomains(List<DomainResponse> responses, String tag);
|
||||
void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException;
|
||||
void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -442,6 +442,6 @@ public class NicProfile implements InternalIdentity, Serializable {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("NicProfile %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "vmId", "reservationId", "iPv4Address", "broadcastUri"));
|
||||
return String.format("NicProfile %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "vmId", "deviceId", "broadcastUri", "reservationId", "iPv4Address"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ public class ApiConstants {
|
|||
public static final String LAST_SERVER_STOP = "lastserverstop";
|
||||
public static final String LEVEL = "level";
|
||||
public static final String LENGTH = "length";
|
||||
public static final String LIMIT = "limit";
|
||||
public static final String LIMIT_CPU_USE = "limitcpuuse";
|
||||
public static final String LIST_HOSTS = "listhosts";
|
||||
public static final String LOCK = "lock";
|
||||
|
|
@ -382,6 +383,7 @@ public class ApiConstants {
|
|||
public static final String RECONNECT = "reconnect";
|
||||
public static final String RECOVER = "recover";
|
||||
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_TYPE = "resourcetype";
|
||||
public static final String RESOURCE_TYPE_NAME = "resourcetypename";
|
||||
|
|
@ -422,8 +424,9 @@ public class ApiConstants {
|
|||
public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
|
||||
public static final String SNAPSHOT_TYPE = "snapshottype";
|
||||
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 SUITABLE_FOR_VM = "suitableforvirtualmachine";
|
||||
public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot";
|
||||
public static final String START_DATE = "startdate";
|
||||
public static final String START_ID = "startid";
|
||||
public static final String START_IP = "startip";
|
||||
|
|
@ -451,6 +454,7 @@ public class ApiConstants {
|
|||
public static final String TIMEOUT = "timeout";
|
||||
public static final String TIMEZONE = "timezone";
|
||||
public static final String TIMEZONEOFFSET = "timezoneoffset";
|
||||
public static final String TOTAL = "total";
|
||||
public static final String TOTAL_SUBNETS = "totalsubnets";
|
||||
public static final String TYPE = "type";
|
||||
public static final String TRUST_STORE = "truststore";
|
||||
|
|
@ -727,6 +731,7 @@ public class ApiConstants {
|
|||
public static final String POLICY_UUID = "policyuuid";
|
||||
public static final String RULE_UUID = "ruleuuid";
|
||||
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_TYPE = "tagtype";
|
||||
public static final String TAG_VALUE = "tagvalue";
|
||||
|
|
|
|||
|
|
@ -20,10 +20,6 @@ import java.util.ArrayList;
|
|||
import java.util.EnumSet;
|
||||
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.ApiConstants;
|
||||
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.response.DomainResponse;
|
||||
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.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},
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
|
|
@ -71,6 +71,9 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||
description = "flag to display the resource icon for domains")
|
||||
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 ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -110,10 +113,14 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||
return dv;
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
public boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -128,12 +135,17 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||
ListResponse<DomainResponse> response = _queryService.searchForDomains(this);
|
||||
response.setResponseName(getCommandName());
|
||||
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) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Domain, domainResponse.getId());
|
||||
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")
|
||||
private String sortBy;
|
||||
|
||||
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for the resource type", since = "4.20.0")
|
||||
private String tag;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -107,6 +110,10 @@ public class ListCapacityCmd extends BaseListCmd {
|
|||
return null;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public class FindStoragePoolsForMigrationCmd extends BaseListCmd {
|
|||
|
||||
@Override
|
||||
public void execute() {
|
||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> pools = _mgr.listStoragePoolsForMigrationOfVolume(getId());
|
||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> pools = _mgr.listStoragePoolsForMigrationOfVolume(getId(), getKeyword());
|
||||
ListResponse<StoragePoolResponse> response = new ListResponse<StoragePoolResponse>();
|
||||
List<StoragePoolResponse> poolResponses = new ArrayList<StoragePoolResponse>();
|
||||
|
||||
|
|
@ -85,7 +85,8 @@ public class FindStoragePoolsForMigrationCmd extends BaseListCmd {
|
|||
poolResponses.add(poolResponse);
|
||||
}
|
||||
sortPoolsBySuitabilityAndName(poolResponses);
|
||||
response.setResponses(poolResponses);
|
||||
List<StoragePoolResponse> pagingList = com.cloud.utils.StringUtils.applyPagination(poolResponses, this.getStartIndex(), this.getPageSizeVal());
|
||||
response.setResponses(pagingList, poolResponses.size());
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
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")
|
||||
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 ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -116,10 +120,14 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd implements UserC
|
|||
return dv;
|
||||
}
|
||||
|
||||
public Boolean getShowIcon() {
|
||||
public boolean getShowIcon() {
|
||||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -134,12 +142,17 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd implements UserC
|
|||
ListResponse<AccountResponse> response = _queryService.searchForAccounts(this);
|
||||
response.setResponseName(getCommandName());
|
||||
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) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Account, accountResponse.getObjectId());
|
||||
if (resourceIcon == null) {
|
||||
|
|
|
|||
|
|
@ -16,17 +16,16 @@
|
|||
// under the License.
|
||||
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.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||
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.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,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
|
|
@ -65,6 +64,13 @@ public class ListDiskOfferingsCmd extends BaseListProjectAndAccountResourcesCmd
|
|||
since = "4.19")
|
||||
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 ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -93,13 +99,16 @@ public class ListDiskOfferingsCmd extends BaseListProjectAndAccountResourcesCmd
|
|||
return storageType;
|
||||
}
|
||||
|
||||
public Long getVirtualMachineId() {
|
||||
return virtualMachineId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
ListResponse<DiskOfferingResponse> response = _queryService.searchForDiskOfferings(this);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
|
|
|
|||
|
|
@ -16,15 +16,15 @@
|
|||
// under the License.
|
||||
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.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
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.ZoneResponse;
|
||||
|
||||
@APICommand(name = "listServiceOfferings", description = "Lists all available service offerings.", responseObject = ServiceOfferingResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
|
|
@ -92,6 +92,14 @@ public class ListServiceOfferingsCmd extends BaseListProjectAndAccountResourcesC
|
|||
since = "4.19")
|
||||
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 ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -138,6 +146,10 @@ public class ListServiceOfferingsCmd extends BaseListProjectAndAccountResourcesC
|
|||
return storageType;
|
||||
}
|
||||
|
||||
public Long getTemplateId() {
|
||||
return templateId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ package org.apache.cloudstack.api.command.user.resource;
|
|||
import java.util.ArrayList;
|
||||
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.ApiConstants;
|
||||
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.ResourceLimitResponse;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
|
||||
@APICommand(name = "listResourceLimits", description = "Lists resource limits.", responseObject = ResourceLimitResponse.class,
|
||||
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. ")
|
||||
private String resourceTypeName;
|
||||
|
||||
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for the resource type", since = "4.20.0")
|
||||
private String tag;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -88,6 +92,10 @@ public class ListResourceLimitsCmd extends BaseListProjectAndAccountResourcesCmd
|
|||
return resourceTypeName;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -96,7 +104,7 @@ public class ListResourceLimitsCmd extends BaseListProjectAndAccountResourcesCmd
|
|||
public void execute() {
|
||||
List<? extends ResourceLimit> result =
|
||||
_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>();
|
||||
List<ResourceLimitResponse> limitResponses = new ArrayList<ResourceLimitResponse>();
|
||||
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")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for the resource type", since = "4.20.0")
|
||||
private String tag;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -91,6 +94,10 @@ public class UpdateResourceCountCmd extends BaseCmd {
|
|||
return resourceType;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -117,7 +124,7 @@ public class UpdateResourceCountCmd extends BaseCmd {
|
|||
@Override
|
||||
public void execute() {
|
||||
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)) {
|
||||
ListResponse<ResourceCountResponse> response = new ListResponse<ResourceCountResponse>();
|
||||
|
|
@ -125,7 +132,6 @@ public class UpdateResourceCountCmd extends BaseCmd {
|
|||
|
||||
for (ResourceCount count : result) {
|
||||
ResourceCountResponse resourceCountResponse = _responseGenerator.createResourceCountResponse(count);
|
||||
resourceCountResponse.setObjectName("resourcecount");
|
||||
countResponses.add(resourceCountResponse);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ public class UpdateResourceLimitCmd extends BaseCmd {
|
|||
+ "11 - SecondaryStorage. Total secondary storage space (in GiB) a user can use. ")
|
||||
private Integer resourceType;
|
||||
|
||||
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for the resource type", since = "4.20.0")
|
||||
private String tag;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -82,6 +85,10 @@ public class UpdateResourceLimitCmd extends BaseCmd {
|
|||
return domainId;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public Integer getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
|
@ -102,7 +109,7 @@ public class UpdateResourceLimitCmd extends BaseCmd {
|
|||
|
||||
@Override
|
||||
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)) {
|
||||
ResourceLimitResponse response = _responseGenerator.createResourceLimitResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.template;
|
||||
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
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).")
|
||||
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 ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -57,6 +59,10 @@ public class UpdateTemplateCmd extends BaseUpdateTemplateOrIsoCmd implements Use
|
|||
return templateType;
|
||||
}
|
||||
|
||||
public String getTemplateTag() {
|
||||
return templateTag;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// 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")
|
||||
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
|
||||
public String getObjectId() {
|
||||
return id;
|
||||
|
|
@ -545,4 +549,9 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTaggedResourceLimitsAndCounts(List<TaggedResourceLimitAndCountResponse> taggedResourceLimitsAndCounts) {
|
||||
this.taggedResources = taggedResourceLimitsAndCounts;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,11 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class CapacityResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.TYPE)
|
||||
|
|
@ -72,6 +71,10 @@ public class CapacityResponse extends BaseResponse {
|
|||
@Param(description = "the percentage of capacity currently in use")
|
||||
private String percentUsed;
|
||||
|
||||
@SerializedName(ApiConstants.TAG)
|
||||
@Param(description = "The tag for the capacity type", since = "4.20.0")
|
||||
private String tag;
|
||||
|
||||
public Short getCapacityType() {
|
||||
return capacityType;
|
||||
}
|
||||
|
|
@ -167,4 +170,8 @@ public class CapacityResponse extends BaseResponse {
|
|||
public void setPercentUsed(String 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")
|
||||
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() {
|
||||
return displayOffering;
|
||||
}
|
||||
|
|
@ -391,4 +395,8 @@ public class DiskOfferingResponse extends BaseResponseWithAnnotations {
|
|||
public void setDetails(Map<String, String> 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 java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@EntityReference(value = Domain.class)
|
||||
|
|
@ -184,6 +185,10 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||
@Param(description = "details for the domain")
|
||||
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() {
|
||||
return this.id;
|
||||
}
|
||||
|
|
@ -447,4 +452,9 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||
public void setDetails(Map<String, String> 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")
|
||||
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) {
|
||||
this.id = id;
|
||||
}
|
||||
|
|
@ -447,4 +451,9 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTaggedResourceLimitsAndCounts(List<TaggedResourceLimitAndCountResponse> taggedResourceLimitsAndCounts) {
|
||||
this.taggedResources = taggedResourceLimitsAndCounts;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,12 @@
|
|||
// under the License.
|
||||
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.BaseResponse;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
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.")
|
||||
private String resourceTypeName;
|
||||
|
||||
@SerializedName("resourcecount")
|
||||
@Param(description = "resource count")
|
||||
@SerializedName(ApiConstants.RESOURCE_COUNT)
|
||||
@Param(description = "The resource count")
|
||||
private long resourceCount;
|
||||
|
||||
@SerializedName(ApiConstants.TAG)
|
||||
@Param(description = "Tag for the resource", since = "4.20.0")
|
||||
private String tag;
|
||||
|
||||
@Override
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
|
|
@ -92,4 +95,7 @@ public class ResourceCountResponse extends BaseResponse implements ControlledEnt
|
|||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ResourceLimitAndCountResponse {
|
||||
|
||||
public void setNetworkLimit(String networkLimit);
|
||||
|
|
@ -92,4 +94,6 @@ public interface ResourceLimitAndCountResponse {
|
|||
|
||||
public void setVmRunning(Integer vmRunning);
|
||||
|
||||
public void setTaggedResourceLimitsAndCounts(List<TaggedResourceLimitAndCountResponse> taggedResourceLimitsAndCounts);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,15 +16,14 @@
|
|||
// under the License.
|
||||
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.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = ResourceLimit.class)
|
||||
@SuppressWarnings("unused")
|
||||
|
|
@ -61,6 +60,10 @@ public class ResourceLimitResponse extends BaseResponse implements ControlledEnt
|
|||
@Param(description = "the project name of the resource limit")
|
||||
private String projectName;
|
||||
|
||||
@SerializedName(ApiConstants.TAG)
|
||||
@Param(description = "The tag for the resource limit", since = "4.20.0")
|
||||
private String tag;
|
||||
|
||||
@Override
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
|
|
@ -94,4 +97,8 @@ public class ResourceLimitResponse extends BaseResponse implements ControlledEnt
|
|||
public void setProjectId(String 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;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
|
||||
/**
|
||||
* an interface defining an {code}AutoClosable{code} reservation object
|
||||
*/
|
||||
|
|
@ -33,5 +34,7 @@ ResourceReservation extends InternalIdentity {
|
|||
|
||||
Resource.ResourceType getResourceType();
|
||||
|
||||
String getTag();
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
@ -54,6 +54,8 @@ public class GsonHelper {
|
|||
GsonBuilder LOGGERBuilder = new GsonBuilder();
|
||||
LOGGERBuilder.disableHtmlEscaping();
|
||||
LOGGERBuilder.setExclusionStrategies(new LoggingExclusionStrategy(LOGGER));
|
||||
LOGGERBuilder.serializeSpecialFloatingPointValues();
|
||||
// maybe add LOGGERBuilder.serializeNulls(); as well?
|
||||
s_gogger = setDefaultGsonConfig(LOGGERBuilder);
|
||||
LOGGER.info("Default Builder inited.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,4 +290,6 @@ public interface VirtualMachineManager extends Manager {
|
|||
|
||||
HashMap<Long, List<? extends VmNetworkStats>> getVmNetworkStatistics(long hostId, String hostName, Map<Long, ? extends VirtualMachine> vmMap);
|
||||
|
||||
Map<Long, Boolean> getDiskOfferingSuitabilityForVm(long vmId, List<Long> diskOfferingIds);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,9 +52,12 @@ public interface StoragePoolAllocator extends Adapter {
|
|||
* avoid
|
||||
* @param int returnUpTo (use -1 to return all possible pools)
|
||||
* @param boolean bypassStorageTypeCheck allows bypassing useLocalStorage check for provided DiskProfile when true
|
||||
* @param String keyword if passed, will only return storage pools that contain this keyword in the name
|
||||
* @return List<StoragePool> List of storage pools that are suitable for the
|
||||
* VM
|
||||
**/
|
||||
List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck, String keyword);
|
||||
|
||||
List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -277,6 +277,8 @@ public interface StorageManager extends StorageService {
|
|||
|
||||
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<VMInstanceVO> listByStoragePool(long storagePoolId);
|
||||
|
|
@ -303,6 +305,9 @@ public interface StorageManager extends StorageService {
|
|||
|
||||
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);
|
||||
|
||||
/**
|
||||
|
|
@ -335,6 +340,8 @@ public interface StorageManager extends StorageService {
|
|||
|
||||
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 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 java.lang.reflect.Field;
|
||||
import java.net.URI;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
|
@ -154,7 +155,6 @@ import com.cloud.api.query.dao.UserVmJoinDao;
|
|||
import com.cloud.api.query.vo.DomainRouterJoinVO;
|
||||
import com.cloud.api.query.vo.UserVmJoinVO;
|
||||
import com.cloud.capacity.CapacityManager;
|
||||
import com.cloud.configuration.Resource.ResourceType;
|
||||
import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.dc.ClusterDetailsVO;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
|
|
@ -1152,7 +1152,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
// check resource count if ResourceCountRunningVMsonly.value() = true
|
||||
final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
|
||||
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;
|
||||
|
|
@ -1462,7 +1462,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
} finally {
|
||||
if (startedVm == null) {
|
||||
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) {
|
||||
try {
|
||||
|
|
@ -2281,7 +2281,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
if (result) {
|
||||
if (VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
||||
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 {
|
||||
throw new CloudRuntimeException("unable to stop " + vm);
|
||||
|
|
@ -5679,18 +5680,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
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
|
||||
public UserVm restoreVirtualMachine(final long vmId, final Long newTemplateId) throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
||||
|
|
@ -6118,4 +6107,48 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2371,12 +2371,12 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
|
||||
@DB
|
||||
protected void releaseNic(final VirtualMachineProfile vmProfile, final long nicId) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
final Pair<Network, NicProfile> networkToRelease = Transaction.execute(new TransactionCallback<Pair<Network, NicProfile>>() {
|
||||
final Pair<Network, NicProfile> networkToRelease = Transaction.execute(new TransactionCallback<>() {
|
||||
@Override
|
||||
public Pair<Network, NicProfile> doInTransaction(final TransactionStatus status) {
|
||||
final NicVO nic = _nicDao.lockRow(nicId, true);
|
||||
if (nic == null) {
|
||||
throw new ConcurrentOperationException("Unable to acquire lock on nic " + nic);
|
||||
throw new ConcurrentOperationException(String.format("Unable to acquire lock on nic id=%d", nicId));
|
||||
}
|
||||
|
||||
final Nic.State originalState = nic.getState();
|
||||
|
|
@ -2390,6 +2390,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel
|
||||
.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
|
||||
if (guru.release(profile, vmProfile, nic.getReservationId())) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("The nic %s on %s was released according to %s by guru %s, now updating record.", nic, profile, vmProfile, guru));
|
||||
}
|
||||
applyProfileToNicForRelease(nic, profile);
|
||||
nic.setState(Nic.State.Allocated);
|
||||
if (originalState == Nic.State.Reserved) {
|
||||
|
|
@ -2399,7 +2402,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
}
|
||||
}
|
||||
// Perform release on network elements
|
||||
return new Pair<Network, NicProfile>(network, profile);
|
||||
return new Pair<>(network, profile);
|
||||
} else {
|
||||
nic.setState(Nic.State.Allocated);
|
||||
updateNic(nic, network.getId(), -1);
|
||||
|
|
@ -2496,7 +2499,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
for (final NetworkElement element : networkElements) {
|
||||
if (providersToImplement.contains(element.getProvider())) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Asking " + element.getName() + " to release " + nic);
|
||||
logger.debug(String.format("Asking %s to release %s, according to the reservation strategy %s", element.getName(), nic, nic.getReservationStrategy()));
|
||||
}
|
||||
try {
|
||||
element.release(network, profile, vm, null);
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ import com.cloud.storage.Volume.Type;
|
|||
import com.cloud.storage.VolumeApiService;
|
||||
import com.cloud.storage.VolumeDetailVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
||||
|
|
@ -245,6 +246,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
PassphraseDao passphraseDao;
|
||||
@Inject
|
||||
StoragePoolHostDao storagePoolHostDao;
|
||||
@Inject
|
||||
DiskOfferingDao diskOfferingDao;
|
||||
|
||||
@Inject
|
||||
protected SnapshotHelper snapshotHelper;
|
||||
|
|
@ -878,9 +881,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
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());
|
||||
|
||||
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
|
||||
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
|
||||
_resourceLimitMgr.incrementVolumeResourceCount(vm.getAccountId(), vol.isDisplayVolume(), vol.getSize(), 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,
|
||||
Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
|
||||
|
||||
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
|
||||
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
|
||||
_resourceLimitMgr.incrementVolumeResourceCount(vm.getAccountId(), vol.isDisplayVolume(), vol.getSize(), 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.
|
||||
_resourceLimitMgr.decrementResourceCount(volumeInfo.getAccountId(), ResourceType.secondary_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) {
|
||||
_volsDao.remove(volume.getId());
|
||||
stateTransitTo(volume, Volume.Event.DestroyRequested);
|
||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplay());
|
||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplay(), new Long(volume.getSize()));
|
||||
_resourceLimitMgr.decrementVolumeResourceCount(volume.getAccountId(), volume.isDisplay(), volume.getSize(), diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId()));
|
||||
} else {
|
||||
destroyVolumeInContext(volume);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import static org.junit.Assert.assertNull;
|
|||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
|
@ -50,27 +51,12 @@ import com.cloud.network.vpc.VpcVO;
|
|||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
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.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
|
@ -83,6 +69,7 @@ import org.mockito.Mockito;
|
|||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Command;
|
||||
|
|
@ -90,16 +77,25 @@ import com.cloud.agent.api.StopAnswer;
|
|||
import com.cloud.agent.api.StopCommand;
|
||||
import com.cloud.agent.api.routing.NetworkElementCommand;
|
||||
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.DeployDestination;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.deploy.DeploymentPlanningManager;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.hypervisor.HypervisorGuruManager;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.org.Cluster;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
|
|
@ -117,11 +113,19 @@ import com.cloud.storage.dao.StoragePoolHostDao;
|
|||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplateZoneDao;
|
||||
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.fsm.StateMachine2;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class VirtualMachineManagerImplTest {
|
||||
|
|
@ -206,6 +210,8 @@ public class VirtualMachineManagerImplTest {
|
|||
@Mock
|
||||
private HypervisorGuruManager _hvGuruMgr;
|
||||
@Mock
|
||||
private ClusterDao clusterDao;
|
||||
@Mock
|
||||
private ClusterDetailsDao _clusterDetailsDao;
|
||||
@Mock
|
||||
private UserVmDetailsDao userVmDetailsDao;
|
||||
|
|
@ -1181,4 +1187,47 @@ public class VirtualMachineManagerImplTest {
|
|||
|
||||
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
|
||||
private Long allocatedCapacity;
|
||||
|
||||
@Transient
|
||||
private String tag;
|
||||
|
||||
public CapacityVO() {
|
||||
}
|
||||
|
||||
|
|
@ -221,6 +224,15 @@ public class CapacityVO implements Capacity {
|
|||
this.allocatedCapacity = allocatedCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
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> 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);
|
||||
|
||||
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,
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ import java.util.Map;
|
|||
|
||||
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.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.CapacityVO;
|
||||
|
|
@ -339,7 +339,8 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
}
|
||||
|
||||
@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();
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
|
|
@ -378,6 +379,18 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
finalQuery.append(" AND capacity_type = ?");
|
||||
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) {
|
||||
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
|
||||
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();
|
||||
PreparedStatement pstmt = null;
|
||||
|
|
@ -516,6 +558,8 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
resourceIdList.add(capacityType.longValue());
|
||||
}
|
||||
|
||||
sql.append(getHostAndPoolConditionForFilteredCapacity(capacityType, hostIds, poolIds));
|
||||
|
||||
if (podId == null && clusterId == null) {
|
||||
sql.append(" GROUP BY capacity_type, data_center_id");
|
||||
} 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) {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
|
|
@ -702,6 +751,7 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
public Long clusterId;
|
||||
public Long podId;
|
||||
public Long dcId;
|
||||
public String tag;
|
||||
|
||||
public SummedCapacity() {
|
||||
}
|
||||
|
|
@ -790,6 +840,14 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
public void setAllocatedCapacity(Long sumAllocated) {
|
||||
this.sumAllocated = sumAllocated;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -47,10 +47,13 @@ public class ResourceCountVO implements ResourceCount {
|
|||
@Column(name = "count")
|
||||
private long count;
|
||||
|
||||
@Column(name = "tag")
|
||||
private String tag;
|
||||
|
||||
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.count = count;
|
||||
|
||||
|
|
@ -59,6 +62,11 @@ public class ResourceCountVO implements ResourceCount {
|
|||
} else if (ownerType == ResourceOwnerType.Domain) {
|
||||
this.domainId = ownerId;
|
||||
}
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public ResourceCountVO(ResourceType type, long count, long ownerId, ResourceOwnerType ownerType) {
|
||||
this(type, count, ownerId, ownerType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -99,7 +107,7 @@ public class ResourceCountVO implements ResourceCount {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("REsourceCount[").append("-")
|
||||
return new StringBuilder("ResourceCount[").append("-")
|
||||
.append(id)
|
||||
.append("-")
|
||||
.append(type)
|
||||
|
|
@ -107,6 +115,8 @@ public class ResourceCountVO implements ResourceCount {
|
|||
.append(accountId)
|
||||
.append("-")
|
||||
.append(domainId)
|
||||
.append("-")
|
||||
.append(tag)
|
||||
.append("]")
|
||||
.toString();
|
||||
}
|
||||
|
|
@ -136,4 +146,13 @@ public class ResourceCountVO implements ResourceCount {
|
|||
public void setAccountId(Long 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")
|
||||
private Long max;
|
||||
|
||||
@Column(name = "tag")
|
||||
private String tag;
|
||||
|
||||
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.max = max;
|
||||
|
||||
|
|
@ -59,6 +62,11 @@ public class ResourceLimitVO implements ResourceLimit {
|
|||
} else if (ownerType == ResourceOwnerType.Domain) {
|
||||
this.domainId = ownerId;
|
||||
}
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public ResourceLimitVO(ResourceCount.ResourceType type, Long max, long ownerId, ResourceOwnerType ownerType) {
|
||||
this(type, max, ownerId, ownerType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -123,4 +131,12 @@ public class ResourceLimitVO implements ResourceLimit {
|
|||
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> {
|
||||
/**
|
||||
* @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 tag for the type of resource
|
||||
* @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 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);
|
||||
|
||||
|
|
@ -45,13 +47,13 @@ public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
|
|||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -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.
|
||||
*/
|
||||
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.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
|
@ -27,6 +28,9 @@ import java.util.Set;
|
|||
import javax.annotation.PostConstruct;
|
||||
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 com.cloud.configuration.Resource;
|
||||
|
|
@ -37,6 +41,7 @@ import com.cloud.configuration.ResourceLimit;
|
|||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
|
|
@ -49,6 +54,8 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||
@Component
|
||||
public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long> implements ResourceCountDao {
|
||||
private final SearchBuilder<ResourceCountVO> TypeSearch;
|
||||
private final SearchBuilder<ResourceCountVO> TypeNullTagSearch;
|
||||
private final SearchBuilder<ResourceCountVO> NonMatchingTagsSearch;
|
||||
|
||||
private final SearchBuilder<ResourceCountVO> AccountSearch;
|
||||
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("accountId", TypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
TypeSearch.and("domainId", TypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||
TypeSearch.and("tag", TypeSearch.entity().getTag(), SearchCriteria.Op.EQ);
|
||||
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();
|
||||
DomainSearch = createSearchBuilder();
|
||||
}
|
||||
|
|
@ -85,9 +108,12 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||
}
|
||||
|
||||
@Override
|
||||
public ResourceCountVO findByOwnerAndType(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
|
||||
SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
|
||||
public ResourceCountVO findByOwnerAndTypeAndTag(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag) {
|
||||
SearchCriteria<ResourceCountVO> sc = tag != null ? TypeSearch.create() : TypeNullTagSearch.create();
|
||||
sc.setParameters("type", type);
|
||||
if (tag != null) {
|
||||
sc.setParameters("tag", tag);
|
||||
}
|
||||
|
||||
if (ownerType == ResourceOwnerType.Account) {
|
||||
sc.setParameters("accountId", ownerId);
|
||||
|
|
@ -101,8 +127,8 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
|
||||
ResourceCountVO vo = findByOwnerAndType(ownerId, ownerType, type);
|
||||
public long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag) {
|
||||
ResourceCountVO vo = findByOwnerAndTypeAndTag(ownerId, ownerType, type, tag);
|
||||
if (vo != null) {
|
||||
return vo.getCount();
|
||||
} else {
|
||||
|
|
@ -111,8 +137,8 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, long count) {
|
||||
ResourceCountVO resourceCountVO = findByOwnerAndType(ownerId, ownerType, type);
|
||||
public void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, String tag, long count) {
|
||||
ResourceCountVO resourceCountVO = findByOwnerAndTypeAndTag(ownerId, ownerType, type, tag);
|
||||
if (resourceCountVO != null && count != resourceCountVO.getCount()) {
|
||||
resourceCountVO.setCount(count);
|
||||
update(resourceCountVO.getId(), resourceCountVO);
|
||||
|
|
@ -129,38 +155,59 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||
}
|
||||
|
||||
@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> domainIdsToUpdate = _domainDao.getDomainParentIds(domainId);
|
||||
for (Long domainIdToUpdate : domainIdsToUpdate) {
|
||||
ResourceCountVO domainCountRecord = findByOwnerAndType(domainIdToUpdate, ResourceOwnerType.Domain, type);
|
||||
ResourceCountVO domainCountRecord = findByOwnerAndTypeAndTag(domainIdToUpdate, ResourceOwnerType.Domain, type, tag);
|
||||
if (domainCountRecord != null) {
|
||||
rowIds.add(domainCountRecord.getId());
|
||||
} else {
|
||||
if (StringUtils.isNotEmpty(tag)) {
|
||||
ResourceCountVO resourceCountVO = createTaggedResourceCount(domainIdToUpdate, ResourceOwnerType.Domain, type, tag);
|
||||
rowIds.add(resourceCountVO.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return rowIds;
|
||||
}
|
||||
|
||||
@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>();
|
||||
|
||||
if (ownerType == ResourceOwnerType.Account) {
|
||||
//get records for account
|
||||
ResourceCountVO accountCountRecord = findByOwnerAndType(ownerId, ResourceOwnerType.Account, type);
|
||||
ResourceCountVO accountCountRecord = findByOwnerAndTypeAndTag(ownerId, ResourceOwnerType.Account, type, tag);
|
||||
if (accountCountRecord != null) {
|
||||
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
|
||||
rowIds.addAll(listRowsToUpdateForDomain(_accountDao.findByIdIncludingRemoved(ownerId).getDomainId(), type));
|
||||
rowIds.addAll(listRowsToUpdateForDomain(_accountDao.findByIdIncludingRemoved(ownerId).getDomainId(), type, tag));
|
||||
} else if (ownerType == ResourceOwnerType.Domain) {
|
||||
return listRowsToUpdateForDomain(ownerId, type);
|
||||
rowIds = listRowsToUpdateForDomain(ownerId, type, tag);
|
||||
}
|
||||
|
||||
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
|
||||
@DB
|
||||
public void createResourceCounts(long ownerId, ResourceLimit.ResourceOwnerType ownerType) {
|
||||
|
|
@ -169,9 +216,23 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
|||
txn.start();
|
||||
|
||||
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) {
|
||||
ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, ownerId, ownerType);
|
||||
persist(resourceCountVO);
|
||||
if (ResourceLimitService.HostTagsSupportingTypes.contains(resourceType)) {
|
||||
createTaggedResourceCounts(ownerId, ownerType, resourceType, hostTags);
|
||||
}
|
||||
if (ResourceLimitService.StorageTagsSupportingTypes.contains(resourceType)) {
|
||||
createTaggedResourceCounts(ownerId, ownerType, resourceType, storageTags);
|
||||
}
|
||||
}
|
||||
|
||||
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 com.cloud.configuration.Resource;
|
||||
import com.cloud.configuration.Resource.ResourceOwnerType;
|
||||
import com.cloud.configuration.ResourceCount;
|
||||
import com.cloud.configuration.ResourceLimitVO;
|
||||
|
|
@ -31,7 +32,8 @@ public interface ResourceLimitDao extends GenericDao<ResourceLimitVO, Long> {
|
|||
|
||||
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);
|
||||
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 org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
|
|
@ -33,19 +35,36 @@ import com.cloud.utils.db.SearchCriteria;
|
|||
|
||||
@Component
|
||||
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() {
|
||||
IdTypeSearch = createSearchBuilder();
|
||||
IdTypeSearch.and("type", IdTypeSearch.entity().getType(), SearchCriteria.Op.EQ);
|
||||
IdTypeSearch.and("domainId", IdTypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||
IdTypeSearch.and("accountId", IdTypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
IdTypeSearch.done();
|
||||
IdTypeTagSearch = createSearchBuilder();
|
||||
IdTypeTagSearch.and("type", IdTypeTagSearch.entity().getType(), SearchCriteria.Op.EQ);
|
||||
IdTypeTagSearch.and("domainId", IdTypeTagSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||
IdTypeTagSearch.and("accountId", IdTypeTagSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
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
|
||||
public List<ResourceLimitVO> listByOwner(Long ownerId, ResourceOwnerType ownerType) {
|
||||
SearchCriteria<ResourceLimitVO> sc = IdTypeSearch.create();
|
||||
SearchCriteria<ResourceLimitVO> sc = IdTypeTagSearch.create();
|
||||
|
||||
if (ownerType == ResourceOwnerType.Account) {
|
||||
sc.setParameters("accountId", ownerId);
|
||||
|
|
@ -81,9 +100,12 @@ public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long>
|
|||
}
|
||||
|
||||
@Override
|
||||
public ResourceLimitVO findByOwnerIdAndType(long ownerId, ResourceOwnerType ownerType, ResourceCount.ResourceType type) {
|
||||
SearchCriteria<ResourceLimitVO> sc = IdTypeSearch.create();
|
||||
public ResourceLimitVO findByOwnerIdAndTypeAndTag(long ownerId, ResourceOwnerType ownerType, ResourceCount.ResourceType type, String tag) {
|
||||
SearchCriteria<ResourceLimitVO> sc = tag != null ? IdTypeTagSearch.create() : IdTypeNullTagSearch.create();
|
||||
sc.setParameters("type", type);
|
||||
if (tag != null) {
|
||||
sc.setParameters("tag", tag);
|
||||
}
|
||||
|
||||
if (ownerType == ResourceOwnerType.Account) {
|
||||
sc.setParameters("accountId", ownerId);
|
||||
|
|
@ -98,7 +120,7 @@ public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long>
|
|||
|
||||
@Override
|
||||
public long removeEntriesByOwner(Long ownerId, ResourceOwnerType ownerType) {
|
||||
SearchCriteria<ResourceLimitVO> sc = IdTypeSearch.create();
|
||||
SearchCriteria<ResourceLimitVO> sc = IdTypeTagSearch.create();
|
||||
|
||||
if (ownerType == ResourceOwnerType.Account) {
|
||||
sc.setParameters("accountId", ownerId);
|
||||
|
|
@ -109,4 +131,23 @@ public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long>
|
|||
}
|
||||
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.
|
||||
package com.cloud.host;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
|
@ -39,21 +42,21 @@ import javax.persistence.Temporal;
|
|||
import javax.persistence.TemporalType;
|
||||
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.host.dao.HostTagsDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.resource.ResourceState;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import com.cloud.util.StoragePoolTypeConverter;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
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
|
||||
@Table(name = "host")
|
||||
|
|
@ -764,7 +767,28 @@ public class HostVO implements Host {
|
|||
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) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -776,7 +800,6 @@ public class HostVO implements Host {
|
|||
if (StringUtils.isEmpty(serviceOffering.getHostTag())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
List<String> serviceOfferingTags = Arrays.asList(serviceOffering.getHostTag().split(","));
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -780,7 +780,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
}
|
||||
|
||||
@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();
|
||||
HostVO entity = hostSearch.entity();
|
||||
hostSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -798,7 +798,9 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
if (clusterId != null) {
|
||||
sc.setParameters("cluster", clusterId);
|
||||
}
|
||||
sc.setParameters("dc", dcId);
|
||||
if (dcId != null) {
|
||||
sc.setParameters("dc", dcId);
|
||||
}
|
||||
sc.setParameters("status", Status.Up.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);
|
||||
|
||||
ServiceOfferingVO findServiceOfferingByComputeOnlyDiskOffering(long diskOfferingId);
|
||||
|
||||
List<ServiceOfferingVO> listByHostTag(String tag);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -291,4 +291,22 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
|||
}
|
||||
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> findCustomDiskOfferings();
|
||||
List<DiskOfferingVO> listByStorageTag(String tag);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,4 +157,22 @@ public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> im
|
|||
|
||||
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);
|
||||
|
||||
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.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.framework.config.dao.ConfigurationDao;
|
||||
|
||||
|
|
@ -31,7 +29,10 @@ import com.cloud.storage.StoragePoolTagVO;
|
|||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
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.TransactionStatus;
|
||||
|
||||
public class StoragePoolTagsDaoImpl extends GenericDaoBase<StoragePoolTagVO, Long> implements StoragePoolTagsDao {
|
||||
|
||||
|
|
@ -178,4 +179,15 @@ public class StoragePoolTagsDaoImpl extends GenericDaoBase<StoragePoolTagVO, Lon
|
|||
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> listByIds(List<Long> ids);
|
||||
|
||||
List<VMTemplateVO> listByTemplateTag(String tag);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -686,6 +686,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||
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
|
||||
public boolean updateState(
|
||||
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);
|
||||
|
||||
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());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import javax.persistence.Id;
|
|||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
|
||||
|
|
@ -329,17 +330,7 @@ public class NicVO implements Nic {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("Nic[").append(id)
|
||||
.append("-")
|
||||
.append(instanceId)
|
||||
.append("-")
|
||||
.append(deviceId)
|
||||
.append("-")
|
||||
.append(reservationId)
|
||||
.append("-")
|
||||
.append(iPv4Address)
|
||||
.append("]")
|
||||
.toString();
|
||||
return String.format("Nic %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "instanceId", "deviceId", "broadcastUri", "reservationId", "iPv4Address"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -18,10 +18,6 @@
|
|||
//
|
||||
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.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
|
|
@ -29,6 +25,11 @@ import javax.persistence.GenerationType;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.cloudstack.user.ResourceReservation;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Entity
|
||||
@Table(name = "resource_reservation")
|
||||
public class ReservationVO implements ResourceReservation {
|
||||
|
|
@ -47,22 +48,30 @@ public class ReservationVO implements ResourceReservation {
|
|||
@Column(name = "resource_type", nullable = false)
|
||||
Resource.ResourceType resourceType;
|
||||
|
||||
@Column(name = "tag")
|
||||
String tag;
|
||||
|
||||
@Column(name = "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) {
|
||||
throw new CloudRuntimeException("resource reservations can not be made for no resources");
|
||||
}
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.resourceType = resourceType;
|
||||
this.tag = tag;
|
||||
this.amount = delta;
|
||||
}
|
||||
|
||||
public ReservationVO(Long accountId, Long domainId, Resource.ResourceType resourceType, Long delta) {
|
||||
this(accountId, domainId, resourceType, null, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return this.id;
|
||||
|
|
@ -83,6 +92,11 @@ public class ReservationVO implements ResourceReservation {
|
|||
return resourceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getReservedAmount() {
|
||||
return amount;
|
||||
|
|
|
|||
|
|
@ -18,11 +18,12 @@
|
|||
//
|
||||
package org.apache.cloudstack.reservation.dao;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import org.apache.cloudstack.reservation.ReservationVO;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface ReservationDao extends GenericDao<ReservationVO, Long> {
|
||||
long getAccountReservation(Long account, Resource.ResourceType resourceType);
|
||||
long getDomainReservation(Long domain, Resource.ResourceType resourceType);
|
||||
long getAccountReservation(Long account, Resource.ResourceType resourceType, String tag);
|
||||
long getDomainReservation(Long domain, Resource.ResourceType resourceType, String tag);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,41 +18,63 @@
|
|||
//
|
||||
package org.apache.cloudstack.reservation.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.reservation.ReservationVO;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
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 {
|
||||
|
||||
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 DOMAIN_ID = "domainId";
|
||||
private final SearchBuilder<ReservationVO> listAccountAndTypeSearch;
|
||||
private final SearchBuilder<ReservationVO> listAccountAndTypeAndNoTagSearch;
|
||||
|
||||
private final SearchBuilder<ReservationVO> listDomainAndTypeSearch;
|
||||
private final SearchBuilder<ReservationVO> listDomainAndTypeAndNoTagSearch;
|
||||
|
||||
public ReservationDaoImpl() {
|
||||
listAccountAndTypeSearch = createSearchBuilder();
|
||||
listAccountAndTypeSearch.and(ACCOUNT_ID, listAccountAndTypeSearch.entity().getAccountId(), 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();
|
||||
|
||||
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.and(DOMAIN_ID, listDomainAndTypeSearch.entity().getDomainId(), 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();
|
||||
|
||||
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
|
||||
public long getAccountReservation(Long accountId, Resource.ResourceType resourceType) {
|
||||
public long getAccountReservation(Long accountId, Resource.ResourceType resourceType, String tag) {
|
||||
long total = 0;
|
||||
SearchCriteria<ReservationVO> sc = listAccountAndTypeSearch.create();
|
||||
SearchCriteria<ReservationVO> sc = tag == null ?
|
||||
listAccountAndTypeAndNoTagSearch.create() : listAccountAndTypeSearch.create();
|
||||
sc.setParameters(ACCOUNT_ID, accountId);
|
||||
sc.setParameters(RESOURCE_TYPE, resourceType);
|
||||
if (tag != null) {
|
||||
sc.setParameters(RESOURCE_TAG, tag);
|
||||
}
|
||||
List<ReservationVO> reservations = listBy(sc);
|
||||
for (ReservationVO reservation : reservations) {
|
||||
total += reservation.getReservedAmount();
|
||||
|
|
@ -61,11 +83,15 @@ public class ReservationDaoImpl extends GenericDaoBase<ReservationVO, Long> impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getDomainReservation(Long domainId, Resource.ResourceType resourceType) {
|
||||
public long getDomainReservation(Long domainId, Resource.ResourceType resourceType, String tag) {
|
||||
long total = 0;
|
||||
SearchCriteria<ReservationVO> sc = listDomainAndTypeSearch.create();
|
||||
SearchCriteria<ReservationVO> sc = tag == null ?
|
||||
listDomainAndTypeAndNoTagSearch.create() : listDomainAndTypeSearch.create();
|
||||
sc.setParameters(DOMAIN_ID, domainId);
|
||||
sc.setParameters(RESOURCE_TYPE, resourceType);
|
||||
if (tag != null) {
|
||||
sc.setParameters(RESOURCE_TAG, tag);
|
||||
}
|
||||
List<ReservationVO> reservations = listBy(sc);
|
||||
for (ReservationVO reservation : reservations) {
|
||||
total += reservation.getReservedAmount();
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ public interface PrimaryDataStoreDao extends GenericDao<StoragePoolVO, Long> {
|
|||
*/
|
||||
List<StoragePoolVO> listBy(long datacenterId, Long podId, Long clusterId, ScopeType scope);
|
||||
|
||||
List<StoragePoolVO> listBy(long datacenterId, Long podId, Long clusterId, ScopeType scope, String keyword);
|
||||
|
||||
/**
|
||||
* Set capacity of storage pool in bytes
|
||||
* @param id pool id.
|
||||
|
|
@ -115,15 +117,19 @@ public interface PrimaryDataStoreDao extends GenericDao<StoragePoolVO, Long> {
|
|||
|
||||
List<StoragePoolVO> findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags, boolean validateTagRule);
|
||||
|
||||
List<StoragePoolVO> findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags, boolean validateTagRule, String keyword);
|
||||
|
||||
List<StoragePoolVO> findZoneWideStoragePoolsByTags(long dcId, String[] tags, boolean validateTagRule);
|
||||
|
||||
List<StoragePoolVO> findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType);
|
||||
|
||||
List<StoragePoolVO> findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType, String keyword);
|
||||
|
||||
List<StoragePoolVO> findLocalStoragePoolsByHostAndTags(long hostId, String[] tags);
|
||||
|
||||
List<StoragePoolVO> listLocalStoragePoolByPath(long datacenterId, String path);
|
||||
|
||||
List<StoragePoolVO> findPoolsInClusters(List<Long> clusterIds);
|
||||
List<StoragePoolVO> findPoolsInClusters(List<Long> clusterIds, String keyword);
|
||||
|
||||
void deletePoolTags(long poolId);
|
||||
|
||||
|
|
|
|||
|
|
@ -244,6 +244,11 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
|
|||
|
||||
@Override
|
||||
public List<StoragePoolVO> listBy(long datacenterId, Long podId, Long clusterId, ScopeType scope) {
|
||||
return listBy(datacenterId, podId, clusterId, scope, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolVO> listBy(long datacenterId, Long podId, Long clusterId, ScopeType scope, String keyword) {
|
||||
SearchCriteria<StoragePoolVO> sc = null;
|
||||
if (clusterId != null) {
|
||||
sc = DcPodSearch.create();
|
||||
|
|
@ -255,6 +260,9 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
|
|||
sc.setParameters("datacenterId", datacenterId);
|
||||
sc.setParameters("podId", podId);
|
||||
sc.setParameters("status", Status.Up);
|
||||
if (keyword != null) {
|
||||
sc.addAnd("name", Op.LIKE, "%" + keyword + "%");
|
||||
}
|
||||
if (scope != null) {
|
||||
sc.setParameters("scope", scope);
|
||||
}
|
||||
|
|
@ -444,9 +452,14 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
|
|||
|
||||
@Override
|
||||
public List<StoragePoolVO> findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags, boolean validateTagRule) {
|
||||
return findLocalStoragePoolsByTags(dcId, podId, clusterId, tags, validateTagRule, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolVO> findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags, boolean validateTagRule, String keyword) {
|
||||
List<StoragePoolVO> storagePools = null;
|
||||
if (tags == null || tags.length == 0) {
|
||||
storagePools = listBy(dcId, podId, clusterId, ScopeType.HOST);
|
||||
storagePools = listBy(dcId, podId, clusterId, ScopeType.HOST, keyword);
|
||||
|
||||
if (validateTagRule) {
|
||||
storagePools = getPoolsWithoutTagRule(storagePools);
|
||||
|
|
@ -583,11 +596,19 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
|
|||
|
||||
@Override
|
||||
public List<StoragePoolVO> findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType) {
|
||||
return findZoneWideStoragePoolsByHypervisor(dataCenterId, hypervisorType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolVO> findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType, String keyword) {
|
||||
QueryBuilder<StoragePoolVO> sc = QueryBuilder.create(StoragePoolVO.class);
|
||||
sc.and(sc.entity().getDataCenterId(), Op.EQ, dataCenterId);
|
||||
sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
|
||||
sc.and(sc.entity().getScope(), Op.EQ, ScopeType.ZONE);
|
||||
sc.and(sc.entity().getHypervisor(), Op.EQ, hypervisorType);
|
||||
if (keyword != null) {
|
||||
sc.and(sc.entity().getName(), Op.LIKE, "%" + keyword + "%");
|
||||
}
|
||||
return sc.list();
|
||||
}
|
||||
|
||||
|
|
@ -612,10 +633,13 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolVO> findPoolsInClusters(List<Long> clusterIds) {
|
||||
public List<StoragePoolVO> findPoolsInClusters(List<Long> clusterIds, String keyword) {
|
||||
SearchCriteria<StoragePoolVO> sc = ClustersSearch.create();
|
||||
sc.setParameters("clusterIds", clusterIds.toArray());
|
||||
sc.setParameters("status", StoragePoolStatus.Up);
|
||||
if (keyword != null) {
|
||||
sc.addAnd("name", Op.LIKE, "%" + keyword + "%");
|
||||
}
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,3 +18,13 @@
|
|||
--;
|
||||
-- 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
|
||||
// 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.host;
|
||||
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import org.junit.Before;
|
||||
|
||||
public class HostVOTest {
|
||||
HostVO host;
|
||||
ServiceOfferingVO offering;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
host = new HostVO();
|
||||
offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0,
|
||||
false, "TestSO", false,VirtualMachine.Type.User,false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSO() {
|
||||
assertFalse(host.checkHostServiceOfferingTags(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoTag() {
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRightTag() {
|
||||
host.setHostTags(Arrays.asList("tag1","tag2"), false);
|
||||
offering.setHostTag("tag2,tag1");
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongTag() {
|
||||
host.setHostTags(Arrays.asList("tag1","tag2"), false);
|
||||
offering.setHostTag("tag2,tag4");
|
||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkHostServiceOfferingTagsTestRuleTagWithServiceTagThatMatches() {
|
||||
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
||||
offering.setHostTag("A");
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkHostServiceOfferingTagsTestRuleTagWithServiceTagThatDoesNotMatch() {
|
||||
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
||||
offering.setHostTag("B");
|
||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkHostServiceOfferingTagsTestRuleTagWithNullServiceTag() {
|
||||
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
||||
offering.setHostTag(null);
|
||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
}
|
||||
// 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.host;
|
||||
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class HostVOTest {
|
||||
HostVO host;
|
||||
ServiceOfferingVO offering;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
host = new HostVO();
|
||||
offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0,
|
||||
false, "TestSO", false,VirtualMachine.Type.User,false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSO() {
|
||||
assertFalse(host.checkHostServiceOfferingTags(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoTag() {
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRightTag() {
|
||||
host.setHostTags(Arrays.asList("tag1","tag2"), false);
|
||||
offering.setHostTag("tag2,tag1");
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongTag() {
|
||||
host.setHostTags(Arrays.asList("tag1","tag2"), false);
|
||||
offering.setHostTag("tag2,tag4");
|
||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkHostServiceOfferingTagsTestRuleTagWithServiceTagThatMatches() {
|
||||
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
||||
offering.setHostTag("A");
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkHostServiceOfferingTagsTestRuleTagWithServiceTagThatDoesNotMatch() {
|
||||
host.setHostTags(List.of("tags[0] == 'A'"), true);
|
||||
offering.setHostTag("B");
|
||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,16 +104,20 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||
return false;
|
||||
}
|
||||
|
||||
protected abstract List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck);
|
||||
protected abstract List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck, String keyword);
|
||||
|
||||
@Override
|
||||
public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
return allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo, false);
|
||||
return allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo, false, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck) {
|
||||
List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid, returnUpTo, bypassStorageTypeCheck);
|
||||
return allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo, bypassStorageTypeCheck, null);
|
||||
}
|
||||
|
||||
public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck, String keyword) {
|
||||
List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid, returnUpTo, bypassStorageTypeCheck, keyword);
|
||||
return reorderPools(pools, vmProfile, plan, dskCh);
|
||||
}
|
||||
|
||||
|
|
@ -304,10 +308,14 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||
return false;
|
||||
}
|
||||
|
||||
Volume 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;
|
||||
Volume volume = null;
|
||||
boolean isTempVolume = dskCh.getVolumeId() == Volume.DISK_OFFERING_SUITABILITY_CHECK_VOLUME_ID;
|
||||
if (!isTempVolume) {
|
||||
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())) {
|
||||
|
|
@ -332,8 +340,10 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||
}
|
||||
|
||||
try {
|
||||
boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolCompliantWithStoragePolicy(requestVolumeDiskProfilePairs, pool);
|
||||
if (!isStoragePoolStoragepolicyComplaince) {
|
||||
boolean isStoragePoolStoragePolicyCompliance = isTempVolume ?
|
||||
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));
|
||||
return false;
|
||||
}
|
||||
|
|
@ -342,7 +352,11 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat
|
|||
DiskOfferingDao _diskOfferingDao;
|
||||
|
||||
@Override
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck) {
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck, String keyword) {
|
||||
logStartOfSearch(dskCh, vmProfile, plan, returnUpTo, bypassStorageTypeCheck);
|
||||
|
||||
if (!bypassStorageTypeCheck && dskCh.useLocalStorage()) {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAl
|
|||
boolean _storagePoolCleanupEnabled;
|
||||
|
||||
@Override
|
||||
public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck) {
|
||||
public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck, String keyword) {
|
||||
logStartOfSearch(dskCh, vmProfile, plan, returnUpTo, bypassStorageTypeCheck);
|
||||
if (!_storagePoolCleanupEnabled) {
|
||||
logger.debug("Storage pool cleanup is not enabled, so GarbageCollectingStoragePoolAllocator is being skipped.");
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
|||
ConfigurationDao _configDao;
|
||||
|
||||
@Override
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck) {
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck, String keyword) {
|
||||
logStartOfSearch(dskCh, vmProfile, plan, returnUpTo, bypassStorageTypeCheck);
|
||||
|
||||
if (!bypassStorageTypeCheck && !dskCh.useLocalStorage()) {
|
||||
|
|
@ -99,7 +99,7 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
|||
return null;
|
||||
}
|
||||
List<StoragePoolVO> availablePools =
|
||||
storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), dskCh.getTags(), true);
|
||||
storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), dskCh.getTags(), true, keyword);
|
||||
availablePools.addAll(storagePoolJoinDao.findStoragePoolByScopeAndRuleTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), ScopeType.HOST, List.of(dskCh.getTags())));
|
||||
for (StoragePoolVO pool : availablePools) {
|
||||
if (suitablePools.size() == returnUpTo) {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
|||
private CapacityDao capacityDao;
|
||||
|
||||
@Override
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck) {
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck, String keyword) {
|
||||
logStartOfSearch(dskCh, vmProfile, plan, returnUpTo, bypassStorageTypeCheck);
|
||||
|
||||
if (!bypassStorageTypeCheck && dskCh.useLocalStorage()) {
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ public class AbstractStoragePoolAllocatorTest {
|
|||
class MockStorapoolAllocater extends AbstractStoragePoolAllocator {
|
||||
|
||||
@Override
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, DeploymentPlanner.ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck) {
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, DeploymentPlanner.ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck, String keyword) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ import com.cloud.storage.Volume;
|
|||
import com.cloud.storage.Volume.State;
|
||||
import com.cloud.storage.VolumeDetailVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
|
|
@ -206,6 +207,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
private SnapshotApiService snapshotApiService;
|
||||
@Inject
|
||||
private PassphraseDao passphraseDao;
|
||||
@Inject
|
||||
private DiskOfferingDao diskOfferingDao;
|
||||
|
||||
public VolumeServiceImpl() {
|
||||
}
|
||||
|
|
@ -1610,8 +1613,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
|
||||
if (vol.getAttachedVM() == null || vol.getAttachedVM().getType() == VirtualMachine.Type.User) {
|
||||
// Decrement the resource count for volumes and primary storage belonging user VM's only
|
||||
_resourceLimitMgr.decrementResourceCount(vol.getAccountId(), ResourceType.volume, vol.isDisplay());
|
||||
_resourceLimitMgr.decrementResourceCount(vol.getAccountId(), ResourceType.primary_storage, vol.isDisplay(), new Long(vol.getSize()));
|
||||
_resourceLimitMgr.decrementVolumeResourceCount(vol.getAccountId(), vol.isDisplay(), vol.getSize(), diskOfferingDao.findById(vol.getDiskOfferingId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ import java.util.List;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.ListUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
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.offering.ServiceOffering;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
|
|
@ -57,6 +60,27 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
|
|||
@Inject
|
||||
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,
|
||||
ExcludeList avoid, List<? extends Host> hosts, int returnUpTo,
|
||||
boolean considerReservedCapacity) {
|
||||
|
|
@ -70,30 +94,34 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
|
|||
if (type == Host.Type.Storage) {
|
||||
return suitableHosts;
|
||||
}
|
||||
String hostTag = offering.getHostTag();
|
||||
if (hostTag != null) {
|
||||
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 offeringHostTag = offering.getHostTag();
|
||||
VMTemplateVO template = (VMTemplateVO)vmProfile.getTemplate();
|
||||
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 {
|
||||
logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
||||
}
|
||||
if (hosts != null) {
|
||||
// retain all computing hosts, regardless of whether they support routing...it's random after all
|
||||
hostsCopy = new ArrayList<Host>(hosts);
|
||||
if (hostTag != null) {
|
||||
hostsCopy.retainAll(_hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag));
|
||||
if (ObjectUtils.anyNotNull(offeringHostTag, templateTag)) {
|
||||
hostsCopy.retainAll(listHostsByTags(type, dcId, podId, clusterId, offeringHostTag, templateTag));
|
||||
} else {
|
||||
hostsCopy.retainAll(_hostDao.listAllHostsThatHaveNoRuleTag(type, clusterId, podId, dcId));
|
||||
}
|
||||
} else {
|
||||
// list all computing hosts, regardless of whether they support routing...it's random after all
|
||||
hostsCopy = new ArrayList<HostVO>();
|
||||
if (hostTag != null) {
|
||||
hostsCopy = _hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag);
|
||||
if (offeringHostTag != null) {
|
||||
hostsCopy = listHostsByTags(type, dcId, podId, clusterId, offeringHostTag, templateTag);
|
||||
} else {
|
||||
hostsCopy = _hostDao.listAllHostsThatHaveNoRuleTag(type, clusterId, podId, dcId);
|
||||
}
|
||||
}
|
||||
hostsCopy = ListUtils.union(hostsCopy, _hostDao.findHostsWithTagRuleThatMatchComputeOferringTags(hostTag));
|
||||
hostsCopy = ListUtils.union(hostsCopy, _hostDao.findHostsWithTagRuleThatMatchComputeOferringTags(offeringHostTag));
|
||||
|
||||
if (hostsCopy.isEmpty()) {
|
||||
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.PrimaryStorageDownloadAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
import com.cloud.agent.api.storage.ResizeVolumeCommand;
|
||||
import com.cloud.utils.component.Manager;
|
||||
|
||||
public interface MockStorageManager extends Manager {
|
||||
|
|
@ -113,4 +114,6 @@ public interface MockStorageManager extends Manager {
|
|||
public UploadStatusAnswer getUploadStatus(UploadStatusCommand 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.PrimaryStorageDownloadAnswer;
|
||||
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.NfsTO;
|
||||
import com.cloud.agent.api.to.StorageFilerTO;
|
||||
|
|
@ -1307,4 +1309,32 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
|
|||
|
||||
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.ListVolumeCommand;
|
||||
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.ConfigureSimulatorCmd;
|
||||
import com.cloud.api.commands.ConfigureSimulatorHAProviderState;
|
||||
|
|
@ -440,6 +441,8 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage
|
|||
answer = _mockVmMgr.fence((FenceCommand)cmd);
|
||||
} else if (cmd instanceof HandleConfigDriveIsoCommand) {
|
||||
answer = _mockStorageMgr.handleConfigDriveIso((HandleConfigDriveIsoCommand)cmd);
|
||||
} else if (cmd instanceof ResizeVolumeCommand) {
|
||||
answer = _mockStorageMgr.handleResizeVolume((ResizeVolumeCommand)cmd);
|
||||
} else if (cmd instanceof GetRouterAlertsCommand
|
||||
|| cmd instanceof VpnUsersCfgCommand
|
||||
|| cmd instanceof RemoteAccessVpnCfgCommand
|
||||
|
|
|
|||
|
|
@ -25,15 +25,9 @@ import java.util.stream.Collectors;
|
|||
|
||||
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.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.alert.AlertManager;
|
||||
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.capacity.Capacity;
|
||||
import com.cloud.capacity.CapacityManager;
|
||||
import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.CapacityState;
|
||||
import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.capacity.dao.CapacityDaoImpl;
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.configuration.dao.ResourceCountDao;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.DedicatedResourceVO;
|
||||
import com.cloud.dc.Vlan;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.DataCenterIpAddressDao;
|
||||
import com.cloud.dc.dao.DedicatedResourceDao;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostStats;
|
||||
import com.cloud.host.HostTagVO;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
|
|
@ -63,7 +62,8 @@ import com.cloud.storage.StorageStats;
|
|||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
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.component.Manager;
|
||||
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,
|
||||
Resource.ResourceType.memory);
|
||||
Resource.ResourceType.memory, null);
|
||||
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,
|
||||
Resource.ResourceType.primary_storage);
|
||||
Resource.ResourceType.primary_storage, null);
|
||||
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(cpuUsed, domain.getPath(), Resource.ResourceType.cpu.getName()));
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import com.cloud.vm.VirtualMachineProfile;
|
|||
public class RandomStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
|
||||
@Override
|
||||
public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck) {
|
||||
public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean bypassStorageTypeCheck, String keyword) {
|
||||
logStartOfSearch(dskCh, vmProfile, plan, returnUpTo, bypassStorageTypeCheck);
|
||||
|
||||
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
|||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
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.InstanceGroupResponse;
|
||||
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.ProjectInvitationResponse;
|
||||
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.dao.DiskOfferingDetailsDao;
|
||||
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.StoragePoolVO;
|
||||
|
||||
|
|
@ -337,6 +341,7 @@ import com.cloud.vm.UserVmManager;
|
|||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.VmStats;
|
||||
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.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 {
|
||||
private static ManagementServer s_ms;
|
||||
static AsyncJobManager s_asyncMgr;
|
||||
|
|
@ -489,6 +490,7 @@ public class ApiDBUtils {
|
|||
static ObjectStoreDao s_objectStoreDao;
|
||||
|
||||
static BucketDao s_bucketDao;
|
||||
static VirtualMachineManager s_virtualMachineManager;
|
||||
|
||||
@Inject
|
||||
private ManagementServer ms;
|
||||
|
|
@ -752,6 +754,8 @@ public class ApiDBUtils {
|
|||
private ObjectStoreDao objectStoreDao;
|
||||
@Inject
|
||||
private BucketDao bucketDao;
|
||||
@Inject
|
||||
private VirtualMachineManager virtualMachineManager;
|
||||
|
||||
@PostConstruct
|
||||
void init() {
|
||||
|
|
@ -886,6 +890,7 @@ public class ApiDBUtils {
|
|||
s_resourceManagerUtil = resourceManagerUtil;
|
||||
s_objectStoreDao = objectStoreDao;
|
||||
s_bucketDao = bucketDao;
|
||||
s_virtualMachineManager = virtualMachineManager;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////////////
|
||||
|
|
@ -937,7 +942,7 @@ public class ApiDBUtils {
|
|||
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) {
|
||||
|
|
@ -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) {
|
||||
return s_resourceLimitMgr.findCorrectResourceLimitForAccount(accountId, limit, type);
|
||||
}
|
||||
|
|
@ -984,7 +979,7 @@ public class ApiDBUtils {
|
|||
return -1;
|
||||
}
|
||||
|
||||
return s_resourceLimitMgr.getResourceCount(account, type);
|
||||
return s_resourceLimitMgr.getResourceCount(account, type, null);
|
||||
}
|
||||
|
||||
public static String getSecurityGroupsNamesForVm(long vmId) {
|
||||
|
|
@ -2098,6 +2093,22 @@ public class ApiDBUtils {
|
|||
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) {
|
||||
return s_diskOfferingJoinDao.newDiskOfferingResponse(offering);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -564,6 +564,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
} else {
|
||||
resourceLimitResponse.setMax(limit.getMax());
|
||||
}
|
||||
resourceLimitResponse.setTag(limit.getTag());
|
||||
resourceLimitResponse.setObjectName("resourcelimit");
|
||||
|
||||
return resourceLimitResponse;
|
||||
|
|
@ -585,7 +586,10 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
|
||||
resourceCountResponse.setResourceType(resourceCount.getType());
|
||||
resourceCountResponse.setResourceCount(resourceCount.getCount());
|
||||
resourceCountResponse.setObjectName("resourcecount");
|
||||
resourceCountResponse.setObjectName(ApiConstants.RESOURCE_COUNT);
|
||||
if (StringUtils.isNotEmpty(resourceCount.getTag())) {
|
||||
resourceCountResponse.setTag(resourceCount.getTag());
|
||||
}
|
||||
return resourceCountResponse;
|
||||
}
|
||||
|
||||
|
|
@ -2015,6 +2019,21 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
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
|
||||
public List<CapacityResponse> createCapacityResponse(List<? extends Capacity> result, DecimalFormat format) {
|
||||
List<CapacityResponse> capacityResponses = new ArrayList<CapacityResponse>();
|
||||
|
|
@ -2060,13 +2079,18 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
} else {
|
||||
capacityResponse.setPercentUsed(format.format(0L));
|
||||
}
|
||||
capacityResponse.setTag(summedCapacity.getTag());
|
||||
|
||||
capacityResponse.setObjectName("capacity");
|
||||
capacityResponses.add(capacityResponse);
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
float capacityUsed = 0;
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ import com.cloud.storage.SnapshotVO;
|
|||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Storage.TemplateType;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.StoragePoolTagVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
|
|
@ -521,6 +522,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
|
||||
@Inject
|
||||
private ResourceIconDao resourceIconDao;
|
||||
@Inject
|
||||
StorageManager storageManager;
|
||||
|
||||
@Inject
|
||||
private ManagementServerHostDao msHostDao;
|
||||
|
|
@ -3153,8 +3156,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
@Override
|
||||
public ListResponse<DiskOfferingResponse> searchForDiskOfferings(ListDiskOfferingsCmd cmd) {
|
||||
Pair<List<DiskOfferingJoinVO>, Integer> result = searchForDiskOfferingsInternal(cmd);
|
||||
ListResponse<DiskOfferingResponse> response = new ListResponse<DiskOfferingResponse>();
|
||||
List<DiskOfferingResponse> offeringResponses = ViewResponseHelper.createDiskOfferingResponse(result.first().toArray(new DiskOfferingJoinVO[result.first().size()]));
|
||||
ListResponse<DiskOfferingResponse> response = new ListResponse<>();
|
||||
List<DiskOfferingResponse> offeringResponses = ViewResponseHelper.createDiskOfferingResponses(cmd.getVirtualMachineId(), result.first());
|
||||
response.setResponses(offeringResponses, result.second());
|
||||
return response;
|
||||
}
|
||||
|
|
@ -3189,6 +3192,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
Long storagePoolId = cmd.getStoragePoolId();
|
||||
Boolean encrypt = cmd.getEncrypt();
|
||||
String storageType = cmd.getStorageType();
|
||||
final Long vmId = cmd.getVirtualMachineId();
|
||||
|
||||
// Keeping this logic consistent with domain specific zones
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
String[] requiredTagsArray = new String[0];
|
||||
if (CollectionUtils.isNotEmpty(result.first()) && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.valueIn(zoneId)) {
|
||||
|
|
@ -3354,6 +3368,24 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
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) {
|
||||
// Note
|
||||
// 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();
|
||||
Boolean encryptRoot = cmd.getEncryptRoot();
|
||||
String storageType = cmd.getStorageType();
|
||||
final Long templateId = cmd.getTemplateId();
|
||||
|
||||
final Account owner = accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
|
||||
SearchCriteria<ServiceOfferingJoinVO> sc = _srvOfferingJoinDao.createSearchCriteria();
|
||||
|
|
@ -3579,6 +3612,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
sc.addAnd("domainId", SearchCriteria.Op.SC, scc);
|
||||
}
|
||||
|
||||
List<String> hostTags = getHostTagsFromTemplateForServiceOfferingsListing(caller, templateId);
|
||||
|
||||
if (currentVmOffering != null) {
|
||||
DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(currentVmOffering.getDiskOfferingId());
|
||||
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);
|
||||
}
|
||||
|
||||
List<String> hostTags = com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getHostTag());
|
||||
if (!hostTags.isEmpty()) {
|
||||
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);
|
||||
List<String> offeringHostTags = com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getHostTag());
|
||||
if (!offeringHostTags.isEmpty()) {
|
||||
hostTags.addAll(offeringHostTags);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -557,12 +557,8 @@ public class ViewResponseHelper {
|
|||
return respList;
|
||||
}
|
||||
|
||||
public static List<DiskOfferingResponse> createDiskOfferingResponse(DiskOfferingJoinVO... offerings) {
|
||||
List<DiskOfferingResponse> respList = new ArrayList<DiskOfferingResponse>();
|
||||
for (DiskOfferingJoinVO vt : offerings) {
|
||||
respList.add(ApiDBUtils.newDiskOfferingResponse(vt));
|
||||
}
|
||||
return respList;
|
||||
public static List<DiskOfferingResponse> createDiskOfferingResponses(Long vmId, List<DiskOfferingJoinVO> offerings) {
|
||||
return ApiDBUtils.newDiskOfferingResponses(vmId, 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.Set;
|
||||
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||
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.uservm.UserVm;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
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> 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.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.query.QueryService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
|
@ -679,4 +680,30 @@ public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJo
|
|||
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.StoragePoolHostDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
|
|
@ -730,10 +731,11 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||
|
||||
protected boolean checkVmProfileAndHost(final VirtualMachineProfile vmProfile, final HostVO host) {
|
||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||
if (offering.getHostTag() != null) {
|
||||
VirtualMachineTemplate template = vmProfile.getTemplate();
|
||||
if (offering.getHostTag() != null || template.getTemplateTag() != null) {
|
||||
_hostDao.loadHostTags(host);
|
||||
if (!host.checkHostServiceOfferingTags(offering)) {
|
||||
logger.debug("Service Offering host tag does not match the last host of this VM");
|
||||
if (!host.checkHostServiceOfferingAndTemplateTags(offering, template)) {
|
||||
logger.debug("Service Offering host tag or template tag does not match the last host of this VM");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.util.Map;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.network.router.VirtualNetworkApplianceManager;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
|
||||
import com.cloud.configuration.Config;
|
||||
|
|
@ -169,18 +170,24 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu
|
|||
assert nic.getTrafficType() == TrafficType.Control;
|
||||
HypervisorType hType = vm.getHypervisorType();
|
||||
if ( ( (hType == HypervisorType.VMware) || (hType == HypervisorType.Hyperv) )&& isRouterVm(vm)) {
|
||||
if (!VirtualNetworkApplianceManager.RemoveControlIpOnStop.valueIn(vm.getVirtualMachine().getDataCenterId())) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("not releasing %s from %s with reservationId %s, as systemvm.release.control.ip.on.stop is set to false for the data center.", nic, vm, reservationId));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
long dcId = vm.getVirtualMachine().getDataCenterId();
|
||||
DataCenterVO dcVo = _dcDao.findById(dcId);
|
||||
if (dcVo.getNetworkType() != NetworkType.Basic) {
|
||||
super.release(nic, vm, reservationId);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Released nic: " + nic);
|
||||
logger.debug(String.format("Released nic: %s for vm %s", nic, vm));
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
nic.deallocate();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Released nic: " + nic);
|
||||
logger.debug(String.format("Released nic: %s for vm %s", nic, vm));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -190,7 +197,7 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu
|
|||
|
||||
nic.deallocate();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Released nic: " + nic);
|
||||
logger.debug(String.format("Released nic: %s for vm %s", nic, vm));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
|
|||
nic.deallocate();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Released nic: " + nic);
|
||||
logger.debug(String.format("Released nic: %s for vm %s", nic, vm));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue