This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new fa85a75bc88 Log previous and new value of configuration when 
reset/update API is called (#10769)
fa85a75bc88 is described below

commit fa85a75bc88bc8d98d8b859038db7a931736d803
Author: Manoj Kumar <manojkr.it...@gmail.com>
AuthorDate: Wed Jun 4 15:36:25 2025 +0530

    Log previous and new value of configuration when reset/update API is called 
(#10769)
---
 .../cloud/configuration/ConfigurationManager.java  |  6 +-
 .../configuration/ConfigurationManagerImpl.java    | 72 ++++++++++++++--------
 .../ConfigurationManagerImplTest.java              | 16 ++---
 .../cloud/vpc/MockConfigurationManagerImpl.java    |  3 +-
 4 files changed, 61 insertions(+), 36 deletions(-)

diff --git 
a/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
 
b/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
index f172bead7aa..859d1176213 100644
--- 
a/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
+++ 
b/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
@@ -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
diff --git 
a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java 
b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
index ecc72e907c2..908f3d7dad0 100644
--- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -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;
             }
diff --git 
a/server/src/test/java/com/cloud/configuration/ConfigurationManagerImplTest.java
 
b/server/src/test/java/com/cloud/configuration/ConfigurationManagerImplTest.java
index 9b988c0058f..5b0f10f8508 100644
--- 
a/server/src/test/java/com/cloud/configuration/ConfigurationManagerImplTest.java
+++ 
b/server/src/test/java/com/cloud/configuration/ConfigurationManagerImplTest.java
@@ -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);
     }
 
diff --git 
a/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java 
b/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java
index d4f3569cb57..cdd902bcebd 100644
--- a/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java
+++ b/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java
@@ -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;
     }

Reply via email to