From deaf9106ca557a938edf25bee65cf6b4eb3ac03f Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Mon, 29 Apr 2013 14:11:51 +0530 Subject: [PATCH] CLOUDSTACK-741: Granular Global Parameters and adding fixes for CLOUDSTACK-2176, CLOUDSTACK-2198, CLOUDSTACK-2200 Adding the zone, cluster, account level parameters The parameters at scope (zone/cluster/pool/account) can be updated by updateConfiguration API with additional parameter zoneid/clusterid/accountid/storagepoolid Whenever these scoped parameters are used in CS they get value from the corresponding details table if not defined get value from global parameter. Same with the listConfiguration API with additional parameter zoneid/clusterid/accountid/storagepoolid --- .../configuration/ConfigurationService.java | 15 +- api/src/com/cloud/network/NetworkModel.java | 2 +- .../command/admin/config/ListCfgsByCmd.java | 44 +++-- .../command/admin/config/UpdateCfgCmd.java | 47 +++-- .../api/response/ConfigurationResponse.java | 3 + .../src/com/cloud/alert/AlertManagerImpl.java | 27 ++- server/src/com/cloud/api/ApiDBUtils.java | 2 +- .../com/cloud/capacity/dao/CapacityDao.java | 2 +- .../cloud/capacity/dao/CapacityDaoImpl.java | 35 ++-- .../src/com/cloud/configuration/Config.java | 20 +- .../configuration/ConfigurationManager.java | 2 +- .../ConfigurationManagerImpl.java | 171 ++++++++++++------ .../src/com/cloud/deploy/FirstFitPlanner.java | 25 +-- .../com/cloud/network/NetworkManagerImpl.java | 7 +- .../com/cloud/network/NetworkModelImpl.java | 11 +- .../com/cloud/network/vpc/VpcManagerImpl.java | 2 +- .../vpn/RemoteAccessVpnManagerImpl.java | 6 +- .../cloud/server/ConfigurationServerImpl.java | 11 +- .../cloud/server/ManagementServerImpl.java | 41 ++++- .../dao/StoragePoolDetailsDaoImpl.java | 1 + .../cloud/template/TemplateAdapterBase.java | 7 +- .../cloud/template/TemplateManagerImpl.java | 10 +- .../cloud/network/MockNetworkModelImpl.java | 2 +- .../vpc/MockConfigurationManagerImpl.java | 8 +- .../com/cloud/vpc/MockNetworkModelImpl.java | 2 +- .../AffinityApiTestConfiguration.java | 29 ++- .../ChildTestConfiguration.java | 38 ++-- setup/db/db/schema-410to420.sql | 4 + .../integration/smoke/test_global_settings.py | 14 +- 29 files changed, 388 insertions(+), 200 deletions(-) diff --git a/api/src/com/cloud/configuration/ConfigurationService.java b/api/src/com/cloud/configuration/ConfigurationService.java index 6937d0b64de..fdbd9d6bb0b 100644 --- a/api/src/com/cloud/configuration/ConfigurationService.java +++ b/api/src/com/cloud/configuration/ConfigurationService.java @@ -20,6 +20,11 @@ import java.util.List; import javax.naming.NamingException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.ResourceAllocationException; import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd; import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd; import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd; @@ -46,10 +51,6 @@ import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd; import com.cloud.dc.DataCenter; import com.cloud.dc.Pod; import com.cloud.dc.Vlan; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Networks.TrafficType; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; @@ -65,7 +66,7 @@ public interface ConfigurationService { * - the command wrapping name and value parameters * @return updated configuration object if successful */ - Configuration updateConfiguration(UpdateCfgCmd cmd); + Configuration updateConfiguration(UpdateCfgCmd cmd) throws InvalidParameterValueException; /** * Create a service offering through the API @@ -250,7 +251,7 @@ public interface ConfigurationService { NetworkOffering getNetworkOffering(long id); - Integer getNetworkOfferingNetworkRate(long networkOfferingId); + Integer getNetworkOfferingNetworkRate(long networkOfferingId, Long dataCenterId); Account getVlanAccount(long vlanId); @@ -262,7 +263,7 @@ public interface ConfigurationService { Long getDefaultPageSize(); - Integer getServiceOfferingNetworkRate(long serviceOfferingId); + Integer getServiceOfferingNetworkRate(long serviceOfferingId, Long dataCenterId); DiskOffering getDiskOffering(long diskOfferingId); diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index 4d7d714a7ae..d81b2d76fee 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -181,7 +181,7 @@ public interface NetworkModel { /** * @return */ - String getDefaultNetworkDomain(); + String getDefaultNetworkDomain(long zoneId); /** * @param ntwkOffId diff --git a/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java b/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java index 9f34405ffbd..a11904e90ce 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java @@ -45,11 +45,17 @@ public class ListCfgsByCmd extends BaseListCmd { @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "lists configuration by name") private String configName; - @Parameter(name=ApiConstants.SCOPE, type = CommandType.STRING, description = "scope(zone/cluster/pool/account) of the parameter that needs to be updated") - private String scope; + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, description="the ID of the Zone to update the parameter value for corresponding zone") + private Long zone_id; - @Parameter(name=ApiConstants.ID, type = CommandType.UUID, entityType = {ZoneResponse.class, ClusterResponse.class, StoragePoolResponse.class, AccountResponse.class}, description = "corresponding ID of the scope") - private Long id; + @Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.UUID, entityType=ClusterResponse.class, description="the ID of the Cluster to update the parameter value for corresponding cluster") + private Long cluster_id; + + @Parameter(name=ApiConstants.STORAGE_ID, type=CommandType.UUID, entityType=StoragePoolResponse.class, description="the ID of the Storage pool to update the parameter value for corresponding storage pool") + private Long storagepool_id; + + @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.UUID, entityType=AccountResponse.class, description="the ID of the Account to update the parameter value for corresponding account") + private Long account_id; // /////////////////////////////////////////////////// @@ -64,14 +70,21 @@ public class ListCfgsByCmd extends BaseListCmd { return configName; } - public String getScope() { - return scope; + public Long getZoneId() { + return zone_id; } - public Long getId() { - return id; + public Long getClusterId() { + return cluster_id; } + public Long getStoragepoolId() { + return storagepool_id; + } + + public Long getAccountId() { + return account_id; + } @Override public Long getPageSizeVal() { @@ -100,10 +113,17 @@ public class ListCfgsByCmd extends BaseListCmd { for (Configuration cfg : result.first()) { ConfigurationResponse cfgResponse = _responseGenerator.createConfigurationResponse(cfg); cfgResponse.setObjectName("configuration"); - if (scope != null) { - cfgResponse.setScope(scope); - } else { - cfgResponse.setScope("global"); + if(getZoneId() != null) { + cfgResponse.setScope("zone"); + } + if(getClusterId() != null) { + cfgResponse.setScope("cluster"); + } + if(getStoragepoolId() != null) { + cfgResponse.setScope("storagepool"); + } + if(getAccountId() != null) { + cfgResponse.setScope("account"); } configResponses.add(cfgResponse); } diff --git a/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java b/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java index 074c5a3b028..deb61d3741d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java @@ -43,11 +43,17 @@ public class UpdateCfgCmd extends BaseCmd { @Parameter(name=ApiConstants.VALUE, type=CommandType.STRING, description="the value of the configuration", length=4095) private String value; - @Parameter(name=ApiConstants.SCOPE, type = CommandType.STRING, description = "scope(zone/cluster/pool/account) of the parameter that needs to be updated") - private String scope; + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, description="the ID of the Zone to update the parameter value for corresponding zone") + private Long zone_id; - @Parameter(name=ApiConstants.ID, type = CommandType.UUID, entityType = {ZoneResponse.class, ClusterResponse.class, StoragePoolResponse.class, AccountResponse.class}, description = "corresponding ID of the scope") - private Long id; + @Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.UUID, entityType=ClusterResponse.class, description="the ID of the Cluster to update the parameter value for corresponding cluster") + private Long cluster_id; + + @Parameter(name=ApiConstants.STORAGE_ID, type=CommandType.UUID, entityType=StoragePoolResponse.class, description="the ID of the Storage pool to update the parameter value for corresponding storage pool") + private Long storagepool_id; + + @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.UUID, entityType=AccountResponse.class, description="the ID of the Account to update the parameter value for corresponding account") + private Long account_id; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -61,12 +67,20 @@ public class UpdateCfgCmd extends BaseCmd { return value; } - public String getScope() { - return scope; + public Long getZoneId() { + return zone_id; } - public Long getId() { - return id; + public Long getClusterId() { + return cluster_id; + } + + public Long getStoragepoolId() { + return storagepool_id; + } + + public Long getAccountId() { + return account_id; } ///////////////////////////////////////////////////// @@ -89,12 +103,19 @@ public class UpdateCfgCmd extends BaseCmd { if (cfg != null) { ConfigurationResponse response = _responseGenerator.createConfigurationResponse(cfg); response.setResponseName(getCommandName()); - if (scope != null) { - response.setScope(scope); - response.setValue(value); - } else { - response.setScope("global"); + if(getZoneId() != null) { + response.setScope("zone"); } + if(getClusterId() != null) { + response.setScope("cluster"); + } + if(getStoragepoolId() != null) { + response.setScope("storagepool"); + } + if(getAccountId() != null) { + response.setScope("account"); + } + response.setValue(value); this.setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update config"); diff --git a/api/src/org/apache/cloudstack/api/response/ConfigurationResponse.java b/api/src/org/apache/cloudstack/api/response/ConfigurationResponse.java index 176c47aff8b..fa0d4b45475 100644 --- a/api/src/org/apache/cloudstack/api/response/ConfigurationResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ConfigurationResponse.java @@ -35,6 +35,9 @@ public class ConfigurationResponse extends BaseResponse { @SerializedName(ApiConstants.SCOPE) @Param(description="scope(zone/cluster/pool/account) of the parameter that needs to be updated") private String scope; + @SerializedName(ApiConstants.ID) @Param(description="the value of the configuration") + private Long id; + @SerializedName(ApiConstants.DESCRIPTION) @Param(description="the description of the configuration") private String description; diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java index 655ed98ea60..6839d44635d 100755 --- a/server/src/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/com/cloud/alert/AlertManagerImpl.java @@ -70,6 +70,7 @@ import com.cloud.host.dao.HostDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.org.Grouping.AllocationState; import com.cloud.resource.ResourceManager; +import com.cloud.server.ConfigurationServer; import com.cloud.storage.StorageManager; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.NumbersUtil; @@ -106,7 +107,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager { @Inject private PrimaryDataStoreDao _storagePoolDao; @Inject private ConfigurationDao _configDao; @Inject private ResourceManager _resourceMgr; - @Inject private ConfigurationManager _configMgr; + @Inject private ConfigurationManager _configMgr; + @Inject ConfigurationServer _configServer; private Timer _timer = null; private float _cpuOverProvisioningFactor = 1; private long _capacityCheckPeriod = 60L * 60L * 1000L; // one hour by default @@ -562,19 +564,30 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager { float overProvFactor = 1f; capacity = _capacityDao.findCapacityBy(capacityType.intValue(), cluster.getDataCenterId(), null, cluster.getId()); - if (capacityType == Capacity.CAPACITY_TYPE_STORAGE){ - capacity.add(getUsedStats(capacityType, cluster.getDataCenterId(), cluster.getPodId(), cluster.getId())); + // cpu and memory allocated capacity notification threshold can be defined at cluster level, so getting the value if they are defined at cluster level + double capacityValue = 0; + switch (capacityType) { + case Capacity.CAPACITY_TYPE_STORAGE: + capacity.add(getUsedStats(capacityType, cluster.getDataCenterId(), cluster.getPodId(), cluster.getId())); + capacityValue = _capacityTypeThresholdMap.get(capacityType); + break; + case Capacity.CAPACITY_TYPE_CPU: + overProvFactor = ApiDBUtils.getCpuOverprovisioningFactor(); + capacityValue = Double.parseDouble(_configServer.getConfigValue(Config.CPUCapacityThreshold.key(), Config.ConfigurationParameterScope.cluster.toString(), cluster.getId())); + break; + case Capacity.CAPACITY_TYPE_MEMORY: + capacityValue = Double.parseDouble(_configServer.getConfigValue(Config.MemoryCapacityThreshold.key(), Config.ConfigurationParameterScope.cluster.toString(), cluster.getId())); + break; + default: + capacityValue = _capacityTypeThresholdMap.get(capacityType); } if (capacity == null || capacity.size() == 0){ continue; - } - if (capacityType == Capacity.CAPACITY_TYPE_CPU){ - overProvFactor = ApiDBUtils.getCpuOverprovisioningFactor(); } double totalCapacity = capacity.get(0).getTotalCapacity() * overProvFactor; double usedCapacity = capacity.get(0).getUsedCapacity() + capacity.get(0).getReservedCapacity(); - if (totalCapacity != 0 && usedCapacity/totalCapacity > _capacityTypeThresholdMap.get(capacityType)){ + if (totalCapacity != 0 && usedCapacity/totalCapacity > capacityValue){ generateEmailAlert(ApiDBUtils.findZoneById(cluster.getDataCenterId()), ApiDBUtils.findPodById(cluster.getPodId()), cluster, totalCapacity, usedCapacity, capacityType); } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 21ce63b8ae8..e291c844a8c 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -1034,7 +1034,7 @@ public class ApiDBUtils { } public static Integer getNetworkRate(long networkOfferingId) { - return _configMgr.getNetworkOfferingNetworkRate(networkOfferingId); + return _configMgr.getNetworkOfferingNetworkRate(networkOfferingId, null); } public static Account getVlanAccount(long vlanId) { diff --git a/server/src/com/cloud/capacity/dao/CapacityDao.java b/server/src/com/cloud/capacity/dao/CapacityDao.java index 0132f69cd50..04466f4adb2 100755 --- a/server/src/com/cloud/capacity/dao/CapacityDao.java +++ b/server/src/com/cloud/capacity/dao/CapacityDao.java @@ -41,5 +41,5 @@ public interface CapacityDao extends GenericDao { List listCapacitiesGroupedByLevelAndType(Integer capacityType, Long zoneId, Long podId, Long clusterId, int level, Long limit); void updateCapacityState(Long dcId, Long podId, Long clusterId, Long hostId, String capacityState); - List listClustersCrossingThreshold(short capacityType, Long zoneId, Float disableThreshold, long computeRequested); + List listClustersCrossingThreshold(short capacityType, Long zoneId, String ConfigName, long computeRequested); } diff --git a/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java b/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java index c3d98173a5c..ec5081a6edf 100755 --- a/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java +++ b/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java @@ -27,6 +27,7 @@ import java.util.Map; import javax.ejb.Local; import javax.inject.Inject; +import com.cloud.configuration.Config; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; @@ -115,12 +116,20 @@ public class CapacityDaoImpl extends GenericDaoBase implements private static final String LIST_CAPACITY_GROUP_BY_CLUSTER_TYPE_PART2 = " GROUP BY cluster_id, capacity_type order by percent desc limit "; private static final String UPDATE_CAPACITY_STATE = "UPDATE `cloud`.`op_host_capacity` SET capacity_state = ? WHERE "; - private static final String LIST_CLUSTERS_CROSSING_THRESHOLD = "SELECT cluster_id " + - "FROM (SELECT cluster_id, ( (sum(capacity.used_capacity) + sum(capacity.reserved_capacity) + ?)/sum(total_capacity) ) ratio "+ - "FROM `cloud`.`op_host_capacity` capacity "+ - "WHERE capacity.data_center_id = ? AND capacity.capacity_type = ? AND capacity.total_capacity > 0 "+ - "GROUP BY cluster_id) tmp " + - "WHERE tmp.ratio > ? "; + + private static final String LIST_CLUSTERS_CROSSING_THRESHOLD = "SELECT clusterList.cluster_id " + + "FROM ( SELECT cluster.cluster_id cluster_id, ( (sum(cluster.used) + sum(cluster.reserved) + ?)/sum(cluster.total) ) ratio, cluster.configValue value " + + "FROM ( SELECT capacity.cluster_id cluster_id, capacity.used_capacity used, capacity.reserved_capacity reserved, capacity.total_capacity total, " + + "CASE (SELECT count(*) FROM `cloud`.`cluster_details` details WHERE details.cluster_id = capacity.cluster_id AND details.name = ? ) " + + "WHEN 1 THEN ( SELECT details.value FROM `cloud`.`cluster_details` details WHERE details.cluster_id = capacity.cluster_id AND details.name = ? ) " + + "ELSE ( SELECT config.value FROM `cloud`.`configuration` config WHERE config.name = ?) " + + "END configValue " + + "FROM `cloud`.`op_host_capacity` capacity " + + "WHERE capacity.data_center_id = ? AND capacity.capacity_type = ? AND capacity.total_capacity > 0) cluster " + + + "GROUP BY cluster.cluster_id) clusterList " + + "WHERE clusterList.ratio > clusterList.value; "; + public CapacityDaoImpl() { @@ -146,20 +155,22 @@ public class CapacityDaoImpl extends GenericDaoBase implements } @Override - public List listClustersCrossingThreshold(short capacityType, Long zoneId, Float disableThreshold, long compute_requested){ + public List listClustersCrossingThreshold(short capacityType, Long zoneId, String configName, long compute_requested){ Transaction txn = Transaction.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); StringBuilder sql = new StringBuilder(LIST_CLUSTERS_CROSSING_THRESHOLD); - - + // during listing the clusters that cross the threshold + // we need to check with disabled thresholds of each cluster if not defined at cluster consider the global value try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); pstmt.setLong(1,compute_requested); - pstmt.setShort(2,capacityType); - pstmt.setFloat(3,disableThreshold); - pstmt.setLong(4,zoneId); + pstmt.setString(2, configName); + pstmt.setString(3, configName); + pstmt.setString(4, configName); + pstmt.setLong(5,zoneId); + pstmt.setShort(6,capacityType); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index dbcbc5332d0..af6adcf44a7 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -53,8 +53,8 @@ public enum Config { CapacityCheckPeriod("Alert", ManagementServer.class, Integer.class, "capacity.check.period", "300000", "The interval in milliseconds between capacity checks", null), StorageAllocatedCapacityThreshold("Alert", ManagementServer.class, Float.class, "cluster.storage.allocated.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of allocated storage utilization above which alerts will be sent about low storage available.", null), StorageCapacityThreshold("Alert", ManagementServer.class, Float.class, "cluster.storage.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of storage utilization above which alerts will be sent about low storage available.", null), - CPUCapacityThreshold("Alert", ManagementServer.class, Float.class, "cluster.cpu.allocated.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of cpu utilization above which alerts will be sent about low cpu available.", null), - MemoryCapacityThreshold("Alert", ManagementServer.class, Float.class, "cluster.memory.allocated.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of memory utilization above which alerts will be sent about low memory available.", null), + CPUCapacityThreshold("Alert", ManagementServer.class, Float.class, "cluster.cpu.allocated.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of cpu utilization above which alerts will be sent about low cpu available.", null, ConfigurationParameterScope.cluster.toString()), + MemoryCapacityThreshold("Alert", ManagementServer.class, Float.class, "cluster.memory.allocated.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of memory utilization above which alerts will be sent about low memory available.", null, ConfigurationParameterScope.cluster.toString()), PublicIpCapacityThreshold("Alert", ManagementServer.class, Float.class, "zone.virtualnetwork.publicip.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of public IP address space utilization above which alerts will be sent.", null), PrivateIpCapacityThreshold("Alert", ManagementServer.class, Float.class, "pod.privateip.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of private IP address space utilization above which alerts will be sent.", null), SecondaryStorageCapacityThreshold("Alert", ManagementServer.class, Float.class, "zone.secstorage.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of secondary storage utilization above which alerts will be sent about low storage available.", null), @@ -63,8 +63,8 @@ public enum Config { LocalStorageCapacityThreshold("Alert", ManagementServer.class, Float.class, "cluster.localStorage.capacity.notificationthreshold", "0.75", "Percentage (as a value between 0 and 1) of local storage utilization above which alerts will be sent about low local storage available.", null), StorageAllocatedCapacityDisableThreshold("Alert", ManagementServer.class, Float.class, "pool.storage.allocated.capacity.disablethreshold", "0.85", "Percentage (as a value between 0 and 1) of allocated storage utilization above which allocators will disable using the pool for low allocated storage available.", null), StorageCapacityDisableThreshold("Alert", ManagementServer.class, Float.class, "pool.storage.capacity.disablethreshold", "0.85", "Percentage (as a value between 0 and 1) of storage utilization above which allocators will disable using the pool for low storage available.", null), - CPUCapacityDisableThreshold("Alert", ManagementServer.class, Float.class, "cluster.cpu.allocated.capacity.disablethreshold", "0.85", "Percentage (as a value between 0 and 1) of cpu utilization above which allocators will disable using the cluster for low cpu available. Keep the corresponding notification threshold lower than this to be notified beforehand.", null), - MemoryCapacityDisableThreshold("Alert", ManagementServer.class, Float.class, "cluster.memory.allocated.capacity.disablethreshold", "0.85", "Percentage (as a value between 0 and 1) of memory utilization above which allocators will disable using the cluster for low memory available. Keep the corresponding notification threshold lower than this to be notified beforehand.", null), + CPUCapacityDisableThreshold("Alert", ManagementServer.class, Float.class, "cluster.cpu.allocated.capacity.disablethreshold", "0.85", "Percentage (as a value between 0 and 1) of cpu utilization above which allocators will disable using the cluster for low cpu available. Keep the corresponding notification threshold lower than this to be notified beforehand.", null, ConfigurationParameterScope.cluster.toString()), + MemoryCapacityDisableThreshold("Alert", ManagementServer.class, Float.class, "cluster.memory.allocated.capacity.disablethreshold", "0.85", "Percentage (as a value between 0 and 1) of memory utilization above which allocators will disable using the cluster for low memory available. Keep the corresponding notification threshold lower than this to be notified beforehand.", null, ConfigurationParameterScope.cluster.toString()), // Storage @@ -93,8 +93,8 @@ public enum Config { GuestVlanBits("Network", ManagementServer.class, Integer.class, "guest.vlan.bits", "12", "The number of bits to reserve for the VLAN identifier in the guest subnet.", null), //MulticastThrottlingRate("Network", ManagementServer.class, Integer.class, "multicast.throttling.rate", "10", "Default multicast rate in megabits per second allowed.", null), - NetworkThrottlingRate("Network", ManagementServer.class, Integer.class, "network.throttling.rate", "200", "Default data transfer rate in megabits per second allowed in network.", null), - GuestDomainSuffix("Network", AgentManager.class, String.class, "guest.domain.suffix", "cloud.internal", "Default domain name for vms inside virtualized networks fronted by router", null), + NetworkThrottlingRate("Network", ManagementServer.class, Integer.class, "network.throttling.rate", "200", "Default data transfer rate in megabits per second allowed in network.", null, ConfigurationParameterScope.zone.toString()), + GuestDomainSuffix("Network", AgentManager.class, String.class, "guest.domain.suffix", "cloud.internal", "Default domain name for vms inside virtualized networks fronted by router", null, ConfigurationParameterScope.zone.toString()), DirectNetworkNoDefaultRoute("Network", ManagementServer.class, Boolean.class, "direct.network.no.default.route", "false", "Direct Network Dhcp Server should not send a default route", "true/false"), OvsTunnelNetwork("Network", ManagementServer.class, Boolean.class, "sdn.ovs.controller", "false", "Enable/Disable Open vSwitch SDN controller for L2-in-L3 overlay networks", null), OvsTunnelNetworkDefaultLabel("Network", ManagementServer.class, String.class, "sdn.ovs.controller.default.label", "cloud-public", "Default network label to be used when fetching interface for GRE endpoints", null), @@ -112,7 +112,7 @@ public enum Config { //VPN RemoteAccessVpnPskLength("Network", AgentManager.class, Integer.class, "remote.access.vpn.psk.length", "24", "The length of the ipsec preshared key (minimum 8, maximum 256)", null), - RemoteAccessVpnClientIpRange("Network", AgentManager.class, String.class, "remote.access.vpn.client.iprange", "10.1.2.1-10.1.2.8", "The range of ips to be allocated to remote access vpn clients. The first ip in the range is used by the VPN server", null), + RemoteAccessVpnClientIpRange("Network", AgentManager.class, String.class, "remote.access.vpn.client.iprange", "10.1.2.1-10.1.2.8", "The range of ips to be allocated to remote access vpn clients. The first ip in the range is used by the VPN server", null, ConfigurationParameterScope.account.toString()), RemoteAccessVpnUserLimit("Network", AgentManager.class, String.class, "remote.access.vpn.user.limit", "8", "The maximum number of VPN users that can be created per account", null), Site2SiteVpnConnectionPerVpnGatewayLimit("Network", ManagementServer.class, Integer.class, "site2site.vpn.vpngateway.connection.limit", "4", "The maximum number of VPN connection per VPN gateway", null), Site2SiteVpnSubnetsPerCustomerGatewayLimit("Network", ManagementServer.class, Integer.class, "site2site.vpn.customergateway.subnets.limit", "10", "The maximum number of subnets per customer gateway", null), @@ -149,7 +149,7 @@ public enum Config { S3Enable("Advanced", ManagementServer.class, Boolean.class, "s3.enable", "false", "enable s3 ", null), EventPurgeInterval("Advanced", ManagementServer.class, Integer.class, "event.purge.interval", "86400", "The interval (in seconds) to wait before running the event purge thread", null), AccountCleanupInterval("Advanced", ManagementServer.class, Integer.class, "account.cleanup.interval", "86400", "The interval (in seconds) between cleanup for removed accounts", null), - AllowPublicUserTemplates("Advanced", ManagementServer.class, Integer.class, "allow.public.user.templates", "true", "If false, users will not be able to create public templates.", null), + AllowPublicUserTemplates("Advanced", ManagementServer.class, Integer.class, "allow.public.user.templates", "true", "If false, users will not be able to create public templates.", null, ConfigurationParameterScope.account.toString()), InstanceName("Advanced", AgentManager.class, String.class, "instance.name", "VM", "Name of the deployment instance.", "instanceName"), ExpungeDelay("Advanced", UserVmManager.class, Integer.class, "expunge.delay", "86400", "Determines how long (in seconds) to wait before actually expunging destroyed vm. The default value = the default value of expunge.interval", null), ExpungeInterval("Advanced", UserVmManager.class, Integer.class, "expunge.interval", "86400", "The interval (in seconds) to wait before running the expunge thread.", null), @@ -419,7 +419,7 @@ public enum Config { global, zone, cluster, - pool, + storagepool, account } @@ -427,7 +427,7 @@ public enum Config { static { _scopeLevelConfigsMap.put(ConfigurationParameterScope.zone.toString(), new ArrayList()); _scopeLevelConfigsMap.put(ConfigurationParameterScope.cluster.toString(), new ArrayList()); - _scopeLevelConfigsMap.put(ConfigurationParameterScope.pool.toString(), new ArrayList()); + _scopeLevelConfigsMap.put(ConfigurationParameterScope.storagepool.toString(), new ArrayList()); _scopeLevelConfigsMap.put(ConfigurationParameterScope.account.toString(), new ArrayList()); _scopeLevelConfigsMap.put(ConfigurationParameterScope.global.toString(), new ArrayList()); diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index 738c5bab35d..bce1776af73 100755 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -60,7 +60,7 @@ public interface ConfigurationManager extends ConfigurationService, Manager { * @param name * @param value */ - void updateConfiguration(long userId, String name, String category, String value, String scope, Long id); + String updateConfiguration(long userId, String name, String category, String value, String scope, Long id); /** * Creates a new service offering diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index d5e405d5395..068a58634ed 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -39,7 +39,9 @@ import javax.naming.NamingException; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; +import com.cloud.dc.*; import com.cloud.dc.dao.*; +import com.cloud.user.*; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.api.ApiConstants.LDAPParams; import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd; @@ -64,6 +66,10 @@ import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd; import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd; import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd; import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -72,20 +78,8 @@ import com.cloud.api.ApiDBUtils; import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.AccountVlanMapVO; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.DataCenterIpAddressVO; -import com.cloud.dc.DataCenterLinkLocalIpAddressVO; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.DcDetailVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Pod; -import com.cloud.dc.PodVlanMapVO; -import com.cloud.dc.Vlan; import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.VlanVO; import com.cloud.deploy.DataCenterDeployment; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; @@ -133,6 +127,7 @@ import com.cloud.org.Grouping; import com.cloud.org.Grouping.AllocationState; import com.cloud.projects.Project; import com.cloud.projects.ProjectManager; +import com.cloud.server.ConfigurationServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -144,12 +139,6 @@ import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.test.IPRangeConfig; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.AccountVO; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.User; -import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.StringUtils; @@ -182,8 +171,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Inject DataCenterDao _zoneDao; @Inject - DcDetailsDao _zoneDetailsDao; - @Inject DomainDao _domainDao; @Inject SwiftDao _swiftDao; @@ -245,6 +232,18 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati FirewallRulesDao _firewallDao; @Inject VpcManager _vpcMgr; + @Inject + ConfigurationServer _configServer; + @Inject + DcDetailsDao _dcDetailsDao; + @Inject + ClusterDetailsDao _clusterDetailsDao; + @Inject + StoragePoolDetailsDao _storagePoolDetailsDao; + @Inject + AccountDetailsDao _accountDetailsDao; + @Inject + PrimaryDataStoreDao _storagePoolDao; // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao? @Inject protected DataCenterLinkLocalIpAddressDao _LinkLocalIpAllocDao; @@ -323,9 +322,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override @DB - public void updateConfiguration(long userId, String name, String category, String value, String scope, Long resourceId) { + public String updateConfiguration(long userId, String name, String category, String value, String scope, Long resourceId) { - String validationMsg = validateConfigurationValue(name, value, scope); + String validationMsg = validateConfigurationValue(name, value); if (validationMsg != null) { s_logger.error("Invalid configuration option, name: " + name + ", value:" + value); @@ -335,23 +334,61 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // If scope of the parameter is given then it needs to be updated in the corresponding details table, // if scope is mentioned as global or not mentioned then it is normal global parameter updation if (scope != null && !scope.isEmpty() && !Config.ConfigurationParameterScope.global.toString().equalsIgnoreCase(scope)) { - if (Config.ConfigurationParameterScope.zone.toString().equalsIgnoreCase(scope)) { - DataCenterVO zone = _zoneDao.findById(resourceId); - if (zone == null) { - throw new InvalidParameterValueException("unable to find zone by id " + resourceId); - } - DcDetailVO dcDetailVO = _zoneDetailsDao.findDetail(resourceId, name.toLowerCase()); - if (dcDetailVO == null) { - dcDetailVO = new DcDetailVO(zone.getId(), name, value); - _zoneDetailsDao.persist(dcDetailVO); - } else { - dcDetailVO.setValue(value); - _zoneDetailsDao.update(resourceId, dcDetailVO); - } - } else { - s_logger.error("TO Do for the remaining levels (cluster/pool/account)"); - throw new InvalidParameterValueException("The scope "+ scope +" yet to be implemented"); + switch (Config.ConfigurationParameterScope.valueOf(scope)) { + case zone: DataCenterVO zone = _zoneDao.findById(resourceId); + if (zone == null) { + throw new InvalidParameterValueException("unable to find zone by id " + resourceId); + } + DcDetailVO dcDetailVO = _dcDetailsDao.findDetail(resourceId, name.toLowerCase()); + if (dcDetailVO == null) { + dcDetailVO = new DcDetailVO(resourceId, name, value); + _dcDetailsDao.persist(dcDetailVO); + } else { + dcDetailVO.setValue(value); + _dcDetailsDao.update(dcDetailVO.getId(), dcDetailVO); + } break; + case cluster: ClusterVO cluster = _clusterDao.findById(resourceId); + if (cluster == null) { + throw new InvalidParameterValueException("unable to find cluster by id " + resourceId); + } + ClusterDetailsVO clusterDetailsVO = _clusterDetailsDao.findDetail(resourceId, name); + if (clusterDetailsVO == null) { + clusterDetailsVO = new ClusterDetailsVO(resourceId, name, value); + _clusterDetailsDao.persist(clusterDetailsVO); + } else { + clusterDetailsVO.setValue(value); + _clusterDetailsDao.update(clusterDetailsVO.getId(), clusterDetailsVO); + } break; + + case storagepool: StoragePoolVO pool = _storagePoolDao.findById(resourceId); + if (pool == null) { + throw new InvalidParameterValueException("unable to find storage pool by id " + resourceId); + } + StoragePoolDetailVO storagePoolDetailVO = _storagePoolDetailsDao.findDetail(resourceId, name); + if (storagePoolDetailVO == null) { + storagePoolDetailVO = new StoragePoolDetailVO(resourceId, name, value); + _storagePoolDetailsDao.persist(storagePoolDetailVO); + + } else { + storagePoolDetailVO.setValue(value); + _storagePoolDetailsDao.update(storagePoolDetailVO.getId(), storagePoolDetailVO); + } break; + + case account: AccountVO account = _accountDao.findById(resourceId); + if (account == null) { + throw new InvalidParameterValueException("unable to find account by id " + resourceId); + } + AccountDetailVO accountDetailVO = _accountDetailsDao.findDetail(resourceId, name); + if (accountDetailVO == null) { + accountDetailVO = new AccountDetailVO(resourceId, name, value); + _accountDetailsDao.persist(accountDetailVO); + } else { + accountDetailVO.setValue(value); + _accountDetailsDao.update(accountDetailVO.getId(), accountDetailVO); + } break; + default: throw new InvalidParameterValueException("Scope provided is invalid"); } + return value; } // Execute all updates in a single transaction @@ -450,16 +487,19 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } txn.commit(); + return _configDao.getValue(name); } @Override @ActionEvent(eventType = EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, eventDescription = "updating configuration") - public Configuration updateConfiguration(UpdateCfgCmd cmd) { + public Configuration updateConfiguration(UpdateCfgCmd cmd) throws InvalidParameterValueException { Long userId = UserContext.current().getCallerUserId(); String name = cmd.getCfgName(); String value = cmd.getValue(); - String scope = cmd.getScope(); - Long id = cmd.getId(); + Long zoneId = cmd.getZoneId(); + Long clusterId = cmd.getClusterId(); + Long storagepoolId = cmd.getStoragepoolId(); + Long accountId = cmd.getAccountId(); UserContext.current().setEventDetails(" Name: " + name + " New Value: " + (((name.toLowerCase()).contains("password")) ? "*****" : (((value == null) ? "" : value)))); // check if config value exists @@ -476,17 +516,44 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati value = null; } - updateConfiguration(userId, name, config.getCategory(), value, scope, id); - String updatedValue = _configDao.getValue(name); + String scope = null; + Long id = null; + int paramCountCheck = 0; + + if (zoneId != null) { + scope = Config.ConfigurationParameterScope.zone.toString(); + id = zoneId; + paramCountCheck++; + } + if (clusterId != null) { + scope = Config.ConfigurationParameterScope.cluster.toString(); + id = clusterId; + paramCountCheck++; + } + if (accountId != null) { + scope = Config.ConfigurationParameterScope.account.toString(); + id = accountId; + paramCountCheck++; + } + if (storagepoolId != null) { + scope = Config.ConfigurationParameterScope.storagepool.toString(); + id = storagepoolId; + paramCountCheck++; + } + + if (paramCountCheck > 1) { + throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope"); + } + + String updatedValue = updateConfiguration(userId, name, config.getCategory(), value, scope, id); if ((value == null && updatedValue == null) || updatedValue.equalsIgnoreCase(value)) { return _configDao.findByName(name); - } else { throw new CloudRuntimeException("Unable to update configuration parameter " + name); } } - private String validateConfigurationValue(String name, String value, String scope) { + private String validateConfigurationValue(String name, String value) { Config c = Config.getConfig(name); if (c == null) { @@ -494,12 +561,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return "Invalid configuration variable."; } String configScope = c.getScope(); - if (scope != null && !scope.isEmpty()) { - if (!configScope.contains(scope)) { - s_logger.error("Invalid scope " + scope + " for the parameter " + name); - return "Invalid scope for the parameter."; - } - } Class type = c.getType(); @@ -4077,7 +4138,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } @Override - public Integer getNetworkOfferingNetworkRate(long networkOfferingId) { + public Integer getNetworkOfferingNetworkRate(long networkOfferingId, Long dataCenterId) { // validate network offering information NetworkOffering no = getNetworkOffering(networkOfferingId); @@ -4089,7 +4150,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (no.getRateMbps() != null) { networkRate = no.getRateMbps(); } else { - networkRate = Integer.parseInt(_configDao.getValue(Config.NetworkThrottlingRate.key())); + networkRate = Integer.parseInt(_configServer.getConfigValue(Config.NetworkThrottlingRate.key(), Config.ConfigurationParameterScope.zone.toString(), dataCenterId)); } // networkRate is unsigned int in netowrkOfferings table, and can't be @@ -4225,7 +4286,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } @Override - public Integer getServiceOfferingNetworkRate(long serviceOfferingId) { + public Integer getServiceOfferingNetworkRate(long serviceOfferingId, Long dataCenterId) { // validate network offering information ServiceOffering offering = _serviceOfferingDao.findById(serviceOfferingId); @@ -4239,7 +4300,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } else { // for domain router service offering, get network rate from if (offering.getSystemVmType() != null && offering.getSystemVmType().equalsIgnoreCase(VirtualMachine.Type.DomainRouter.toString())) { - networkRate = Integer.parseInt(_configDao.getValue(Config.NetworkThrottlingRate.key())); + networkRate = Integer.parseInt(_configServer.getConfigValue(Config.NetworkThrottlingRate.key(), Config.ConfigurationParameterScope.zone.toString(), dataCenterId)); } else { networkRate = Integer.parseInt(_configDao.getValue(Config.VmNetworkThrottlingRate.key())); } diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index 1647cf7dba9..2e7e9f6128f 100755 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -452,21 +452,6 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { return disabledPods; } - private Map getCapacityThresholdMap(){ - // Lets build this real time so that the admin wont have to restart MS if he changes these values - Map disableThresholdMap = new HashMap(); - - String cpuDisableThresholdString = _configDao.getValue(Config.CPUCapacityDisableThreshold.key()); - float cpuDisableThreshold = NumbersUtil.parseFloat(cpuDisableThresholdString, 0.85F); - disableThresholdMap.put(Capacity.CAPACITY_TYPE_CPU, cpuDisableThreshold); - - String memoryDisableThresholdString = _configDao.getValue(Config.MemoryCapacityDisableThreshold.key()); - float memoryDisableThreshold = NumbersUtil.parseFloat(memoryDisableThresholdString, 0.85F); - disableThresholdMap.put(Capacity.CAPACITY_TYPE_MEMORY, memoryDisableThreshold); - - return disableThresholdMap; - } - private List getCapacitiesForCheckingThreshold(){ List capacityList = new ArrayList(); capacityList.add(Capacity.CAPACITY_TYPE_CPU); @@ -476,7 +461,6 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { private void removeClustersCrossingThreshold(List clusterListForVmAllocation, ExcludeList avoid, VirtualMachineProfile vmProfile, DeploymentPlan plan){ - Map capacityThresholdMap = getCapacityThresholdMap(); List capacityList = getCapacitiesForCheckingThreshold(); List clustersCrossingThreshold = new ArrayList(); @@ -491,12 +475,11 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { return; } if (capacity == Capacity.CAPACITY_TYPE_CPU) { - clustersCrossingThreshold = _capacityDao.listClustersCrossingThreshold(capacity, plan.getDataCenterId(), - capacityThresholdMap.get(capacity), cpu_requested); + clustersCrossingThreshold = _capacityDao.listClustersCrossingThreshold(capacity, plan.getDataCenterId(), Config.CPUCapacityDisableThreshold.key(), cpu_requested); } else if (capacity == Capacity.CAPACITY_TYPE_MEMORY ) { clustersCrossingThreshold = _capacityDao.listClustersCrossingThreshold(capacity, plan.getDataCenterId(), - capacityThresholdMap.get(capacity), ram_requested ); + Config.MemoryCapacityDisableThreshold.key(), ram_requested ); } @@ -506,8 +489,8 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { // Remove clusters crossing disabled threshold clusterListForVmAllocation.removeAll(clustersCrossingThreshold); - s_logger.debug("Cannot allocate cluster list " + clustersCrossingThreshold.toString() + " for vm creation since their allocated percentage" + - " crosses the disable capacity threshold: " + capacityThresholdMap.get(capacity) + " for capacity Type : " + capacity + ", skipping these clusters"); + s_logger.debug("Cannot allocate cluster list " + clustersCrossingThreshold.toString() + " for vm creation since their allocated percentage" + + " crosses the disable capacity threshold defined at each cluster/ at global value for capacity Type : " + capacity + ", skipping these clusters"); } } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 72ccac0ec7d..7adcf07f044 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -46,6 +46,7 @@ import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; +import com.cloud.server.ConfigurationServer; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.IpAddress.State; import com.cloud.network.Network.*; @@ -153,6 +154,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L RemoteAccessVpnService _vpnMgr; @Inject PodVlanMapDao _podVlanMapDao; + @Inject + ConfigurationServer _configServer; List _networkGurus; public List getNetworkGurus() { @@ -245,7 +248,6 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L int _networkGcWait; int _networkGcInterval; - String _networkDomain; int _networkLockTimeout; private Map _configs; @@ -866,7 +868,6 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _networkGcInterval = NumbersUtil.parseInt(_configs.get(Config.NetworkGcInterval.key()), 600); _configs = _configDao.getConfiguration("Network", params); - _networkDomain = _configs.get(Config.GuestDomainSuffix.key()); _networkLockTimeout = NumbersUtil.parseInt(_configs.get(Config.NetworkLockTimeout.key()), 600); @@ -2023,7 +2024,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L // 2) If null, generate networkDomain using domain suffix from the global config variables if (networkDomain == null) { - networkDomain = "cs" + Long.toHexString(owner.getId()) + _networkDomain; + networkDomain = "cs" + Long.toHexString(owner.getId()) + _configServer.getConfigValue(Config.GuestDomainSuffix.key(), Config.ConfigurationParameterScope.zone.toString(), zoneId); } } else { diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index c5930d9315c..bd62886674f 100755 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -52,6 +52,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.UnsupportedServiceException; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.server.ConfigurationServer; import com.cloud.network.IpAddress.State; import com.cloud.network.Network.Capability; import com.cloud.network.Network.GuestType; @@ -143,6 +144,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { @Inject PodVlanMapDao _podVlanMapDao; + @Inject + ConfigurationServer _configServer; List _networkElements; public List getNetworkElements() { @@ -921,9 +924,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { } } if (isUserVmsDefaultNetwork || isDomRGuestOrPublicNetwork) { - return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId()); + return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId(), vm.getDataCenterId()); } else { - return _configMgr.getNetworkOfferingNetworkRate(ntwkOff.getId()); + return _configMgr.getNetworkOfferingNetworkRate(ntwkOff.getId(), vm.getDataCenterId()); } } @@ -1564,8 +1567,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { } @Override - public String getDefaultNetworkDomain() { - return _networkDomain; + public String getDefaultNetworkDomain(long zoneId) { + return _configServer.getConfigValue(Config.GuestDomainSuffix.key(), Config.ConfigurationParameterScope.zone.toString(), zoneId); } @Override diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 224a6800326..bc7bb0c75f2 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -582,7 +582,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis // 2) If null, generate networkDomain using domain suffix from the global config variables if (networkDomain == null) { - networkDomain = "cs" + Long.toHexString(owner.getId()) + _ntwkModel.getDefaultNetworkDomain(); + networkDomain = "cs" + Long.toHexString(owner.getId()) + _ntwkModel.getDefaultNetworkDomain(zoneId); } } diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index 673535aaa42..062743b23af 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -62,6 +62,7 @@ import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.RulesManager; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ConfigurationServer; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; @@ -100,6 +101,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc @Inject UsageEventDao _usageEventDao; @Inject ConfigurationDao _configDao; @Inject List _vpnServiceProviders; + @Inject ConfigurationServer _configServer; int _userLimit; @@ -156,7 +158,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc } if (ipRange == null) { - ipRange = _clientIpRange; + ipRange = _configServer.getConfigValue(Config.RemoteAccessVpnClientIpRange.key(), Config.ConfigurationParameterScope.account.toString(), ipAddr.getAccountId()); } String[] range = ipRange.split("-"); if (range.length != 2) { @@ -200,7 +202,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc private void validateRemoteAccessVpnConfiguration() throws ConfigurationException { String ipRange = _clientIpRange; if (ipRange == null) { - s_logger.warn("Remote Access VPN configuration missing client ip range -- ignoring"); + s_logger.warn("Remote Access VPN global configuration missing client ip range -- ignoring"); return; } Integer pskLength = _pskLength; diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index cd890ce8582..3d97447fe40 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -48,8 +48,10 @@ import com.cloud.dc.*; import com.cloud.dc.dao.DcDetailsDao; import com.cloud.user.*; import com.cloud.utils.db.GenericDao; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -59,6 +61,7 @@ import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceCountDao; import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; @@ -112,6 +115,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio @Inject private ConfigurationDao _configDao; @Inject private DataCenterDao _zoneDao; + @Inject private ClusterDao _clusterDao; + @Inject private PrimaryDataStoreDao _storagePoolDao; @Inject private HostPodDao _podDao; @Inject private DiskOfferingDao _diskOfferingDao; @Inject private ServiceOfferingDao _serviceOfferingDao; @@ -698,7 +703,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio return dcDetailVO.getValue(); } break; - case cluster: ClusterDetailsVO cluster = _clusterDetailsDao.findById(resourceId); + case cluster: ClusterVO cluster = _clusterDao.findById(resourceId); if (cluster == null) { throw new InvalidParameterValueException("unable to find cluster by id " + resourceId); } @@ -707,7 +712,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio return clusterDetailsVO.getValue(); } break; - case pool: StoragePoolDetailVO pool = _storagePoolDetailsDao.findById(resourceId); + case storagepool: StoragePoolVO pool = _storagePoolDao.findById(resourceId); if (pool == null) { throw new InvalidParameterValueException("unable to find storage pool by id " + resourceId); } @@ -716,7 +721,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio return storagePoolDetailVO.getValue(); } break; - case account: AccountDetailVO account = _accountDetailsDao.findById(resourceId); + case account: AccountVO account = _accountDao.findById(resourceId); if (account == null) { throw new InvalidParameterValueException("unable to find account by id " + resourceId); } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 1799f7729e0..f18c9d592aa 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1274,16 +1274,41 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe Object name = cmd.getConfigName(); Object category = cmd.getCategory(); Object keyword = cmd.getKeyword(); - Long id = cmd.getId(); - String scope = cmd.getScope(); + Long zoneId = cmd.getZoneId(); + Long clusterId = cmd.getClusterId(); + Long storagepoolId = cmd.getStoragepoolId(); + Long accountId = cmd.getAccountId(); + String scope = null; + Long id = null; + int paramCountCheck = 0; - if (scope!= null && !scope.isEmpty()) { + if (zoneId != null) { + scope = Config.ConfigurationParameterScope.zone.toString(); + id = zoneId; + paramCountCheck++; + } + if (clusterId != null) { + scope = Config.ConfigurationParameterScope.cluster.toString(); + id = clusterId; + paramCountCheck++; + } + if (accountId != null) { + scope = Config.ConfigurationParameterScope.account.toString(); + id = accountId; + paramCountCheck++; + } + if (storagepoolId != null) { + scope = Config.ConfigurationParameterScope.storagepool.toString(); + id = storagepoolId; + paramCountCheck++; + } + + if (paramCountCheck > 1) { + throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope"); + } + + if (scope != null && !scope.isEmpty()) { // getting the list of parameters at requested scope - try { - Config.ConfigurationParameterScope.valueOf(scope.toLowerCase()); - } catch (Exception e ) { - throw new InvalidParameterValueException("Invalid scope " + scope + " while listing configuration parameters"); - } if (id == null) { throw new InvalidParameterValueException("Invalid id null, id is needed corresponding to the scope"); } diff --git a/server/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java b/server/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java index a0d5d0e6e97..38b525330f2 100644 --- a/server/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java +++ b/server/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java @@ -41,6 +41,7 @@ public class StoragePoolDetailsDaoImpl extends GenericDaoBase