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

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


The following commit(s) were added to refs/heads/4.22 by this push:
     new 12f43219528 Changes error message when using invalid `endpoint.url` 
(#8603)
12f43219528 is described below

commit 12f432195284dbd420f20dbb7590d2b27f58621b
Author: Lucas Martins <[email protected]>
AuthorDate: Mon Dec 8 05:41:56 2025 -0300

    Changes error message when using invalid `endpoint.url` (#8603)
    
    Co-authored-by: lucas.martins.scclouds <[email protected]>
    Co-authored-by: Daniel Augusto Veronezi Salvador 
<[email protected]>
    Co-authored-by: erikbocks <[email protected]>
---
 .../cloudstack/config/ApiServiceConfiguration.java | 19 +++++
 .../config/ApiServiceConfigurationTest.java        | 95 ++++++++++++++++++++++
 .../cluster/KubernetesClusterManagerImpl.java      | 15 +---
 .../KubernetesClusterActionWorker.java             |  2 +-
 .../com/cloud/network/as/AutoScaleManagerImpl.java |  5 +-
 .../network/lb/LoadBalancingRulesManagerImpl.java  |  8 +-
 6 files changed, 122 insertions(+), 22 deletions(-)

diff --git 
a/api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java 
b/api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java
index a4aa860487f..113b97f43c8 100644
--- 
a/api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java
+++ 
b/api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java
@@ -16,10 +16,15 @@
 // under the License.
 package org.apache.cloudstack.config;
 
+import com.cloud.exception.InvalidParameterValueException;
 import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 public class ApiServiceConfiguration implements Configurable {
+    protected static Logger LOGGER = 
LogManager.getLogger(ApiServiceConfiguration.class);
     public static final ConfigKey<String> ManagementServerAddresses = new 
ConfigKey<>(String.class, "host", "Advanced", "localhost", "The ip address of 
management server. This can also accept comma separated addresses.", true, 
ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
     public static final ConfigKey<String> ApiServletPath = new 
ConfigKey<String>("Advanced", String.class, "endpoint.url", 
"http://localhost:8080/client/api";,
             "API end point. Can be used by CS components/services deployed 
remotely, for sending CS API requests", true);
@@ -29,6 +34,20 @@ public class ApiServiceConfiguration implements Configurable 
{
             "true", "Are the source checks on API calls enabled (true) or not 
(false)? See api.allowed.source.cidr.list", true, ConfigKey.Scope.Global);
     public static final ConfigKey<String> ApiAllowedSourceCidrList = new 
ConfigKey<>(String.class, "api.allowed.source.cidr.list", "Advanced",
             "0.0.0.0/0,::/0", "Comma separated list of IPv4/IPv6 CIDRs from 
which API calls can be performed. Can be set on Global and Account levels.", 
true, ConfigKey.Scope.Account, null, null, null, null, null, 
ConfigKey.Kind.CSV, null);
+
+
+    public static void validateEndpointUrl() {
+        String csUrl = getApiServletPathValue();
+        if (StringUtils.isBlank(csUrl) || StringUtils.containsAny(csUrl, 
"localhost", "127.0.0.1", "[::1]")) {
+            LOGGER.error("Global setting [{}] cannot contain localhost or be 
blank. Current value: {}", ApiServletPath.key(), csUrl);
+            throw new InvalidParameterValueException("Unable to complete this 
operation. Contact your cloud admin.");
+        }
+    }
+
+    public static String getApiServletPathValue() {
+        return ApiServletPath.value();
+    }
+
     @Override
     public String getConfigComponentName() {
         return ApiServiceConfiguration.class.getSimpleName();
diff --git 
a/api/src/test/java/org/apache/cloudstack/config/ApiServiceConfigurationTest.java
 
b/api/src/test/java/org/apache/cloudstack/config/ApiServiceConfigurationTest.java
new file mode 100644
index 00000000000..4e96af3ead4
--- /dev/null
+++ 
b/api/src/test/java/org/apache/cloudstack/config/ApiServiceConfigurationTest.java
@@ -0,0 +1,95 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.config;
+
+import com.cloud.exception.InvalidParameterValueException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ApiServiceConfigurationTest {
+
+    private static final String LOCALHOST = "http://localhost";;
+
+    private static final String ENDPOINT_URL = 
"https://acs.clouds.com/client/api";;
+
+    private static final String WHITE_SPACE = " ";
+
+    private static final String BLANK_STRING = "";
+
+    private static final String NULL_STRING = null;
+
+    private static final String LOCALHOST_IP = "127.0.0.1";
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void 
validateEndpointUrlTestIfEndpointUrlContainLocalhostShouldThrowInvalidParameterValueException()
 {
+        try (MockedStatic<ApiServiceConfiguration> 
apiServiceConfigurationMockedStatic = 
Mockito.mockStatic(ApiServiceConfiguration.class)) {
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::getApiServletPathValue).thenReturn(LOCALHOST);
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::validateEndpointUrl).thenCallRealMethod();
+            ApiServiceConfiguration.validateEndpointUrl();
+        }
+    }
+
+    @Test
+    public void 
validateEndpointUrlTestIfEndpointUrlContainLocalhostShouldNotThrowInvalidParameterValueException()
 {
+        try (MockedStatic<ApiServiceConfiguration> 
apiServiceConfigurationMockedStatic = 
Mockito.mockStatic(ApiServiceConfiguration.class)) {
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::getApiServletPathValue).thenReturn(ENDPOINT_URL);
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::validateEndpointUrl).thenCallRealMethod();
+            ApiServiceConfiguration.validateEndpointUrl();
+        }
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void 
validateEndpointUrlTestIfEndpointUrlIsNullShouldThrowInvalidParameterValueException()
 {
+        try (MockedStatic<ApiServiceConfiguration> 
apiServiceConfigurationMockedStatic = 
Mockito.mockStatic(ApiServiceConfiguration.class)) {
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::getApiServletPathValue).thenReturn(NULL_STRING);
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::validateEndpointUrl).thenCallRealMethod();
+            ApiServiceConfiguration.validateEndpointUrl();
+        }
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void 
validateEndpointUrlTestIfEndpointUrlIsBlankShouldThrowInvalidParameterValueException()
 {
+        try (MockedStatic<ApiServiceConfiguration> 
apiServiceConfigurationMockedStatic = 
Mockito.mockStatic(ApiServiceConfiguration.class)) {
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::getApiServletPathValue).thenReturn(BLANK_STRING);
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::validateEndpointUrl).thenCallRealMethod();
+            ApiServiceConfiguration.validateEndpointUrl();
+        }
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void 
validateEndpointUrlTestIfEndpointUrlIsWhiteSpaceShouldThrowInvalidParameterValueException()
 {
+        try (MockedStatic<ApiServiceConfiguration> 
apiServiceConfigurationMockedStatic = 
Mockito.mockStatic(ApiServiceConfiguration.class)) {
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::getApiServletPathValue).thenReturn(WHITE_SPACE);
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::validateEndpointUrl).thenCallRealMethod();
+            ApiServiceConfiguration.validateEndpointUrl();
+        }
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void 
validateEndpointUrlTestIfEndpointUrlContainLocalhostIpShouldThrowInvalidParameterValueException()
 {
+        try (MockedStatic<ApiServiceConfiguration> 
apiServiceConfigurationMockedStatic = 
Mockito.mockStatic(ApiServiceConfiguration.class)) {
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::getApiServletPathValue).thenReturn(LOCALHOST_IP);
+            
apiServiceConfigurationMockedStatic.when(ApiServiceConfiguration::validateEndpointUrl).thenCallRealMethod();
+            ApiServiceConfiguration.validateEndpointUrl();
+        }
+    }
+}
diff --git 
a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
 
b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
index 213657db073..422c9072fbf 100644
--- 
a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
+++ 
b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
@@ -905,15 +905,6 @@ public class KubernetesClusterManagerImpl extends 
ManagerBase implements Kuberne
         return response;
     }
 
-    private void validateEndpointUrl() {
-        String csUrl = ApiServiceConfiguration.ApiServletPath.value();
-        if (csUrl == null || csUrl.contains("localhost")) {
-            String error = String.format("Global setting %s has to be set to 
the Management Server's API end point",
-                ApiServiceConfiguration.ApiServletPath.key());
-            throw new InvalidParameterValueException(error);
-        }
-    }
-
     private DataCenter validateAndGetZoneForKubernetesCreateParameters(Long 
zoneId, Long networkId) {
         DataCenter zone = dataCenterDao.findById(zoneId);
         if (zone == null) {
@@ -1008,7 +999,7 @@ public class KubernetesClusterManagerImpl extends 
ManagerBase implements Kuberne
     }
 
     private void validateManagedKubernetesClusterCreateParameters(final 
CreateKubernetesClusterCmd cmd) throws CloudRuntimeException {
-        validateEndpointUrl();
+        ApiServiceConfiguration.validateEndpointUrl();
         final String name = cmd.getName();
         final Long zoneId = cmd.getZoneId();
         final Long kubernetesVersionId = cmd.getKubernetesVersionId();
@@ -1308,7 +1299,7 @@ public class KubernetesClusterManagerImpl extends 
ManagerBase implements Kuberne
                     
KubernetesVersionManagerImpl.MINIMUN_AUTOSCALER_SUPPORTED_VERSION ));
             }
 
-            validateEndpointUrl();
+            ApiServiceConfiguration.validateEndpointUrl();
 
             if (minSize == null || maxSize == null) {
                 throw new InvalidParameterValueException("Autoscaling requires 
minsize and maxsize to be passed");
@@ -1413,7 +1404,7 @@ public class KubernetesClusterManagerImpl extends 
ManagerBase implements Kuberne
 
     private void 
validateKubernetesClusterUpgradeParameters(UpgradeKubernetesClusterCmd cmd) {
         // Validate parameters
-        validateEndpointUrl();
+        ApiServiceConfiguration.validateEndpointUrl();
 
         final Long kubernetesClusterId = cmd.getId();
         final Long upgradeVersionId = cmd.getKubernetesVersionId();
diff --git 
a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorker.java
 
b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorker.java
index baf717612f8..cd334954946 100644
--- 
a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorker.java
+++ 
b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorker.java
@@ -685,7 +685,7 @@ public class KubernetesClusterActionWorker {
 
         try {
             String command = String.format("sudo %s/%s -u '%s' -k '%s' -s 
'%s'",
-                    scriptPath, deploySecretsScriptFilename, 
ApiServiceConfiguration.ApiServletPath.value(), keys[0], keys[1]);
+                scriptPath, deploySecretsScriptFilename, 
ApiServiceConfiguration.getApiServletPathValue(), keys[0], keys[1]);
             Account account = 
accountDao.findById(kubernetesCluster.getAccountId());
             if (account != null && account.getType() == Account.Type.PROJECT) {
                 String projectId = 
projectService.findByProjectAccountId(account.getId()).getUuid();
diff --git 
a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java 
b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java
index 90380b77e44..232c4a6bd68 100644
--- a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java
@@ -512,7 +512,6 @@ public class AutoScaleManagerImpl extends ManagerBase 
implements AutoScaleManage
 
         String apiKey = user.getApiKey();
         String secretKey = user.getSecretKey();
-        String csUrl = ApiServiceConfiguration.ApiServletPath.value();
 
         if (apiKey == null) {
             throw new InvalidParameterValueException("apiKey for user: " + 
user.getUsername() + " is empty. Please generate it");
@@ -522,9 +521,7 @@ public class AutoScaleManagerImpl extends ManagerBase 
implements AutoScaleManage
             throw new InvalidParameterValueException("secretKey for user: " + 
user.getUsername() + " is empty. Please generate it");
         }
 
-        if (csUrl == null || csUrl.contains("localhost")) {
-            throw new InvalidParameterValueException(String.format("Global 
setting %s has to be set to the Management Server's API end point", 
ApiServiceConfiguration.ApiServletPath.key()));
-        }
+        ApiServiceConfiguration.validateEndpointUrl();
     }
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_CREATE, 
eventDescription = "creating autoscale vm profile", create = true)
diff --git 
a/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java 
b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index 5ceebf06dd8..df60553bb8e 100644
--- 
a/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ 
b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -337,7 +337,6 @@ public class LoadBalancingRulesManagerImpl<Type> extends 
ManagerBase implements
 
         String apiKey = null;
         String secretKey = null;
-        String csUrl = ApiServiceConfiguration.ApiServletPath.value();
         Network.Provider provider = getLoadBalancerServiceProvider(lb);
         if (Network.Provider.Netscaler.equals(provider)) {
             Long autoscaleUserId = autoScaleVmProfile.getAutoScaleUserId();
@@ -358,13 +357,12 @@ public class LoadBalancingRulesManagerImpl<Type> extends 
ManagerBase implements
                 throw new InvalidParameterValueException("secretKey for user: 
" + user.getUsername() + " is empty. Please generate it");
             }
 
-            if (csUrl == null || csUrl.contains("localhost")) {
-                throw new InvalidParameterValueException(String.format("Global 
setting %s has to be set to the Management Server's API end point", 
ApiServiceConfiguration.ApiServletPath.key()));
-            }
+            ApiServiceConfiguration.validateEndpointUrl();
         }
 
         LbAutoScaleVmProfile lbAutoScaleVmProfile =
-            new LbAutoScaleVmProfile(autoScaleVmProfile, apiKey, secretKey, 
csUrl, zoneId, domainId, serviceOfferingId, templateId, vmName, lbNetworkUuid);
+            new LbAutoScaleVmProfile(autoScaleVmProfile, apiKey, secretKey, 
ApiServiceConfiguration.getApiServletPathValue(), zoneId, domainId, 
serviceOfferingId, templateId,
+                    vmName, lbNetworkUuid);
         return new LbAutoScaleVmGroup(vmGroup, autoScalePolicies, 
lbAutoScaleVmProfile, currentState);
     }
 

Reply via email to