diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/OperationContext.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/OperationContext.java index f9fb91eccfd..e4cf23a8042 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/OperationContext.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/OperationContext.java @@ -22,7 +22,6 @@ import io.fabric8.kubernetes.api.model.DeletionPropagation; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.http.HttpClient; -import io.fabric8.kubernetes.client.internal.okhttp.OkHttpClientImpl; import io.fabric8.kubernetes.client.utils.ApiVersionUtil; import io.fabric8.kubernetes.client.utils.Utils; diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/http/HttpClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/http/HttpClient.java index 1230083145a..c457a544852 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/http/HttpClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/http/HttpClient.java @@ -22,6 +22,7 @@ import javax.net.ssl.TrustManager; import java.io.IOException; +import java.net.InetSocketAddress; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -52,6 +53,16 @@ public interface Builder { Builder authenticatorNone(); Builder sslContext(SSLContext context, TrustManager[] trustManagers); + + Builder followAllRedirects(); + + Builder proxyAddress(InetSocketAddress proxyAddress); + + Builder proxyAuthorization(String credentials); + + Builder tlsVersions(TlsVersion[] tlsVersions); + + Builder preferHttp11(); } @Override diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/http/TlsVersion.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/http/TlsVersion.java index 48fbfacde95..6df3309c543 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/http/TlsVersion.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/http/TlsVersion.java @@ -18,13 +18,23 @@ /** * TODO: determine if java names should be used here as well or instead + * + * Replacement for okhttp3.TlsVersion */ public enum TlsVersion { - TLS_1_3, - TLS_1_2, - TLS_1_1, - TLS_1_0, - SSL_3_0; + + TLS_1_3("TLSv1.3"), + TLS_1_2("TLSv1.2"), + TLS_1_1("TLSv1.1"), + TLS_1_0("TLSv1"), + SSL_3_0("SSLv3"), + ; + + final String javaName; + + TlsVersion(String javaName) { + this.javaName = javaName; + } public static TlsVersion forJavaName(String string) { if (string.equals("SSLv3")) { @@ -36,4 +46,8 @@ public static TlsVersion forJavaName(String string) { return TlsVersion.valueOf(string.replaceAll("[v.]", "_")); } + public String javaName() { + return javaName; + } + } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientBuilderImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientBuilderImpl.java new file mode 100644 index 00000000000..626d1720ac9 --- /dev/null +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientBuilderImpl.java @@ -0,0 +1,209 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed 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 io.fabric8.kubernetes.client.internal.okhttp; + +import io.fabric8.kubernetes.client.http.HttpClient; +import io.fabric8.kubernetes.client.http.HttpClient.Builder; +import io.fabric8.kubernetes.client.http.TlsVersion; +import io.fabric8.kubernetes.client.internal.okhttp.OkHttpClientImpl.OkHttpResponseImpl; +import okhttp3.Authenticator; +import okhttp3.ConnectionSpec; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.logging.HttpLoggingInterceptor; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import java.io.IOException; +import java.io.InputStream; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static okhttp3.ConnectionSpec.CLEARTEXT; + +public class OkHttpClientBuilderImpl implements Builder { + + static final class InteceptorAdapter implements Interceptor { + private final io.fabric8.kubernetes.client.http.Interceptor interceptor; + private final String name; + + private InteceptorAdapter(io.fabric8.kubernetes.client.http.Interceptor interceptor, String name) { + this.interceptor = interceptor; + this.name = name; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request.Builder requestBuilder = chain.request().newBuilder(); + OkHttpRequestImpl.BuilderImpl builderImpl = new OkHttpRequestImpl.BuilderImpl(requestBuilder); + interceptor.before(new OkHttpRequestImpl.BuilderImpl(requestBuilder), new OkHttpRequestImpl(chain.request())); + Response response = chain.proceed(requestBuilder.build()); + if (!response.isSuccessful()) { + boolean call = interceptor.afterFailure(builderImpl, new OkHttpResponseImpl<>(response, InputStream.class)); + if (call) { + return chain.proceed(requestBuilder.build()); + } + } + return response; + } + + public String getName() { + return name; + } + } + + private boolean streaming; + private OkHttpClient.Builder builder; + + public OkHttpClientBuilderImpl(okhttp3.OkHttpClient.Builder newBuilder) { + this.builder = newBuilder; + } + + @Override + public HttpClient build() { + OkHttpClient client = builder.build(); + + if (streaming) { + // If we set the HttpLoggingInterceptor's logging level to Body (as it is by default), it does + // not let us stream responses from the server. + for (Interceptor i : client.networkInterceptors()) { + if (i instanceof HttpLoggingInterceptor) { + HttpLoggingInterceptor interceptor = (HttpLoggingInterceptor) i; + interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); + } + } + } + + return new OkHttpClientImpl(client); + } + + @Override + public Builder readTimeout(long readTimeout, TimeUnit unit) { + builder.readTimeout(readTimeout, unit); + return this; + } + + @Override + public Builder connectTimeout(long connectTimeout, TimeUnit unit) { + builder.connectTimeout(connectTimeout, unit); + return this; + } + + @Override + public Builder writeTimeout(long timeout, TimeUnit timeoutUnit) { + builder.writeTimeout(timeout, timeoutUnit); + return this; + } + + @Override + public Builder forStreaming() { + builder.cache(null); + this.streaming = true; + return this; + } + + @Override + public Builder addOrReplaceInterceptor(String name, io.fabric8.kubernetes.client.http.Interceptor interceptor) { + List interceptors = builder.interceptors(); + for (int i = 0; i < interceptors.size(); i++) { + Interceptor exiting = interceptors.get(i); + if (exiting instanceof InteceptorAdapter) { + InteceptorAdapter adapter = (InteceptorAdapter)exiting; + if (adapter.getName().equals(name)) { + if (interceptor == null) { + interceptors.remove(i); + } else { + interceptors.set(i, new InteceptorAdapter(interceptor, name)); + } + return this; + } + } + } + if (interceptor != null) { + builder.addInterceptor(new InteceptorAdapter(interceptor, name)); + } + return this; + } + + @Override + public Builder authenticatorNone() { + builder.authenticator(Authenticator.NONE); + return this; + } + + @Override + public Builder sslContext(SSLContext context, TrustManager[] trustManagers) { + X509TrustManager trustManager = null; + if (trustManagers != null && trustManagers.length == 1) { + trustManager = (X509TrustManager) trustManagers[0]; + } + builder.sslSocketFactory(context.getSocketFactory(), trustManager); + return this; + } + + @Override + public Builder followAllRedirects() { + builder.followRedirects(true).followSslRedirects(true); + return this; + } + + @Override + public Builder proxyAddress(InetSocketAddress proxyAddress) { + if (proxyAddress == null) { + builder.proxy(Proxy.NO_PROXY); + } else { + builder.proxy(new Proxy(Proxy.Type.HTTP, proxyAddress)); + } + return this; + } + + @Override + public Builder proxyAuthorization(String credentials) { + builder.proxyAuthenticator((route, response) -> { + return response.request().newBuilder().header("Proxy-Authorization", credentials).build(); + }); + return this; + } + + @Override + public Builder tlsVersions(TlsVersion[] tlsVersions) { + ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + .tlsVersions(Arrays.asList(tlsVersions) + .stream() + .map(tls -> okhttp3.TlsVersion.valueOf(tls.name())) + .toArray(okhttp3.TlsVersion[]::new)) + .build(); + builder.connectionSpecs(Arrays.asList(spec, CLEARTEXT)); + return this; + } + + @Override + public Builder preferHttp11() { + builder.protocols(Collections.singletonList(Protocol.HTTP_1_1)); + return this; + } + +} \ No newline at end of file diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientFactory.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientFactory.java index d7eed8773b9..9f538deef3b 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientFactory.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientFactory.java @@ -20,34 +20,16 @@ import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.http.HttpClient; import io.fabric8.kubernetes.client.http.HttpClient.Builder; -import io.fabric8.kubernetes.client.internal.SSLUtils; import io.fabric8.kubernetes.client.utils.HttpClientUtils; -import okhttp3.ConnectionSpec; -import okhttp3.Credentials; import okhttp3.Dispatcher; import okhttp3.OkHttpClient; -import okhttp3.Protocol; -import okhttp3.TlsVersion; import okhttp3.logging.HttpLoggingInterceptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.net.ssl.KeyManager; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; - -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.Proxy; -import java.net.URL; -import java.util.Arrays; -import java.util.Collections; -import java.util.Locale; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; -import static okhttp3.ConnectionSpec.CLEARTEXT; - public class OkHttpClientFactory implements HttpClient.Factory { @Override @@ -57,7 +39,7 @@ public HttpClient createHttpClient(Config config) { @Override public Builder newBuilder() { - return OkHttpClientImpl.builder(); + return new OkHttpClientBuilderImpl(new OkHttpClient.Builder()); } /** @@ -66,15 +48,11 @@ public Builder newBuilder() { * @param additionalConfig a consumer that allows overriding HTTP client properties * @return returns an HTTP client */ - public static io.fabric8.kubernetes.client.http.HttpClient createHttpClient(final Config config, + public static io.fabric8.kubernetes.client.http.HttpClient createHttpClient(Config config, final Consumer additionalConfig) { try { OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); - // Follow any redirects - httpClientBuilder.followRedirects(true); - httpClientBuilder.followSslRedirects(true); - if (config.isTrustCerts() || config.isDisableHostnameVerification()) { httpClientBuilder.hostnameVerifier((s, sslSession) -> true); } @@ -86,14 +64,6 @@ public static io.fabric8.kubernetes.client.http.HttpClient createHttpClient(fina httpClientBuilder.addNetworkInterceptor(loggingInterceptor); } - if (config.getConnectionTimeout() > 0) { - httpClientBuilder.connectTimeout(config.getConnectionTimeout(), TimeUnit.MILLISECONDS); - } - - if (config.getRequestTimeout() > 0) { - httpClientBuilder.readTimeout(config.getRequestTimeout(), TimeUnit.MILLISECONDS); - } - if (config.getWebsocketPingInterval() > 0) { httpClientBuilder.pingInterval(config.getWebsocketPingInterval(), TimeUnit.MILLISECONDS); } @@ -105,59 +75,18 @@ public static io.fabric8.kubernetes.client.http.HttpClient createHttpClient(fina httpClientBuilder.dispatcher(dispatcher); } - // Only check proxy if it's a full URL with protocol - if (config.getMasterUrl().toLowerCase(Locale.ROOT).startsWith(Config.HTTP_PROTOCOL_PREFIX) - || config.getMasterUrl().startsWith(Config.HTTPS_PROTOCOL_PREFIX)) { - try { - URL proxyUrl = HttpClientUtils.getProxyUrl(config); - if (proxyUrl != null) { - httpClientBuilder - .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyUrl.getHost(), proxyUrl.getPort()))); - - if (config.getProxyUsername() != null) { - httpClientBuilder.proxyAuthenticator((route, response) -> { + Builder builderWrapper = new OkHttpClientBuilderImpl(httpClientBuilder); - String credential = Credentials.basic(config.getProxyUsername(), config.getProxyPassword()); - return response.request().newBuilder().header("Proxy-Authorization", credential).build(); - }); - } - } else { - httpClientBuilder.proxy(Proxy.NO_PROXY); - } - - } catch (MalformedURLException e) { - throw new KubernetesClientException("Invalid proxy server configuration", e); - } - } - - if (config.getTlsVersions() != null && config.getTlsVersions().length > 0) { - ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) - .tlsVersions(Arrays.asList(config.getTlsVersions()) - .stream() - .map(tls -> TlsVersion.valueOf(tls.name())) - .toArray(TlsVersion[]::new)) - .build(); - httpClientBuilder.connectionSpecs(Arrays.asList(spec, CLEARTEXT)); - } - - if (shouldDisableHttp2() || config.isHttp2Disable()) { - httpClientBuilder.protocols(Collections.singletonList(Protocol.HTTP_1_1)); + HttpClientUtils.applyCommonConfiguration(config, builderWrapper); + + if (shouldDisableHttp2() && !config.isHttp2Disable()) { + builderWrapper.preferHttp11(); } - + if (additionalConfig != null) { additionalConfig.accept(httpClientBuilder); } - Builder builderWrapper = new OkHttpClientImpl.BuilderImpl(httpClientBuilder); - - // TODO: the rest can be moved to common logic - TrustManager[] trustManagers = SSLUtils.trustManagers(config); - KeyManager[] keyManagers = SSLUtils.keyManagers(config); - - SSLContext sslContext = SSLUtils.sslContext(keyManagers, trustManagers); - builderWrapper.sslContext(sslContext, trustManagers); - - HttpClientUtils.createApplicableInterceptors(config).forEach((s, i) -> builderWrapper.addOrReplaceInterceptor(s, i)); return builderWrapper.build(); } catch (Exception e) { throw KubernetesClientException.launderThrowable(e); diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientImpl.java index aa88be1e3b1..9ce97fb68cf 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal/okhttp/OkHttpClientImpl.java @@ -19,25 +19,16 @@ import io.fabric8.kubernetes.client.http.HttpClient; import io.fabric8.kubernetes.client.http.HttpRequest; import io.fabric8.kubernetes.client.http.HttpResponse; -import okhttp3.Authenticator; import okhttp3.Call; import okhttp3.Callback; import okhttp3.ConnectionPool; import okhttp3.Dispatcher; -import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.OkHttpClient; -import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; -import okhttp3.logging.HttpLoggingInterceptor; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; import java.io.IOException; -import java.io.InputStream; import java.io.Reader; import java.util.HashMap; import java.util.List; @@ -45,7 +36,6 @@ import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; -import java.util.concurrent.TimeUnit; public class OkHttpClientImpl implements HttpClient { @@ -56,10 +46,6 @@ public class OkHttpClientImpl implements HttpClient { public static final MediaType STRATEGIC_MERGE_JSON_PATCH = parseMediaType("application/strategic-merge-patch+json"); public static final MediaType JSON_MERGE_PATCH = parseMediaType("application/merge-patch+json"); - public static Builder builder() { - return new BuilderImpl(new OkHttpClient.Builder()); - } - static MediaType parseMediaType(String contentType) { MediaType result = MediaType.parse(contentType); MEDIA_TYPES.put(contentType, result); @@ -122,128 +108,6 @@ public List headers(String key) { } - private static final class InteceptorAdapter implements Interceptor { - private final io.fabric8.kubernetes.client.http.Interceptor interceptor; - private final String name; - - private InteceptorAdapter(io.fabric8.kubernetes.client.http.Interceptor interceptor, String name) { - this.interceptor = interceptor; - this.name = name; - } - - @Override - public Response intercept(Chain chain) throws IOException { - Request.Builder requestBuilder = chain.request().newBuilder(); - OkHttpRequestImpl.BuilderImpl builderImpl = new OkHttpRequestImpl.BuilderImpl(requestBuilder); - interceptor.before(new OkHttpRequestImpl.BuilderImpl(requestBuilder), new OkHttpRequestImpl(chain.request())); - Response response = chain.proceed(requestBuilder.build()); - if (!response.isSuccessful()) { - boolean call = interceptor.afterFailure(builderImpl, new OkHttpResponseImpl<>(response, InputStream.class)); - if (call) { - return chain.proceed(requestBuilder.build()); - } - } - return response; - } - - public String getName() { - return name; - } - } - - public static class BuilderImpl implements Builder { - - private boolean streaming; - private OkHttpClient.Builder builder; - - public BuilderImpl(okhttp3.OkHttpClient.Builder newBuilder) { - this.builder = newBuilder; - } - - @Override - public HttpClient build() { - OkHttpClient client = builder.build(); - - if (streaming) { - // If we set the HttpLoggingInterceptor's logging level to Body (as it is by default), it does - // not let us stream responses from the server. - for (Interceptor i : client.networkInterceptors()) { - if (i instanceof HttpLoggingInterceptor) { - HttpLoggingInterceptor interceptor = (HttpLoggingInterceptor) i; - interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); - } - } - } - - return new OkHttpClientImpl(client); - } - - @Override - public Builder readTimeout(long readTimeout, TimeUnit unit) { - builder.readTimeout(readTimeout, unit); - return this; - } - - @Override - public Builder connectTimeout(long connectTimeout, TimeUnit unit) { - builder.connectTimeout(connectTimeout, unit); - return this; - } - - @Override - public Builder writeTimeout(long timeout, TimeUnit timeoutUnit) { - builder.writeTimeout(timeout, timeoutUnit); - return this; - } - - @Override - public Builder forStreaming() { - builder.cache(null); - this.streaming = true; - return this; - } - - @Override - public Builder addOrReplaceInterceptor(String name, io.fabric8.kubernetes.client.http.Interceptor interceptor) { - List interceptors = builder.interceptors(); - for (int i = 0; i < interceptors.size(); i++) { - Interceptor exiting = interceptors.get(i); - if (exiting instanceof InteceptorAdapter) { - InteceptorAdapter adapter = (InteceptorAdapter)exiting; - if (adapter.getName().equals(name)) { - if (interceptor == null) { - interceptors.remove(i); - } else { - interceptors.set(i, new InteceptorAdapter(interceptor, name)); - } - return this; - } - } - } - if (interceptor != null) { - builder.addInterceptor(new InteceptorAdapter(interceptor, name)); - } - return this; - } - - @Override - public Builder authenticatorNone() { - builder.authenticator(Authenticator.NONE); - return this; - } - - @Override - public Builder sslContext(SSLContext context, TrustManager[] trustManagers) { - X509TrustManager trustManager = null; - if (trustManagers != null && trustManagers.length == 1) { - trustManager = (X509TrustManager) trustManagers[0]; - } - builder.sslSocketFactory(context.getSocketFactory(), trustManager); - return null; - } - - } - private final okhttp3.OkHttpClient httpClient; public OkHttpClientImpl(OkHttpClient httpClient) { @@ -283,7 +147,7 @@ public void clearPool() { @Override public Builder newBuilder() { - return new BuilderImpl(httpClient.newBuilder()); + return new OkHttpClientBuilderImpl(httpClient.newBuilder()); } @Override diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/HttpClientUtils.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/HttpClientUtils.java index 4b194fa67eb..8350a8da4c5 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/HttpClientUtils.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/HttpClientUtils.java @@ -21,15 +21,22 @@ import io.fabric8.kubernetes.client.http.HttpClient; import io.fabric8.kubernetes.client.http.HttpHeaders; import io.fabric8.kubernetes.client.http.Interceptor; +import io.fabric8.kubernetes.client.internal.SSLUtils; import io.fabric8.kubernetes.client.internal.okhttp.OkHttpClientFactory; -import io.fabric8.kubernetes.client.internal.okhttp.OkHttpClientImpl; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; + +import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.LinkedHashMap; +import java.util.Locale; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -130,6 +137,58 @@ public static HttpClient createHttpClient(Config config) { return new OkHttpClientFactory().createHttpClient(config); } + public static void applyCommonConfiguration(Config config, HttpClient.Builder builder) { + builder.followAllRedirects(); + + if (config.getConnectionTimeout() > 0) { + builder.connectTimeout(config.getConnectionTimeout(), TimeUnit.MILLISECONDS); + } + + if (config.getRequestTimeout() > 0) { + builder.readTimeout(config.getRequestTimeout(), TimeUnit.MILLISECONDS); + } + + if (config.isHttp2Disable()) { + builder.preferHttp11(); + } + + try { + + // Only check proxy if it's a full URL with protocol + if (config.getMasterUrl().toLowerCase(Locale.ROOT).startsWith(Config.HTTP_PROTOCOL_PREFIX) + || config.getMasterUrl().startsWith(Config.HTTPS_PROTOCOL_PREFIX)) { + try { + URL proxyUrl = HttpClientUtils.getProxyUrl(config); + if (proxyUrl != null) { + builder.proxyAddress(new InetSocketAddress(proxyUrl.getHost(), proxyUrl.getPort())); + + if (config.getProxyUsername() != null) { + builder.proxyAuthorization(basicCredentials(config.getProxyUsername(), config.getProxyPassword())); + } + } else { + builder.proxyAddress(null); + } + } catch (MalformedURLException e) { + throw new KubernetesClientException("Invalid proxy server configuration", e); + } + } + + TrustManager[] trustManagers = SSLUtils.trustManagers(config); + KeyManager[] keyManagers = SSLUtils.keyManagers(config); + + SSLContext sslContext = SSLUtils.sslContext(keyManagers, trustManagers); + builder.sslContext(sslContext, trustManagers); + + if (config.getTlsVersions() != null && config.getTlsVersions().length > 0) { + builder.tlsVersions(config.getTlsVersions()); + } + + } catch (Exception e) { + KubernetesClientException.launderThrowable(e); + } + HttpClientUtils.createApplicableInterceptors(config).forEach((s, i) -> builder.addOrReplaceInterceptor(s, i)); + } + public static HttpClient.Builder createHttpClientBuilder() { // TODO: replace with reflection / service load and factory interface return new OkHttpClientFactory().newBuilder();