Log previous and new value of configuration when reset/update API is called (#10769)

This commit is contained in:
Manoj Kumar 2025-06-04 15:36:25 +05:30 committed by GitHub
parent 7632814cd2
commit fa85a75bc8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 36 deletions

View File

@ -77,12 +77,14 @@ public interface ConfigurationManager {
/**
* Updates a configuration entry with a new value
*
* @param userId
* @param name
* @param category
* @param value
* @param scope
* @param id
*/
String updateConfiguration(long userId, String name, String category, String value, String scope, Long id);
String updateConfiguration(long userId, String name, String category, String value, ConfigKey.Scope scope, Long id);
// /**
// * Creates a new service offering

View File

@ -713,7 +713,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
@Override
@DB
public String updateConfiguration(final long userId, final String name, final String category, String value, final String scope, final Long resourceId) {
public String updateConfiguration(final long userId, final String name, final String category, String value, ConfigKey.Scope scope, final Long resourceId) {
final String validationMsg = validateConfigurationValue(name, value, scope);
if (validationMsg != null) {
logger.error("Invalid value [{}] for configuration [{}] due to [{}].", value, name, validationMsg);
@ -724,15 +724,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
// corresponding details table,
// if scope is mentioned as global or not mentioned then it is normal
// global parameter updation
if (scope != null && !scope.isEmpty() && !ConfigKey.Scope.Global.toString().equalsIgnoreCase(scope)) {
if (scope != null && !ConfigKey.Scope.Global.equals(scope)) {
boolean valueEncrypted = shouldEncryptValue(category);
if (valueEncrypted) {
value = DBEncryptionUtil.encrypt(value);
}
ApiCommandResourceType resourceType;
ConfigKey.Scope scopeVal = ConfigKey.Scope.valueOf(scope);
switch (scopeVal) {
switch (scope) {
case Zone:
final DataCenterVO zone = _zoneDao.findById(resourceId);
if (zone == null) {
@ -831,9 +830,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
CallContext.current().setEventResourceType(resourceType);
CallContext.current().setEventResourceId(resourceId);
CallContext.current().setEventDetails(String.format(" Name: %s, New Value: %s, Scope: %s", name, value, scope));
CallContext.current().setEventDetails(String.format(" Name: %s, New Value: %s, Scope: %s", name, value, scope.name()));
_configDepot.invalidateConfigCache(name, scopeVal, resourceId);
_configDepot.invalidateConfigCache(name, scope, resourceId);
return valueEncrypted ? DBEncryptionUtil.decrypt(value) : value;
}
@ -999,40 +998,40 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
return _configDao.findByName(name);
}
String scope = null;
ConfigKey.Scope scope = null;
Long id = null;
int paramCountCheck = 0;
if (zoneId != null) {
scope = ConfigKey.Scope.Zone.toString();
scope = ConfigKey.Scope.Zone;
id = zoneId;
paramCountCheck++;
}
if (clusterId != null) {
scope = ConfigKey.Scope.Cluster.toString();
scope = ConfigKey.Scope.Cluster;
id = clusterId;
paramCountCheck++;
}
if (accountId != null) {
Account account = _accountMgr.getAccount(accountId);
_accountMgr.checkAccess(caller, null, false, account);
scope = ConfigKey.Scope.Account.toString();
scope = ConfigKey.Scope.Account;
id = accountId;
paramCountCheck++;
}
if (domainId != null) {
_accountMgr.checkAccess(caller, _domainDao.findById(domainId));
scope = ConfigKey.Scope.Domain.toString();
scope = ConfigKey.Scope.Domain;
id = domainId;
paramCountCheck++;
}
if (storagepoolId != null) {
scope = ConfigKey.Scope.StoragePool.toString();
scope = ConfigKey.Scope.StoragePool;
id = storagepoolId;
paramCountCheck++;
}
if (imageStoreId != null) {
scope = ConfigKey.Scope.ImageStore.toString();
scope = ConfigKey.Scope.ImageStore;
id = imageStoreId;
paramCountCheck++;
}
@ -1046,8 +1045,15 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
if (value.isEmpty() || value.equals("null")) {
value = (id == null) ? null : "";
}
String currentValueInScope = getConfigurationValueInScope(config, name, scope, id);
final String updatedValue = updateConfiguration(userId, name, category, value, scope, id);
if (value == null && updatedValue == null || updatedValue.equalsIgnoreCase(value)) {
logger.debug("Config: {} value is updated from: {} to {} for scope: {}", name,
encryptEventValueIfConfigIsEncrypted(config, currentValueInScope),
encryptEventValueIfConfigIsEncrypted(config, value),
scope != null ? scope : ConfigKey.Scope.Global.name());
return _configDao.findByName(name);
} else {
throw new CloudRuntimeException("Unable to update configuration parameter " + name);
@ -1109,7 +1115,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
configScope = config.getScopes();
}
String scope = "";
String scopeVal = "";
Map<String, Long> scopeMap = new LinkedHashMap<>();
Long id = null;
@ -1125,22 +1131,23 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
ParamCountPair paramCountPair = getParamCount(scopeMap);
id = paramCountPair.getId();
paramCountCheck = paramCountPair.getParamCount();
scope = paramCountPair.getScope();
scopeVal = paramCountPair.getScope();
if (paramCountCheck > 1) {
throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
}
if (scope != null) {
ConfigKey.Scope scopeVal = ConfigKey.Scope.valueOf(scope);
if (!scope.equals(ConfigKey.Scope.Global.toString()) && !configScope.contains(scopeVal)) {
if (scopeVal != null) {
ConfigKey.Scope scope = ConfigKey.Scope.valueOf(scopeVal);
if (!scopeVal.equals(ConfigKey.Scope.Global.toString()) && !configScope.contains(scope)) {
throw new InvalidParameterValueException("Invalid scope id provided for the parameter " + name);
}
}
String newValue = null;
ConfigKey.Scope scopeVal = ConfigKey.Scope.valueOf(scope);
switch (scopeVal) {
ConfigKey.Scope scope = ConfigKey.Scope.valueOf(scopeVal);
String currentValueInScope = getConfigurationValueInScope(config, name, scope, id);
switch (scope) {
case Zone:
final DataCenterVO zone = _zoneDao.findById(id);
if (zone == null) {
@ -1225,12 +1232,28 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
newValue = optionalValue.isPresent() ? optionalValue.get().toString() : defaultValue;
}
_configDepot.invalidateConfigCache(name, scopeVal, id);
logger.debug("Config: {} value is updated from: {} to {} for scope: {}", name,
encryptEventValueIfConfigIsEncrypted(config, currentValueInScope),
encryptEventValueIfConfigIsEncrypted(config, newValue), scope);
_configDepot.invalidateConfigCache(name, scope, id);
CallContext.current().setEventDetails(" Name: " + name + " New Value: " + (name.toLowerCase().contains("password") ? "*****" : defaultValue == null ? "" : defaultValue));
return new Pair<Configuration, String>(_configDao.findByName(name), newValue);
}
private String getConfigurationValueInScope(ConfigurationVO config, String name, ConfigKey.Scope scope, Long id) {
String configValue;
if (scope == null || ConfigKey.Scope.Global.equals(scope)) {
configValue = config.getValue();
} else {
ConfigKey<?> configKey = _configDepot.get(name);
Object currentValue = configKey.valueInScope(scope, id);
configValue = currentValue != null ? currentValue.toString() : null;
}
return configValue;
}
/**
* Validates whether a value is valid for the specified configuration. This includes type and range validation.
* @param name name of the configuration.
@ -1238,7 +1261,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
* @param scope scope of the configuration.
* @return null if the value is valid; otherwise, returns an error message.
*/
protected String validateConfigurationValue(String name, String value, String scope) {
protected String validateConfigurationValue(String name, String value, ConfigKey.Scope scope) {
final ConfigurationVO cfg = _configDao.findByName(name);
if (cfg == null) {
logger.error("Missing configuration variable " + name + " in configuration table");
@ -1248,10 +1271,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
List<ConfigKey.Scope> configScope = cfg.getScopes();
if (scope != null) {
ConfigKey.Scope scopeVal = ConfigKey.Scope.valueOf(scope);
if (!configScope.contains(scopeVal) &&
if (!configScope.contains(scope) &&
!(ENABLE_ACCOUNT_SETTINGS_FOR_DOMAIN.value() && configScope.contains(ConfigKey.Scope.Account) &&
scope.equals(ConfigKey.Scope.Domain.toString()))) {
ConfigKey.Scope.Domain.equals(scope))) {
logger.error("Invalid scope id provided for the parameter " + name);
return "Invalid scope id provided for the parameter " + name;
}

View File

@ -459,7 +459,7 @@ public class ConfigurationManagerImplTest {
@Test
public void testValidateInvalidConfiguration() {
Mockito.doReturn(null).when(configDao).findByName(Mockito.anyString());
String msg = configurationManagerImplSpy.validateConfigurationValue("test.config.name", "testvalue", ConfigKey.Scope.Global.toString());
String msg = configurationManagerImplSpy.validateConfigurationValue("test.config.name", "testvalue", ConfigKey.Scope.Global);
Assert.assertEquals("Invalid configuration variable.", msg);
}
@ -468,7 +468,7 @@ public class ConfigurationManagerImplTest {
ConfigurationVO cfg = mock(ConfigurationVO.class);
when(cfg.getScopes()).thenReturn(List.of(ConfigKey.Scope.Account));
Mockito.doReturn(cfg).when(configDao).findByName(Mockito.anyString());
String msg = configurationManagerImplSpy.validateConfigurationValue("test.config.name", "testvalue", ConfigKey.Scope.Domain.toString());
String msg = configurationManagerImplSpy.validateConfigurationValue("test.config.name", "testvalue", ConfigKey.Scope.Domain);
Assert.assertEquals("Invalid scope id provided for the parameter test.config.name", msg);
}
@ -480,7 +480,7 @@ public class ConfigurationManagerImplTest {
Mockito.doReturn(cfg).when(configDao).findByName(Mockito.anyString());
Mockito.doReturn(configKey).when(configurationManagerImplSpy._configDepot).get(configKey.key());
String result = configurationManagerImplSpy.validateConfigurationValue(configKey.key(), "11", configKey.getScopes().get(0).name());
String result = configurationManagerImplSpy.validateConfigurationValue(configKey.key(), "11", configKey.getScopes().get(0));
Assert.assertNotNull(result);
}
@ -492,7 +492,7 @@ public class ConfigurationManagerImplTest {
ConfigKey<Integer> configKey = UnmanagedVMsManager.ThreadsOnKVMHostToImportVMwareVMFiles;
Mockito.doReturn(cfg).when(configDao).findByName(Mockito.anyString());
Mockito.doReturn(configKey).when(configurationManagerImplSpy._configDepot).get(configKey.key());
String msg = configurationManagerImplSpy.validateConfigurationValue(configKey.key(), "10", configKey.getScopes().get(0).name());
String msg = configurationManagerImplSpy.validateConfigurationValue(configKey.key(), "10", configKey.getScopes().get(0));
Assert.assertNull(msg);
}
@ -505,7 +505,7 @@ public class ConfigurationManagerImplTest {
Mockito.doReturn(configKey).when(configurationManagerImplSpy._configDepot).get(configKey.key());
configurationManagerImplSpy.populateConfigValuesForValidationSet();
String result = configurationManagerImplSpy.validateConfigurationValue(configKey.key(), "0", configKey.getScopes().get(0).name());
String result = configurationManagerImplSpy.validateConfigurationValue(configKey.key(), "0", configKey.getScopes().get(0));
Assert.assertNotNull(result);
}
@ -518,7 +518,7 @@ public class ConfigurationManagerImplTest {
Mockito.doReturn(cfg).when(configDao).findByName(Mockito.anyString());
Mockito.doReturn(configKey).when(configurationManagerImplSpy._configDepot).get(configKey.key());
configurationManagerImplSpy.populateConfigValuesForValidationSet();
String msg = configurationManagerImplSpy.validateConfigurationValue(configKey.key(), "9", configKey.getScopes().get(0).name());
String msg = configurationManagerImplSpy.validateConfigurationValue(configKey.key(), "9", configKey.getScopes().get(0));
Assert.assertNull(msg);
}
@ -633,14 +633,14 @@ public class ConfigurationManagerImplTest {
@Test
public void validateConfigurationValueTestValidatesValueType() {
Mockito.when(configKeyMock.type()).thenReturn(Integer.class);
configurationManagerImplSpy.validateConfigurationValue("validate.type", "100", ConfigKey.Scope.Global.name());
configurationManagerImplSpy.validateConfigurationValue("validate.type", "100", ConfigKey.Scope.Global);
Mockito.verify(configurationManagerImplSpy).validateValueType("100", Integer.class);
}
@Test
public void validateConfigurationValueTestValidatesValueRange() {
Mockito.when(configKeyMock.type()).thenReturn(Integer.class);
configurationManagerImplSpy.validateConfigurationValue("validate.range", "100", ConfigKey.Scope.Global.name());
configurationManagerImplSpy.validateConfigurationValue("validate.range", "100", ConfigKey.Scope.Global);
Mockito.verify(configurationManagerImplSpy).validateValueRange("validate.range", "100", Integer.class, null);
}

View File

@ -82,6 +82,7 @@ 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.config.Configuration;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.impl.ConfigurationSubGroupVO;
import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
@ -497,7 +498,7 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
* @see com.cloud.configuration.ConfigurationManager#updateConfiguration(long, java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public String updateConfiguration(long userId, String name, String category, String value, String scope, Long resourceId) {
public String updateConfiguration(long userId, String name, String category, String value, ConfigKey.Scope scope, Long resourceId) {
// TODO Auto-generated method stub
return null;
}