From baf7e0a6c6b834471a47a77669f7001fd263b4dd Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Sun, 23 Jun 2019 20:04:01 +0530 Subject: [PATCH] server, api: allowing domain(s), zone(s) overwrite while updating offerings 'domainid' and 'zoneid' param of update*Offering APIs has been made string type. For associating multiple domains, zones to an offering, a comma-separated list of domains and zones can be passes. To make a domain specific offering public, a value of 'public' can be given for domainid param. To make a zone specific offering available for all zones, a value of 'all' can be given for zoneid param. Signed-off-by: Abhishek Kumar --- .../configuration/ConfigurationService.java | 42 ++++++ .../network/vpc/VpcProvisioningService.java | 13 ++ .../network/UpdateNetworkOfferingCmd.java | 91 +++++++++---- .../admin/offering/UpdateDiskOfferingCmd.java | 89 ++++++++---- .../offering/UpdateServiceOfferingCmd.java | 88 ++++++++---- .../admin/vpc/UpdateVPCOfferingCmd.java | 91 +++++++++---- .../ConfigurationManagerImpl.java | 128 ++++++++++++++---- .../com/cloud/network/vpc/VpcManagerImpl.java | 33 ++++- .../vpc/MockConfigurationManagerImpl.java | 36 +++++ 9 files changed, 480 insertions(+), 131 deletions(-) diff --git a/api/src/main/java/com/cloud/configuration/ConfigurationService.java b/api/src/main/java/com/cloud/configuration/ConfigurationService.java index 5af44ed18f4..8b419027f70 100644 --- a/api/src/main/java/com/cloud/configuration/ConfigurationService.java +++ b/api/src/main/java/com/cloud/configuration/ConfigurationService.java @@ -106,6 +106,20 @@ public interface ConfigurationService { */ boolean deleteServiceOffering(DeleteServiceOfferingCmd cmd); + /** + * Retrieve ID of domains for a service offering + * + * @param serviceOfferingId + */ + List getServiceOfferingDomains(Long serviceOfferingId); + + /** + * Retrieve ID of domains for a service offering + * + * @param serviceOfferingId + */ + List getServiceOfferingZones(Long serviceOfferingId); + /** * Updates a disk offering * @@ -139,6 +153,20 @@ public interface ConfigurationService { */ DiskOffering createDiskOffering(CreateDiskOfferingCmd cmd); + /** + * Retrieve ID of domains for a disk offering + * + * @param diskOfferingId + */ + List getDiskOfferingDomains(Long diskOfferingId); + + /** + * Retrieve ID of domains for a disk offering + * + * @param diskOfferingId + */ + List getDiskOfferingZones(Long diskOfferingId); + /** * Creates a new pod based on the parameters specified in the command object * @@ -269,6 +297,20 @@ public interface ConfigurationService { boolean deleteNetworkOffering(DeleteNetworkOfferingCmd cmd); + /** + * Retrieve ID of domains for a network offering + * + * @param networkOfferingId + */ + List getNetworkOfferingDomains(Long networkOfferingId); + + /** + * Retrieve ID of domains for a network offering + * + * @param networkOfferingId + */ + List getNetworkOfferingZones(Long networkOfferingId); + Account getVlanAccount(long vlanId); Domain getVlanDomain(long vlanId); diff --git a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java index e5cd477c61c..035e5fd5944 100644 --- a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java +++ b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java @@ -51,4 +51,17 @@ public interface VpcProvisioningService { */ public VpcOffering updateVpcOffering(UpdateVPCOfferingCmd cmd); + /** + * Retrieve ID of domains for a VPC offering + * + * @param vpcOfferingId + */ + List getVpcOfferingDomains(Long vpcOfferingId); + + /** + * Retrieve ID of domains for a VPC offering + * + * @param vpcOfferingId + */ + List getVpcOfferingZones(Long vpcOfferingId); } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java index ee391a51190..83c82741ab2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java @@ -16,14 +16,8 @@ // under the License. package org.apache.cloudstack.api.command.admin.network; -import java.util.LinkedHashSet; +import java.util.ArrayList; import java.util.List; -import java.util.Set; - -import org.apache.cloudstack.api.response.DomainResponse; -import org.apache.cloudstack.api.response.ZoneResponse; -import org.apache.commons.collections.CollectionUtils; -import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -32,9 +26,14 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.NetworkOfferingResponse; +import org.apache.log4j.Logger; +import com.cloud.dc.DataCenter; +import com.cloud.domain.Domain; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; +import com.google.common.base.Strings; @APICommand(name = "updateNetworkOffering", description = "Updates a network offering.", responseObject = NetworkOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @@ -80,19 +79,15 @@ public class UpdateNetworkOfferingCmd extends BaseCmd { private String tags; @Parameter(name = ApiConstants.DOMAIN_ID, - type = CommandType.LIST, - collectionType = CommandType.UUID, - entityType = DomainResponse.class, - description = "the ID of the containing domain(s), null for public offerings") - private List domainIds; + type = CommandType.STRING, + description = "the ID of the containing domain(s) as comma separated string, public for public offerings") + private String domainIds; @Parameter(name = ApiConstants.ZONE_ID, - type = CommandType.LIST, - collectionType = CommandType.UUID, - entityType = ZoneResponse.class, - description = "the ID of the containing zone(s), null for public offerings", + type = CommandType.STRING, + description = "the ID of the containing zone(s) as comma separated string, all for all zones offerings", since = "4.13") - private List zoneIds; + private String zoneIds; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -135,21 +130,63 @@ public class UpdateNetworkOfferingCmd extends BaseCmd { } public List getDomainIds() { - if (CollectionUtils.isNotEmpty(domainIds)) { - Set set = new LinkedHashSet<>(domainIds); - domainIds.clear(); - domainIds.addAll(set); + List validDomainIds = new ArrayList<>(); + if (!Strings.isNullOrEmpty(domainIds)) { + if (domainIds.contains(",")) { + String[] domains = domainIds.split(","); + for (String domain : domains) { + Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim()); + if (validDomain != null) { + validDomainIds.add(validDomain.getId()); + } else { + throw new InvalidParameterValueException("Failed to create network offering because invalid domain has been specified."); + } + } + } else { + domainIds = domainIds.trim(); + if (!domainIds.matches("public")) { + Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim()); + if (validDomain != null) { + validDomainIds.add(validDomain.getId()); + } else { + throw new InvalidParameterValueException("Failed to create network offering because invalid domain has been specified."); + } + } + } + } else { + validDomainIds.addAll(_configService.getNetworkOfferingDomains(id)); } - return domainIds; + return validDomainIds; } public List getZoneIds() { - if (CollectionUtils.isNotEmpty(zoneIds)) { - Set set = new LinkedHashSet<>(zoneIds); - zoneIds.clear(); - zoneIds.addAll(set); + List validZoneIds = new ArrayList<>(); + if (!Strings.isNullOrEmpty(zoneIds)) { + if (zoneIds.contains(",")) { + String[] zones = zoneIds.split(","); + for (String zone : zones) { + DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim()); + if (validZone != null) { + validZoneIds.add(validZone.getId()); + } else { + throw new InvalidParameterValueException("Failed to create network offering because invalid zone has been specified."); + } + } + } else { + zoneIds = zoneIds.trim(); + if (!zoneIds.matches("all")) { + DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim()); + if (validZone != null) { + validZoneIds.add(validZone.getId()); + } else { + throw new InvalidParameterValueException("Failed to create network offering because invalid zone has been specified."); + } + } + } + } else { + validZoneIds.addAll(_configService.getNetworkOfferingZones(id)); } - return zoneIds; + return validZoneIds; } ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java index 8e8ff2b4385..903695307bb 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java @@ -16,9 +16,8 @@ // under the License. package org.apache.cloudstack.api.command.admin.offering; -import java.util.LinkedHashSet; +import java.util.ArrayList; import java.util.List; -import java.util.Set; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -27,13 +26,14 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.DiskOfferingResponse; -import org.apache.cloudstack.api.response.DomainResponse; -import org.apache.cloudstack.api.response.ZoneResponse; -import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; +import com.cloud.dc.DataCenter; +import com.cloud.domain.Domain; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.offering.DiskOffering; import com.cloud.user.Account; +import com.google.common.base.Strings; @APICommand(name = "updateDiskOffering", description = "Updates a disk offering.", responseObject = DiskOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @@ -66,19 +66,16 @@ public class UpdateDiskOfferingCmd extends BaseCmd { private Boolean displayOffering; @Parameter(name = ApiConstants.DOMAIN_ID, - type = CommandType.LIST, - collectionType = CommandType.UUID, - entityType = DomainResponse.class, - description = "the ID of the containing domain(s), null for public offerings") - private List domainIds; + type = CommandType.STRING, + description = "the ID of the containing domain(s) as comma separated string, public for public offerings", + since = "4.13") + private String domainIds; @Parameter(name = ApiConstants.ZONE_ID, - type = CommandType.LIST, - collectionType = CommandType.UUID, - entityType = ZoneResponse.class, - description = "the ID of the containing zone(s), null for public offerings", + type = CommandType.STRING, + description = "the ID of the containing zone(s) as comma separated string, all for all zones offerings", since = "4.13") - private List zoneIds; + private String zoneIds; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -105,21 +102,63 @@ public class UpdateDiskOfferingCmd extends BaseCmd { } public List getDomainIds() { - if (CollectionUtils.isNotEmpty(domainIds)) { - Set set = new LinkedHashSet<>(domainIds); - domainIds.clear(); - domainIds.addAll(set); + List validDomainIds = new ArrayList<>(); + if (!Strings.isNullOrEmpty(domainIds)) { + if (domainIds.contains(",")) { + String[] domains = domainIds.split(","); + for (String domain : domains) { + Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim()); + if (validDomain != null) { + validDomainIds.add(validDomain.getId()); + } else { + throw new InvalidParameterValueException("Failed to create disk offering because invalid domain has been specified."); + } + } + } else { + domainIds = domainIds.trim(); + if (!domainIds.matches("public")) { + Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim()); + if (validDomain != null) { + validDomainIds.add(validDomain.getId()); + } else { + throw new InvalidParameterValueException("Failed to create disk offering because invalid domain has been specified."); + } + } + } + } else { + validDomainIds.addAll(_configService.getDiskOfferingDomains(id)); } - return domainIds; + return validDomainIds; } public List getZoneIds() { - if (CollectionUtils.isNotEmpty(zoneIds)) { - Set set = new LinkedHashSet<>(zoneIds); - zoneIds.clear(); - zoneIds.addAll(set); + List validZoneIds = new ArrayList<>(); + if (!Strings.isNullOrEmpty(zoneIds)) { + if (zoneIds.contains(",")) { + String[] zones = zoneIds.split(","); + for (String zone : zones) { + DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim()); + if (validZone != null) { + validZoneIds.add(validZone.getId()); + } else { + throw new InvalidParameterValueException("Failed to create disk offering because invalid zone has been specified."); + } + } + } else { + zoneIds = zoneIds.trim(); + if (!zoneIds.matches("all")) { + DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim()); + if (validZone != null) { + validZoneIds.add(validZone.getId()); + } else { + throw new InvalidParameterValueException("Failed to create disk offering because invalid zone has been specified."); + } + } + } + } else { + validZoneIds.addAll(_configService.getDiskOfferingZones(id)); } - return zoneIds; + return validZoneIds; } ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java index c2e11e5fe45..43a0666e934 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java @@ -16,9 +16,8 @@ // under the License. package org.apache.cloudstack.api.command.admin.offering; -import java.util.LinkedHashSet; +import java.util.ArrayList; import java.util.List; -import java.util.Set; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -26,14 +25,15 @@ import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; -import org.apache.cloudstack.api.response.ZoneResponse; -import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; +import com.cloud.dc.DataCenter; +import com.cloud.domain.Domain; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; +import com.google.common.base.Strings; @APICommand(name = "updateServiceOffering", description = "Updates a service offering.", responseObject = ServiceOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @@ -61,19 +61,15 @@ public class UpdateServiceOfferingCmd extends BaseCmd { private Integer sortKey; @Parameter(name = ApiConstants.DOMAIN_ID, - type = CommandType.LIST, - collectionType = CommandType.UUID, - entityType = DomainResponse.class, - description = "the ID of the containing domain(s), null for public offerings") - private List domainIds; + type = CommandType.STRING, + description = "the ID of the containing domain(s) as comma separated string, public for public offerings") + private String domainIds; @Parameter(name = ApiConstants.ZONE_ID, - type = CommandType.LIST, - collectionType = CommandType.UUID, - entityType = ZoneResponse.class, - description = "the ID of the containing zone(s), null for public offerings", + type = CommandType.STRING, + description = "the ID of the containing zone(s) as comma separated string, all for all zones offerings", since = "4.13") - private List zoneIds; + private String zoneIds; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -96,21 +92,63 @@ public class UpdateServiceOfferingCmd extends BaseCmd { } public List getDomainIds() { - if (CollectionUtils.isNotEmpty(domainIds)) { - Set set = new LinkedHashSet<>(domainIds); - domainIds.clear(); - domainIds.addAll(set); + List validDomainIds = new ArrayList<>(); + if (!Strings.isNullOrEmpty(domainIds)) { + if (domainIds.contains(",")) { + String[] domains = domainIds.split(","); + for (String domain : domains) { + Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim()); + if (validDomain != null) { + validDomainIds.add(validDomain.getId()); + } else { + throw new InvalidParameterValueException("Failed to create service offering because invalid domain has been specified."); + } + } + } else { + domainIds = domainIds.trim(); + if (!domainIds.matches("public")) { + Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim()); + if (validDomain != null) { + validDomainIds.add(validDomain.getId()); + } else { + throw new InvalidParameterValueException("Failed to create service offering because invalid domain has been specified."); + } + } + } + } else { + validDomainIds.addAll(_configService.getServiceOfferingDomains(id)); } - return domainIds; + return validDomainIds; } public List getZoneIds() { - if (CollectionUtils.isNotEmpty(zoneIds)) { - Set set = new LinkedHashSet<>(zoneIds); - zoneIds.clear(); - zoneIds.addAll(set); + List validZoneIds = new ArrayList<>(); + if (!Strings.isNullOrEmpty(zoneIds)) { + if (zoneIds.contains(",")) { + String[] zones = zoneIds.split(","); + for (String zone : zones) { + DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim()); + if (validZone != null) { + validZoneIds.add(validZone.getId()); + } else { + throw new InvalidParameterValueException("Failed to create service offering because invalid zone has been specified."); + } + } + } else { + zoneIds = zoneIds.trim(); + if (!zoneIds.matches("all")) { + DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim()); + if (validZone != null) { + validZoneIds.add(validZone.getId()); + } else { + throw new InvalidParameterValueException("Failed to create service offering because invalid zone has been specified."); + } + } + } + } else { + validZoneIds.addAll(_configService.getServiceOfferingZones(id)); } - return zoneIds; + return validZoneIds; } ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java index aeeb7ae2acb..194d3aa5189 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java @@ -16,14 +16,8 @@ // under the License. package org.apache.cloudstack.api.command.admin.vpc; -import java.util.LinkedHashSet; +import java.util.ArrayList; import java.util.List; -import java.util.Set; - -import org.apache.cloudstack.api.response.DomainResponse; -import org.apache.cloudstack.api.response.ZoneResponse; -import org.apache.commons.collections.CollectionUtils; -import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -32,10 +26,15 @@ import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.VpcOfferingResponse; +import org.apache.log4j.Logger; +import com.cloud.dc.DataCenter; +import com.cloud.domain.Domain; import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.vpc.VpcOffering; import com.cloud.user.Account; +import com.google.common.base.Strings; @APICommand(name = "updateVPCOffering", description = "Updates VPC offering", responseObject = VpcOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @@ -60,19 +59,15 @@ public class UpdateVPCOfferingCmd extends BaseAsyncCmd { private String state; @Parameter(name = ApiConstants.DOMAIN_ID, - type = CommandType.LIST, - collectionType = CommandType.UUID, - entityType = DomainResponse.class, - description = "the ID of the containing domain(s), null for public offerings") - private List domainIds; + type = CommandType.STRING, + description = "the ID of the containing domain(s) as comma separated string, public for public offerings") + private String domainIds; @Parameter(name = ApiConstants.ZONE_ID, - type = CommandType.LIST, - collectionType = CommandType.UUID, - entityType = ZoneResponse.class, - description = "the ID of the containing zone(s), null for public offerings", + type = CommandType.STRING, + description = "the ID of the containing zone(s) as comma separated string, all for all zones offerings", since = "4.13") - private List zoneIds; + private String zoneIds; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -95,21 +90,63 @@ public class UpdateVPCOfferingCmd extends BaseAsyncCmd { } public List getDomainIds() { - if (CollectionUtils.isNotEmpty(domainIds)) { - Set set = new LinkedHashSet<>(domainIds); - domainIds.clear(); - domainIds.addAll(set); + List validDomainIds = new ArrayList<>(); + if (!Strings.isNullOrEmpty(domainIds)) { + if (domainIds.contains(",")) { + String[] domains = domainIds.split(","); + for (String domain : domains) { + Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim()); + if (validDomain != null) { + validDomainIds.add(validDomain.getId()); + } else { + throw new InvalidParameterValueException("Failed to create VPC offering because invalid domain has been specified."); + } + } + } else { + domainIds = domainIds.trim(); + if (!domainIds.matches("public")) { + Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim()); + if (validDomain != null) { + validDomainIds.add(validDomain.getId()); + } else { + throw new InvalidParameterValueException("Failed to create VPC offering because invalid domain has been specified."); + } + } + } + } else { + validDomainIds.addAll(_vpcProvSvc.getVpcOfferingDomains(id)); } - return domainIds; + return validDomainIds; } public List getZoneIds() { - if (CollectionUtils.isNotEmpty(zoneIds)) { - Set set = new LinkedHashSet<>(zoneIds); - zoneIds.clear(); - zoneIds.addAll(set); + List validZoneIds = new ArrayList<>(); + if (!Strings.isNullOrEmpty(zoneIds)) { + if (zoneIds.contains(",")) { + String[] zones = zoneIds.split(","); + for (String zone : zones) { + DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim()); + if (validZone != null) { + validZoneIds.add(validZone.getId()); + } else { + throw new InvalidParameterValueException("Failed to create VPC offering because invalid zone has been specified."); + } + } + } else { + zoneIds = zoneIds.trim(); + if (!zoneIds.matches("all")) { + DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim()); + if (validZone != null) { + validZoneIds.add(validZone.getId()); + } else { + throw new InvalidParameterValueException("Failed to create VPC offering because invalid zone has been specified."); + } + } + } + } else { + validZoneIds.addAll(_vpcProvSvc.getVpcOfferingZones(id)); } - return zoneIds; + return validZoneIds; } ///////////////////////////////////////////////////// diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index f46c6700431..cfc7e129de2 100755 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -25,6 +25,7 @@ import java.sql.PreparedStatement; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -2588,12 +2589,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // Verify input parameters final ServiceOffering offeringHandle = _entityMgr.findById(ServiceOffering.class, id); - List existingDomainIds = _serviceOfferingDetailsDao.findDomainIds(id); - if (offeringHandle == null) { throw new InvalidParameterValueException("unable to find service offering " + id); } + List existingDomainIds = _serviceOfferingDetailsDao.findDomainIds(id); + Collections.sort(existingDomainIds); + + List existingZoneIds = _serviceOfferingDetailsDao.findZoneIds(id); + Collections.sort(existingZoneIds); + // check if valid domain if (CollectionUtils.isNotEmpty(domainIds)) { for (final Long domainId: domainIds) { @@ -2619,15 +2624,21 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // Filter child domains when both parent and child domains are present List filteredDomainIds = filterChildSubDomains(domainIds); + Collections.sort(filteredDomainIds); List filteredZoneIds = new ArrayList<>(); if (CollectionUtils.isNotEmpty(zoneIds)) { filteredZoneIds.addAll(zoneIds); } + Collections.sort(filteredZoneIds); if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) { if (existingDomainIds.isEmpty()) { throw new InvalidParameterValueException(String.format("Unable to update public service offering: %s by user: %s because it is domain-admin", offeringHandle.getUuid(), user.getUuid())); + } else { + if (filteredDomainIds.isEmpty()) { + throw new InvalidParameterValueException(String.format("Unable to update service offering: %s to a public offering by user: %s because it is domain-admin", offeringHandle.getUuid(), user.getUuid())); + } } for (Long domainId : existingDomainIds) { if (!_domainDao.isChildDomain(account.getDomainId(), domainId)) { @@ -2645,7 +2656,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } final boolean updateNeeded = name != null || displayText != null || sortKey != null; - final boolean detailsUpdateNeeded = !filteredDomainIds.isEmpty() || !filteredZoneIds.isEmpty(); + final boolean detailsUpdateNeeded = !filteredDomainIds.equals(existingDomainIds) || !filteredZoneIds.equals(existingZoneIds); if (!updateNeeded && !detailsUpdateNeeded) { return _serviceOfferingDao.findById(id); } @@ -2692,21 +2703,21 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return null; } List detailsVO = new ArrayList<>(); - if(!filteredDomainIds.isEmpty() || !filteredZoneIds.isEmpty()) { + if(detailsUpdateNeeded) { SearchBuilder sb = _serviceOfferingDetailsDao.createSearchBuilder(); sb.and("offeringId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); sb.and("detailName", sb.entity().getName(), SearchCriteria.Op.EQ); sb.done(); SearchCriteria sc = sb.create(); sc.setParameters("offeringId", String.valueOf(id)); - if(!filteredDomainIds.isEmpty()) { + if(!filteredDomainIds.equals(existingDomainIds)) { sc.setParameters("detailName", ApiConstants.DOMAIN_ID); _serviceOfferingDetailsDao.remove(sc); for (Long domainId : filteredDomainIds) { detailsVO.add(new ServiceOfferingDetailsVO(id, ApiConstants.DOMAIN_ID, String.valueOf(domainId), false)); } } - if(!filteredZoneIds.isEmpty()) { + if(!filteredZoneIds.equals(existingZoneIds)) { sc.setParameters("detailName", ApiConstants.ZONE_ID); _serviceOfferingDetailsDao.remove(sc); for (Long zoneId : filteredZoneIds) { @@ -2724,14 +2735,32 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return offering; } + @Override + public List getServiceOfferingDomains(Long serviceOfferingId) { + final ServiceOffering offeringHandle = _entityMgr.findById(ServiceOffering.class, serviceOfferingId); + if (offeringHandle == null) { + throw new InvalidParameterValueException("Unable to find service offering " + serviceOfferingId); + } + return _serviceOfferingDetailsDao.findDomainIds(serviceOfferingId); + } + + @Override + public List getServiceOfferingZones(Long serviceOfferingId) { + final ServiceOffering offeringHandle = _entityMgr.findById(ServiceOffering.class, serviceOfferingId); + if (offeringHandle == null) { + throw new InvalidParameterValueException("Unable to find service offering " + serviceOfferingId); + } + return _serviceOfferingDetailsDao.findZoneIds(serviceOfferingId); + } + protected DiskOfferingVO createDiskOffering(final Long userId, final List domainIds, final List zoneIds, final String name, final String description, final String provisioningType, - final Long numGibibytes, String tags, boolean isCustomized, final boolean localStorageRequired, - final boolean isDisplayOfferingEnabled, final Boolean isCustomizedIops, Long minIops, Long maxIops, - Long bytesReadRate, Long bytesReadRateMax, Long bytesReadRateMaxLength, - Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength, - Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength, - Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength, - final Integer hypervisorSnapshotReserve) { + final Long numGibibytes, String tags, boolean isCustomized, final boolean localStorageRequired, + final boolean isDisplayOfferingEnabled, final Boolean isCustomizedIops, Long minIops, Long maxIops, + Long bytesReadRate, Long bytesReadRateMax, Long bytesReadRateMaxLength, + Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength, + Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength, + Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength, + final Integer hypervisorSnapshotReserve) { long diskSize = 0;// special case for custom disk offerings if (numGibibytes != null && numGibibytes <= 0) { throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb."); @@ -2951,12 +2980,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // Check if diskOffering exists final DiskOffering diskOfferingHandle = _entityMgr.findById(DiskOffering.class, diskOfferingId); - List existingDomainIds = diskOfferingDetailsDao.findDomainIds(diskOfferingId); - if (diskOfferingHandle == null) { throw new InvalidParameterValueException("Unable to find disk offering by id " + diskOfferingId); } + List existingDomainIds = diskOfferingDetailsDao.findDomainIds(diskOfferingId); + Collections.sort(existingDomainIds); + + List existingZoneIds = diskOfferingDetailsDao.findZoneIds(diskOfferingId); + Collections.sort(existingZoneIds); + // check if valid domain if (CollectionUtils.isNotEmpty(domainIds)) { for (final Long domainId: domainIds) { @@ -2986,15 +3019,21 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // Filter child domains when both parent and child domains are present List filteredDomainIds = filterChildSubDomains(domainIds); + Collections.sort(filteredDomainIds); List filteredZoneIds = new ArrayList<>(); if (CollectionUtils.isNotEmpty(zoneIds)) { filteredZoneIds.addAll(zoneIds); } + Collections.sort(filteredZoneIds); if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) { if (existingDomainIds.isEmpty()) { throw new InvalidParameterValueException(String.format("Unable to update public disk offering: %s by user: %s because it is domain-admin", diskOfferingHandle.getUuid(), user.getUuid())); + } else { + if (filteredDomainIds.isEmpty()) { + throw new InvalidParameterValueException(String.format("Unable to update disk offering: %s to a public offering by user: %s because it is domain-admin", diskOfferingHandle.getUuid(), user.getUuid())); + } } for (Long domainId : existingDomainIds) { if (!_domainDao.isChildDomain(account.getDomainId(), domainId)) { @@ -3012,7 +3051,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } final boolean updateNeeded = name != null || displayText != null || sortKey != null || displayDiskOffering != null; - final boolean detailsUpdateNeeded = !filteredDomainIds.isEmpty() || !filteredZoneIds.isEmpty(); + final boolean detailsUpdateNeeded = !filteredDomainIds.equals(existingDomainIds) || !filteredZoneIds.equals(existingZoneIds); if (!updateNeeded && !detailsUpdateNeeded) { return _diskOfferingDao.findById(diskOfferingId); } @@ -3064,21 +3103,21 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return null; } List detailsVO = new ArrayList<>(); - if(!filteredDomainIds.isEmpty() || !filteredZoneIds.isEmpty()) { + if(detailsUpdateNeeded) { SearchBuilder sb = diskOfferingDetailsDao.createSearchBuilder(); sb.and("offeringId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); sb.and("detailName", sb.entity().getName(), SearchCriteria.Op.EQ); sb.done(); SearchCriteria sc = sb.create(); sc.setParameters("offeringId", String.valueOf(diskOfferingId)); - if(!filteredDomainIds.isEmpty()) { + if(!filteredDomainIds.equals(existingDomainIds)) { sc.setParameters("detailName", ApiConstants.DOMAIN_ID); diskOfferingDetailsDao.remove(sc); for (Long domainId : filteredDomainIds) { detailsVO.add(new DiskOfferingDetailVO(diskOfferingId, ApiConstants.DOMAIN_ID, String.valueOf(domainId), false)); } } - if(!filteredZoneIds.isEmpty()) { + if(!filteredZoneIds.equals(existingZoneIds)) { sc.setParameters("detailName", ApiConstants.ZONE_ID); diskOfferingDetailsDao.remove(sc); for (Long zoneId : filteredZoneIds) { @@ -3138,6 +3177,24 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } + @Override + public List getDiskOfferingDomains(Long diskOfferingId) { + final DiskOffering offeringHandle = _entityMgr.findById(DiskOffering.class, diskOfferingId); + if (offeringHandle == null) { + throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId); + } + return diskOfferingDetailsDao.findDomainIds(diskOfferingId); + } + + @Override + public List getDiskOfferingZones(Long diskOfferingId) { + final DiskOffering offeringHandle = _entityMgr.findById(DiskOffering.class, diskOfferingId); + if (offeringHandle == null) { + throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId); + } + return diskOfferingDetailsDao.findZoneIds(diskOfferingId); + } + @Override @ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_DELETE, eventDescription = "deleting service offering") public boolean deleteServiceOffering(final DeleteServiceOfferingCmd cmd) { @@ -5533,11 +5590,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // Verify input parameters final NetworkOfferingVO offeringToUpdate = _networkOfferingDao.findById(id); - List existingDomainIds = networkOfferingDetailsDao.findDomainIds(id); if (offeringToUpdate == null) { throw new InvalidParameterValueException("unable to find network offering " + id); } + List existingDomainIds = networkOfferingDetailsDao.findDomainIds(id); + Collections.sort(existingDomainIds); + + List existingZoneIds = networkOfferingDetailsDao.findZoneIds(id); + Collections.sort(existingZoneIds); + // Don't allow to update system network offering if (offeringToUpdate.isSystemOnly()) { throw new InvalidParameterValueException("Can't update system network offerings"); @@ -5562,11 +5624,13 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // Filter child domains when both parent and child domains are present List filteredDomainIds = filterChildSubDomains(domainIds); + Collections.sort(filteredDomainIds); List filteredZoneIds = new ArrayList<>(); if (CollectionUtils.isNotEmpty(zoneIds)) { filteredZoneIds.addAll(zoneIds); } + Collections.sort(filteredZoneIds); final NetworkOfferingVO offering = _networkOfferingDao.createForUpdate(id); @@ -5658,21 +5722,21 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } List detailsVO = new ArrayList<>(); - if(!filteredDomainIds.isEmpty() || !filteredZoneIds.isEmpty()) { + if(!filteredDomainIds.equals(existingDomainIds) || !filteredZoneIds.equals(existingZoneIds)) { SearchBuilder sb = networkOfferingDetailsDao.createSearchBuilder(); sb.and("offeringId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); sb.and("detailName", sb.entity().getName(), SearchCriteria.Op.EQ); sb.done(); SearchCriteria sc = sb.create(); sc.setParameters("offeringId", String.valueOf(id)); - if(!filteredDomainIds.isEmpty()) { + if(!filteredDomainIds.equals(existingDomainIds)) { sc.setParameters("detailName", ApiConstants.DOMAIN_ID); networkOfferingDetailsDao.remove(sc); for (Long domainId : filteredDomainIds) { detailsVO.add(new NetworkOfferingDetailsVO(id, Detail.domainid, String.valueOf(domainId), false)); } } - if(!filteredZoneIds.isEmpty()) { + if(!filteredZoneIds.equals(existingZoneIds)) { sc.setParameters("detailName", ApiConstants.ZONE_ID); networkOfferingDetailsDao.remove(sc); for (Long zoneId : filteredZoneIds) { @@ -5689,6 +5753,24 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return _networkOfferingDao.findById(id); } + @Override + public List getNetworkOfferingDomains(Long networkOfferingId) { + final NetworkOffering offeringHandle = _entityMgr.findById(NetworkOffering.class, networkOfferingId); + if (offeringHandle == null) { + throw new InvalidParameterValueException("Unable to find network offering " + networkOfferingId); + } + return networkOfferingDetailsDao.findDomainIds(networkOfferingId); + } + + @Override + public List getNetworkOfferingZones(Long networkOfferingId) { + final NetworkOffering offeringHandle = _entityMgr.findById(NetworkOffering.class, networkOfferingId); + if (offeringHandle == null) { + throw new InvalidParameterValueException("Unable to find network offering " + networkOfferingId); + } + return networkOfferingDetailsDao.findZoneIds(networkOfferingId); + } + @Override @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the " + "default zone", async = true) public AccountVO markDefaultZone(final String accountName, final long domainId, final long defaultZoneId) { diff --git a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java index c52ffdeb669..b6d27a3440e 100644 --- a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java @@ -833,19 +833,26 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis // Verify input parameters final VpcOfferingVO offeringToUpdate = _vpcOffDao.findById(vpcOffId); - List existingDomainIds = vpcOfferingDetailsDao.findDomainIds(vpcOffId); if (offeringToUpdate == null) { throw new InvalidParameterValueException("Unable to find vpc offering " + vpcOffId); } + List existingDomainIds = vpcOfferingDetailsDao.findDomainIds(vpcOffId); + Collections.sort(existingDomainIds); + + List existingZoneIds = vpcOfferingDetailsDao.findZoneIds(vpcOffId); + Collections.sort(existingZoneIds); + // Filter child domains when both parent and child domains are present List filteredDomainIds = filterChildSubDomains(domainIds); + Collections.sort(filteredDomainIds); List filteredZoneIds = new ArrayList<>(); if (CollectionUtils.isNotEmpty(zoneIds)) { filteredZoneIds.addAll(zoneIds); } + Collections.sort(filteredZoneIds); final boolean updateNeeded = vpcOfferingName != null || displayText != null || state != null; @@ -877,21 +884,21 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis } } List detailsVO = new ArrayList<>(); - if(!filteredDomainIds.isEmpty() || !filteredZoneIds.isEmpty()) { + if(!filteredDomainIds.equals(existingDomainIds) || !filteredZoneIds.equals(existingZoneIds)) { SearchBuilder sb = vpcOfferingDetailsDao.createSearchBuilder(); sb.and("offeringId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); sb.and("detailName", sb.entity().getName(), SearchCriteria.Op.EQ); sb.done(); SearchCriteria sc = sb.create(); sc.setParameters("offeringId", String.valueOf(vpcOffId)); - if(!filteredDomainIds.isEmpty()) { + if(!filteredDomainIds.equals(existingDomainIds)) { sc.setParameters("detailName", ApiConstants.DOMAIN_ID); vpcOfferingDetailsDao.remove(sc); for (Long zoneId : filteredZoneIds) { detailsVO.add(new VpcOfferingDetailsVO(vpcOffId, ApiConstants.ZONE_ID, String.valueOf(zoneId), false)); } } - if(!filteredZoneIds.isEmpty()) { + if(!filteredZoneIds.equals(existingZoneIds)) { sc.setParameters("detailName", ApiConstants.ZONE_ID); vpcOfferingDetailsDao.remove(sc); for (Long domainId : filteredDomainIds) { @@ -908,6 +915,24 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis return _vpcOffDao.findById(vpcOffId); } + @Override + public List getVpcOfferingDomains(Long vpcOfferingId) { + final VpcOffering offeringHandle = _entityMgr.findById(VpcOffering.class, vpcOfferingId); + if (offeringHandle == null) { + throw new InvalidParameterValueException("Unable to find VPC offering " + vpcOfferingId); + } + return vpcOfferingDetailsDao.findDomainIds(vpcOfferingId); + } + + @Override + public List getVpcOfferingZones(Long vpcOfferingId) { + final VpcOffering offeringHandle = _entityMgr.findById(VpcOffering.class, vpcOfferingId); + if (offeringHandle == null) { + throw new InvalidParameterValueException("Unable to find VPC offering " + vpcOfferingId); + } + return vpcOfferingDetailsDao.findZoneIds(vpcOfferingId); + } + @Override @ActionEvent(eventType = EventTypes.EVENT_VPC_CREATE, eventDescription = "creating vpc", create = true) public Vpc createVpc(final long zoneId, final long vpcOffId, final long vpcOwnerId, final String vpcName, final String displayText, final String cidr, String networkDomain, diff --git a/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java index dcba62ef125..b42996bb02b 100644 --- a/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java +++ b/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java @@ -125,6 +125,18 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu return false; } + @Override + public List getServiceOfferingDomains(Long serviceOfferingId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getServiceOfferingZones(Long serviceOfferingId) { + // TODO Auto-generated method stub + return null; + } + /* (non-Javadoc) * @see com.cloud.configuration.ConfigurationService#updateDiskOffering(org.apache.cloudstack.api.commands.UpdateDiskOfferingCmd) */ @@ -152,6 +164,18 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu return null; } + @Override + public List getDiskOfferingDomains(Long diskOfferingId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getDiskOfferingZones(Long diskOfferingId) { + // TODO Auto-generated method stub + return null; + } + /* (non-Javadoc) * @see com.cloud.configuration.ConfigurationService#createPod(long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @@ -288,6 +312,18 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu return false; } + @Override + public List getNetworkOfferingDomains(Long networkOfferingId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getNetworkOfferingZones(Long networkOfferingId) { + // TODO Auto-generated method stub + return null; + } + /* (non-Javadoc) * @see com.cloud.configuration.ConfigurationService#getNetworkOfferingNetworkRate(long) */