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);
}