diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/Config.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/Config.java index 34260a58748..6efdb3016d4 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/Config.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/Config.java @@ -153,6 +153,7 @@ public class Config { private static final int DEFAULT_WATCH_RECONNECT_INTERVAL = 1000; private static final int DEFAULT_CONNECTION_TIMEOUT = 10 * 1000; private static final String DEFAULT_CLIENT_KEY_PASSPHRASE = "changeit"; + private static final String SOCKS5_PROTOCOL_PREFIX = "socks5://"; private Boolean trustCerts; private Boolean disableHostnameVerification; @@ -926,6 +927,18 @@ private static void mergeKubeConfigContents(Config config, String context, io.fa if (currentAuthInfo != null) { mergeKubeConfigAuthInfo(config, currentCluster, currentAuthInfo); } + String proxyUrl = currentCluster.getProxyUrl(); + if (Utils.isNotNullOrEmpty(proxyUrl)) { + if (proxyUrl.startsWith(SOCKS5_PROTOCOL_PREFIX) && config.getMasterUrl().startsWith(HTTPS_PROTOCOL_PREFIX)) { + config.setHttpsProxy(proxyUrl); + } else if (proxyUrl.startsWith(SOCKS5_PROTOCOL_PREFIX)) { + config.setHttpProxy(proxyUrl); + } else if (proxyUrl.startsWith(HTTP_PROTOCOL_PREFIX)) { + config.setHttpProxy(proxyUrl); + } else if (proxyUrl.startsWith(HTTPS_PROTOCOL_PREFIX)) { + config.setHttpsProxy(proxyUrl); + } + } } } diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigProxySourceTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigProxySourceTest.java index fa1ef152670..36b421118e7 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigProxySourceTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigProxySourceTest.java @@ -15,13 +15,19 @@ */ package io.fabric8.kubernetes.client; +import io.fabric8.kubernetes.client.utils.Serialization; import io.fabric8.kubernetes.client.utils.Utils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @@ -223,13 +229,70 @@ void tearDown() { System.clearProperty("kubeconfig"); } - @Test - @Disabled("https://github.com/fabric8io/kubernetes-client/issues/6150") - void noOtherConfiguration() { - // When + Then - assertThat(new ConfigBuilder().build()) - .hasFieldOrPropertyWithValue("httpProxy", null) - .hasFieldOrPropertyWithValue("httpsProxy", "socks5://proxy-via-kubeconfig-proxy-url:1080"); + @Nested + @DisplayName("no other proxy configuration") + class NoOtherConfiguration { + @TempDir + private File temporaryFolder; + + @Test + @DisplayName("proxy-url with sock5 scheme, masterUrl with https scheme, then Config sets httpsProxy") + void whenProxyUrlSocks5MasterUrlHttps_thenHttpsProxySetInConfig() { + // When + Then + assertThat(new ConfigBuilder().build()) + .hasFieldOrPropertyWithValue("httpProxy", null) + .hasFieldOrPropertyWithValue("httpsProxy", "socks5://proxy-via-kubeconfig-proxy-url:1080"); + } + + @Test + @DisplayName("proxy-url with http scheme, then Config sets httpProxy") + void whenProxyUrlHttp_thenHttpProxySetInConfig() throws IOException { + // Given + System.setProperty("kubeconfig", + createKubeConfigWithCluster("http://kubernetes-remote-server.example:6443", "http://proxy-server.example:80") + .getAbsolutePath()); + // When + Then + assertThat(new ConfigBuilder().build()) + .hasFieldOrPropertyWithValue("httpProxy", "http://proxy-server.example:80") + .hasFieldOrPropertyWithValue("httpsProxy", null); + } + + @Test + @DisplayName("proxy-url with https scheme, then Config sets httpsProxy") + void whenProxyUrlHttps_thenHttpsProxySetInConfig() throws IOException { + // Given + System.setProperty("kubeconfig", + createKubeConfigWithCluster("https://kubernetes-remote-server.example:6443", "https://proxy-server.example:80") + .getAbsolutePath()); + // When + Then + assertThat(new ConfigBuilder().build()) + .hasFieldOrPropertyWithValue("httpProxy", null) + .hasFieldOrPropertyWithValue("httpsProxy", "https://proxy-server.example:80"); + } + + @Test + @DisplayName("proxy-url with sock5 scheme, masterUrl with http scheme, then Config sets httpProxy") + void whenProxyUrlSocks5AndMasterUrlHttp_thenHttpProxySetInConfig() throws IOException { + // Given + System.setProperty("kubeconfig", + createKubeConfigWithCluster("http://kubernetes-remote-server.example:6443", "socks5://proxy-server.example:1080") + .getAbsolutePath()); + // When + Then + assertThat(new ConfigBuilder().build()) + .hasFieldOrPropertyWithValue("httpProxy", "socks5://proxy-server.example:1080") + .hasFieldOrPropertyWithValue("httpsProxy", null); + } + + private File createKubeConfigWithCluster(String masterUrl, String proxyUrl) throws IOException { + io.fabric8.kubernetes.api.model.Config kubeConfig = Serialization.unmarshal( + ConfigTest.class.getResourceAsStream("/config-proxy-source/kubeconfig-with-proxy-url"), + io.fabric8.kubernetes.api.model.Config.class); + kubeConfig.getClusters().get(0).getCluster().setServer(masterUrl); + kubeConfig.getClusters().get(0).getCluster().setProxyUrl(proxyUrl); + File updatedKubeConfig = new File(temporaryFolder, "kubeconfig"); + Files.write(updatedKubeConfig.toPath(), Serialization.asYaml(kubeConfig).getBytes(StandardCharsets.UTF_8)); + return updatedKubeConfig; + } } @Test