Skip to content

Configuration settings validation improvements #10998

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: 4.19
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,17 @@
import java.util.List;

import org.apache.cloudstack.api.response.MigrationResponse;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.storage.ImageStoreService.MigrationPolicy;

public interface StorageOrchestrationService {
ConfigKey<Double> ImageStoreImbalanceThreshold = new ConfigKey<>("Advanced", Double.class,
"image.store.imbalance.threshold",
"0.3",
"The storage imbalance threshold that is compared with the standard deviation percentage for a storage utilization metric. " +
"The value is a percentage in decimal format.",
true, ConfigKey.Scope.Global);

MigrationResponse migrateData(Long srcDataStoreId, List<Long> destDatastores, MigrationPolicy migrationPolicy);

MigrationResponse migrateResources(Long srcImgStoreId, Long destImgStoreId, List<Long> templateIdList, List<Long> snapshotIdList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,6 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
@Inject
DataMigrationUtility migrationHelper;

ConfigKey<Double> ImageStoreImbalanceThreshold = new ConfigKey<>("Advanced", Double.class,
"image.store.imbalance.threshold",
"0.3",
"The storage imbalance threshold that is compared with the standard deviation percentage for a storage utilization metric. " +
"The value is a percentage in decimal format.",
true, ConfigKey.Scope.Global);

Integer numConcurrentCopyTasksPerSSVM = 2;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public interface QuotaConfig {
public static final ConfigKey<Boolean> QuotaPluginEnabled = new ConfigKey<Boolean>("Advanced", Boolean.class, "quota.enable.service", "false",
"Indicates whether Quota plugin is enabled or not.", true);

public static final ConfigKey<String> QuotaEnableEnforcement = new ConfigKey<String>("Advanced", String.class, "quota.enable.enforcement", "false",
public static final ConfigKey<Boolean> QuotaEnableEnforcement = new ConfigKey<Boolean>("Advanced", Boolean.class, "quota.enable.enforcement", "false",
"Enable the usage quota enforcement, i.e. on true when exceeding quota the respective account will be locked.", true);

public static final ConfigKey<String> QuotaCurrencySymbol = new ConfigKey<String>("Advanced", String.class, "quota.currency.symbol", "$",
Expand Down Expand Up @@ -57,7 +57,7 @@ public interface QuotaConfig {
public static final ConfigKey<String> QuotaSmtpEnabledSecurityProtocols = new ConfigKey<String>("Advanced", String.class, "quota.usage.smtp.enabledSecurityProtocols", "",
"White-space separated security protocols; ex: \"TLSv1 TLSv1.1\". Supported protocols: SSLv2Hello, SSLv3, TLSv1, TLSv1.1 and TLSv1.2.", true);

public static final ConfigKey<String> QuotaSmtpUseStartTLS = new ConfigKey<String>("Advanced", String.class, "quota.usage.smtp.useStartTLS", "false",
public static final ConfigKey<Boolean> QuotaSmtpUseStartTLS = new ConfigKey<Boolean>("Advanced", Boolean.class, "quota.usage.smtp.useStartTLS", "false",
"If set to true and if we enable security via quota.usage.smtp.useAuth, this will enable StartTLS to secure the connection.", true);

public static final ConfigKey<Long> QuotaActivationRuleTimeout = new ConfigKey<>("Advanced", Long.class, "quota.activationrule.timeout", "2000", "The maximum runtime,"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ public QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Doubl
if (account == null) {
throw new InvalidParameterValueException("Account does not exist with account id " + accountId);
}
final boolean lockAccountEnforcement = "true".equalsIgnoreCase(QuotaConfig.QuotaEnableEnforcement.value());
final boolean lockAccountEnforcement = QuotaConfig.QuotaEnableEnforcement.value();
final BigDecimal currentAccountBalance = _quotaBalanceDao.lastQuotaBalance(accountId, domainId, startOfNextDay(new Date(despositedOn.getTime())));
if (s_logger.isDebugEnabled()) {
s_logger.debug("AddQuotaCredits: Depositing " + amount + " on adjusted date " + despositedOn + ", current balance " + currentAccountBalance);
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/com/cloud/configuration/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@ public enum Config {
ElasticLoadBalancerEnabled(
"Advanced",
ManagementServer.class,
String.class,
Boolean.class,
"network.loadbalancer.basiczone.elb.enabled",
"false",
"Whether the load balancing service is enabled for basic zones",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
import org.apache.cloudstack.config.ApiServiceConfiguration;
import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.StorageOrchestrationService;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
Expand Down Expand Up @@ -592,6 +593,8 @@
weightBasedParametersForValidation.add(CapacityManager.SecondaryStorageCapacityThreshold.key());
weightBasedParametersForValidation.add(ClusterDrsService.ClusterDrsImbalanceThreshold.key());
weightBasedParametersForValidation.add(ClusterDrsService.ClusterDrsImbalanceSkipThreshold.key());
weightBasedParametersForValidation.add(StorageOrchestrationService.ImageStoreImbalanceThreshold.key());
weightBasedParametersForValidation.add(AlertManager.Ipv6SubnetCapacityThreshold.key());
}

private void overProvisioningFactorsForValidation() {
Expand Down Expand Up @@ -1203,7 +1206,7 @@
return "Invalid scope id provided for the parameter " + name;
}
}
Class<?> type = null;
Class<?> type;
final Config configuration = Config.getConfig(name);
if (configuration == null) {
s_logger.warn("Did not find configuration " + name + " in Config.java. Perhaps moved to ConfigDepot");
Expand All @@ -1216,25 +1219,10 @@
} else {
type = configuration.getType();
}

//no need to validate further if a
//config can have null value.
String errMsg = null;
try {
if (type.equals(Integer.class)) {
errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid integer value for parameter " + name;
Integer.parseInt(value);
} else if (type.equals(Float.class)) {
errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid float value for parameter " + name;
Float.parseFloat(value);
} else if (type.equals(Long.class)) {
errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid long value for parameter " + name;
Long.parseLong(value);
}
} catch (final Exception e) {
// catching generic exception as some throws NullPointerException and some throws NumberFormatExcpeion
s_logger.error(errMsg);
return errMsg;
}
String errMsg = validateConfigValueAndType(name, value, type);

if (value == null) {
if (type.equals(Boolean.class)) {
Expand Down Expand Up @@ -1326,6 +1314,18 @@
}
}

if (type.equals(Double.class)) {
try {
final Double val = Double.parseDouble(value);

Check warning on line 1319 in server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java#L1318-L1319

Added lines #L1318 - L1319 were not covered by tests
if (weightBasedParametersForValidation.contains(name) && (val < 0f || val > 1f)) {
Copy link
Preview

Copilot AI Jun 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using double literals (0.0 and 1.0) instead of float literals (0f and 1f) for clarity when comparing Double values.

Suggested change
if (weightBasedParametersForValidation.contains(name) && (val < 0f || val > 1f)) {
if (weightBasedParametersForValidation.contains(name) && (val < 0.0 || val > 1.0)) {

Copilot uses AI. Check for mistakes.

throw new InvalidParameterValueException("Please enter a value between 0 and 1 for the configuration parameter: " + name);

Check warning on line 1321 in server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java#L1321

Added line #L1321 was not covered by tests
}
} catch (final NumberFormatException e) {
s_logger.error("There was an error trying to parse the double value for configuration parameter: " + name);
throw new InvalidParameterValueException("There was an error trying to parse the double value for configuration parameter: " + name);
}

Check warning on line 1326 in server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java#L1323-L1326

Added lines #L1323 - L1326 were not covered by tests
}

if (type.equals(String.class)) {
if (name.equalsIgnoreCase(SecStorageAllowedInternalDownloadSites.key()) && StringUtils.isNotEmpty(value)) {
final String[] cidrs = value.split(",");
Expand Down Expand Up @@ -1384,6 +1384,30 @@
}
}

private String validateConfigValueAndType(String name, String value, Class<?> type) {
String errMsg = null;
try {
if (type.equals(Integer.class)) {
errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid integer value for parameter " + name;
Integer.parseInt(value);
} else if (type.equals(Float.class)) {
errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid float value for parameter " + name;
Float.parseFloat(value);

Check warning on line 1395 in server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java#L1394-L1395

Added lines #L1394 - L1395 were not covered by tests
} else if (type.equals(Long.class)) {
errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid long value for parameter " + name;
Long.parseLong(value);

Check warning on line 1398 in server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java#L1397-L1398

Added lines #L1397 - L1398 were not covered by tests
} else if (type.equals(Double.class)) {
errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid double value for parameter " + name;
Double.parseDouble(value);

Check warning on line 1401 in server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java#L1400-L1401

Added lines #L1400 - L1401 were not covered by tests
}
} catch (final Exception e) {

Check warning on line 1403 in server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java#L1403

Added line #L1403 was not covered by tests
// catching generic exception as some throws NullPointerException and some throws NumberFormatExcpeion
s_logger.error(errMsg);
return errMsg;

Check warning on line 1406 in server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java#L1405-L1406

Added lines #L1405 - L1406 were not covered by tests
}
return errMsg;
}

/**
* A valid value should be an integer between min and max (the values from the range).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = name;
String elbEnabledString = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key());
_elbEnabled = Boolean.parseBoolean(elbEnabledString);
_elbEnabled = elbEnabledString == null ? false : Boolean.parseBoolean(elbEnabledString);
if (_ipAddrMgr.RulesContinueOnError.value() != null) {
rulesContinueOnErrFlag = _ipAddrMgr.RulesContinueOnError.value();
}
Expand Down
13 changes: 0 additions & 13 deletions server/src/main/java/com/cloud/storage/ImageStoreServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.StorageOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.storage.ImageStoreService;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
Expand All @@ -59,18 +58,6 @@ public class ImageStoreServiceImpl extends ManagerBase implements ImageStoreServ
@Inject
public UUIDManager uuidMgr;

ConfigKey<Double> ImageStoreImbalanceThreshold = new ConfigKey<>("Advanced", Double.class,
"image.store.imbalance.threshold",
"0.3",
"The storage imbalance threshold that is compared with the standard deviation percentage for a storage utilization metric. " +
"The value is a percentage in decimal format.",
true, ConfigKey.Scope.Global);


public Integer numConcurrentCopyTasksPerSSVM = null;



@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
return true;
Expand Down
Loading