This is an automated email from the ASF dual-hosted git repository.
smolnar82 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new c3f55243f KNOX-3356: Allow Cloudera Manager service discovery over
cleartext HTTP (#1272)
c3f55243f is described below
commit c3f55243fba023261ae91b80b5534aaa460ed114
Author: Sandor Molnar <[email protected]>
AuthorDate: Fri Jun 19 17:46:10 2026 +0200
KNOX-3356: Allow Cloudera Manager service discovery over cleartext HTTP
(#1272)
---
.../ClouderaManagerServiceDiscoveryMessages.java | 3 +++
.../topology/discovery/cm/DiscoveryApiClient.java | 14 ++++++++++
.../cm/ClouderaManagerServiceDiscoveryTest.java | 30 +++++++++++++++++++++-
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java
index d025fdf05..30155c4d9 100644
---
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java
@@ -280,6 +280,9 @@ public interface ClouderaManagerServiceDiscoveryMessages {
@Message(level = MessageLevel.ERROR, text = "Failed to configure truststore")
void failedToConfigureTruststore();
+ @Message(level = MessageLevel.DEBUG, text = "Skipping SSL configuration for
cleartext CM discovery address {0}")
+ void skippingSslConfigurationForCleartextAddress(String address);
+
@Message(level = MessageLevel.DEBUG, text = "Looking up cluster services
from service discovery repository...")
void lookupClusterServicesFromRepository();
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/DiscoveryApiClient.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/DiscoveryApiClient.java
index f74203b61..27e240ca5 100644
---
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/DiscoveryApiClient.java
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/DiscoveryApiClient.java
@@ -20,6 +20,7 @@ import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Locale;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
@@ -155,6 +156,11 @@ public class DiscoveryApiClient extends ApiClient {
return (address.endsWith("/") ? address + apiPath : address + "/" +
apiPath);
}
+ private boolean isSecure() {
+ final String basePath = getBasePath();
+ return basePath != null &&
basePath.toLowerCase(Locale.ROOT).startsWith("https:");
+ }
+
private void configureInterceptors(List<Interceptor> interceptors) {
final OkHttpClient.Builder builder = getHttpClient().newBuilder();
interceptors.forEach(builder::addInterceptor);
@@ -172,6 +178,14 @@ public class DiscoveryApiClient extends ApiClient {
}
private void configureSsl(GatewayConfig gatewayConfig, KeyStore trustStore) {
+ // The CM discovery endpoint may be plain HTTP (e.g. CM TLS not enabled).
In that case the
+ // TLS-only ConnectionSpec below would make OkHttp reject the connection
with
+ // "CLEARTEXT communication not enabled for client". Only configure TLS
for HTTPS addresses.
+ if (!isSecure()) {
+ log.skippingSslConfigurationForCleartextAddress(getBasePath());
+ return;
+ }
+
final SSLContext truststoreSSLContext =
TruststoreSSLContextUtils.getTruststoreSSLContext(trustStore);
final X509TrustManager trustManager =
TruststoreSSLContextUtils.getTrustManager(trustStore);
diff --git
a/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
b/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
index adaaaf35a..9437913ad 100644
---
a/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
+++
b/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
@@ -91,6 +91,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class ClouderaManagerServiceDiscoveryTest {
private static final String DISCOVERY_URL = "http://localhost:1234";
+ private static final String DISCOVERY_URL_TLS = "https://localhost:1234";
private static final String DISCOVERY_USER = "discoveryUser";
private static final String CLUSTER_NAME = "Cluster 1";
private static final String DISCOVERY_PASSWORD_ALIAS = "discovery.alias";
@@ -164,7 +165,7 @@ public class ClouderaManagerServiceDiscoveryTest {
EasyMock.expect(gwConf.getClouderaManagerClientSSLProtocols()).andReturn(Set.of(cmClientTlsVersion)).anyTimes();
EasyMock.replay(gwConf);
- ServiceDiscoveryConfig sdConfig = createMockDiscoveryConfig(DISCOVERY_URL,
DISCOVERY_USER, CLUSTER_NAME);
+ ServiceDiscoveryConfig sdConfig =
createMockDiscoveryConfig(DISCOVERY_URL_TLS, DISCOVERY_USER, CLUSTER_NAME);
AliasService aliasService = EasyMock.createNiceMock(AliasService.class);
EasyMock.replay(aliasService);
@@ -195,6 +196,33 @@ public class ClouderaManagerServiceDiscoveryTest {
assertTrue(containsTlsVersion(connectionSpecs.get(0).tlsVersions(),
cmClientTlsVersion));
}
+ /**
+ * KNOX-3353: when the CM discovery address is plain HTTP (CM TLS not
enabled), the client must
+ * not be locked to a TLS-only ConnectionSpec, otherwise OkHttp rejects the
request with
+ * "CLEARTEXT communication not enabled for client". The default specs
(which include CLEARTEXT)
+ * should be left in place.
+ */
+ @Test
+ public void testApiClientAllowsCleartextForHttpDiscoveryAddress() {
+ GatewayConfig gwConf = EasyMock.createNiceMock(GatewayConfig.class);
+
EasyMock.expect(gwConf.getClouderaManagerServiceDiscoveryApiVersion()).andReturn(GatewayConfig.DEFAULT_CLOUDERA_MANAGER_SERVICE_DISCOVERY_API_VERSION).anyTimes();
+ EasyMock.replay(gwConf);
+
+ ServiceDiscoveryConfig sdConfig = createMockDiscoveryConfig(DISCOVERY_URL,
DISCOVERY_USER, CLUSTER_NAME);
+
+ AliasService aliasService = EasyMock.createNiceMock(AliasService.class);
+ EasyMock.replay(aliasService);
+
+ KeyStore trustStore = EasyMock.createNiceMock(KeyStore.class);
+ EasyMock.replay(trustStore);
+
+ ApiClient apiClient = new TestDiscoveryApiClient(gwConf, sdConfig,
aliasService, trustStore);
+
+ final List<ConnectionSpec> connectionSpecs =
apiClient.getHttpClient().connectionSpecs();
+ assertTrue("HTTP discovery address should keep a CLEARTEXT-capable
connection spec.",
+ connectionSpecs.stream().anyMatch(spec ->
spec.equals(ConnectionSpec.CLEARTEXT)));
+ }
+
private boolean containsCipherSuite(List<CipherSuite> cipherSuites, String
cipherSuiteNameToCheck) {
return cipherSuites.stream().anyMatch(cipherSuite ->
cipherSuite.javaName().equals(cipherSuiteNameToCheck));
}