From 00db1be17b6a074851a2b197f92517fcdc844ef1 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Wed, 24 Jul 2024 18:42:18 +0530 Subject: [PATCH] test: add unit test for old deprecated Config constructor - Add unit test for `@Deprecated` Config constructor. We don't know whether this public constructor is being used by any user. Adding a test just in case to verify that it behaves as expected. - Organize tests in `ConfigTest` to be grouped under various load sources - Add new test `ConfigSourcePrecedenceTest` for verifying Config source load precedence Signed-off-by: Rohan Kumar --- .../client/ConfigSourcePrecedenceTest.java | 225 +++ .../fabric8/kubernetes/client/ConfigTest.java | 1464 +++++++++++------ .../config-source-precedence/kube-config | 33 + .../serviceaccount/ca.crt | 3 + .../serviceaccount/namespace | 1 + .../serviceaccount/token | 1 + .../test/resources/test-serviceaccount/ca.crt | 3 + .../test/resources/test-serviceaccount/token | 1 + .../DisableAutoConfigurationIT.java | 63 + 9 files changed, 1277 insertions(+), 517 deletions(-) create mode 100644 kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigSourcePrecedenceTest.java create mode 100644 kubernetes-client-api/src/test/resources/config-source-precedence/kube-config create mode 100644 kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/ca.crt create mode 100644 kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/namespace create mode 100644 kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/token create mode 100644 kubernetes-client-api/src/test/resources/test-serviceaccount/ca.crt create mode 100644 kubernetes-client-api/src/test/resources/test-serviceaccount/token create mode 100644 kubernetes-itests/src/test/java/io/fabric8/kubernetes/DisableAutoConfigurationIT.java diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigSourcePrecedenceTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigSourcePrecedenceTest.java new file mode 100644 index 00000000000..4c452970d3e --- /dev/null +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigSourcePrecedenceTest.java @@ -0,0 +1,225 @@ +/* + * 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; + +import io.fabric8.kubernetes.client.utils.Utils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +class ConfigSourcePrecedenceTest { + @Nested + @DisplayName("With provided kubeconfig property") + class KubeConfigSource { + @BeforeEach + void setUp() { + System.setProperty("kubeconfig", + Utils.filePath(ConfigSourcePrecedenceTest.class.getResource("/config-source-precedence/kube-config"))); + } + + @Test + @DisplayName("then use kubeconfig attributes in Config") + void whenNoOtherSourceProvided_thenUseKubeConfig() { + // Given + Config config = new ConfigBuilder().build(); + + // When + Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://172.28.128.4:8443/") + .hasFieldOrPropertyWithValue("namespace", "namespace-from-kubeconfig") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token-from-kubeconfig"); + } + + @Test + @DisplayName("And User configuration via builder, then User Configuration via builder takes precedence") + void whenUserConfigurationOverridesSomeFields_thenUserConfigurationGivenPrecedence() { + // Given + Config config = new ConfigBuilder() + .withMasterUrl("https://user-configuration-override:8443") + .withNamespace("namespace-from-user") + .build(); + + // When + Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://user-configuration-override:8443/") + .hasFieldOrPropertyWithValue("namespace", "namespace-from-user") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token-from-kubeconfig"); + } + + @Test + @DisplayName("And System Properties configured, then System Properties take precedence") + void whenSystemPropertiesUsedForSomeFields_thenSystemPropertiesGivenPrecedence() { + try { + // Given + System.setProperty("kubernetes.master", "https://user-configuration-override:8443"); + System.setProperty("kubernetes.auth.token", "token-overridden"); + + // When + Config config = new ConfigBuilder().build(); + + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://user-configuration-override:8443/") + .hasFieldOrPropertyWithValue("namespace", "namespace-from-kubeconfig") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token-overridden"); + } finally { + System.clearProperty("kubernetes.master"); + System.clearProperty("kubernetes.namespace"); + System.clearProperty("kubernetes.auth.token"); + } + } + + @Test + @DisplayName("And Service Account mounted, then kubeconfig takes precedence") + void whenServiceAccountPropertyConfigured_thenDoNotUseServiceAccount() { + try { + // Given + System.setProperty("kubernetes.auth.serviceAccount.token", + Utils.filePath(ConfigSourcePrecedenceTest.class.getResource("/config-source-precedence/serviceaccount/token"))); + System.setProperty("kubenamespace", + Utils.filePath(ConfigSourcePrecedenceTest.class.getResource("/config-source-precedence/serviceaccount/namespace"))); + Config config = new ConfigBuilder().build(); + + // When + Then + assertThat(config) + .hasFieldOrPropertyWithValue("namespace", "namespace-from-kubeconfig") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token-from-kubeconfig"); + } finally { + System.clearProperty("kubernetes.auth.serviceAccount.token"); + System.clearProperty("kubenamespace"); + } + } + } + + @Nested + @DisplayName("With ServiceAccount mounted") + class InsideKubernetesCluster { + @BeforeEach + void setUp() { + System.setProperty("kubeconfig", "/dev/null"); + System.setProperty("kubernetes.auth.serviceAccount.token", + Utils.filePath(ConfigSourcePrecedenceTest.class.getResource("/config-source-precedence/serviceaccount/token"))); + System.setProperty("kubenamespace", + Utils.filePath(ConfigSourcePrecedenceTest.class.getResource("/config-source-precedence/serviceaccount/namespace"))); + } + + @Test + @DisplayName("then use ServiceAccount attributes in Config") + void whenNoOtherSourceProvided_thenUseServiceAccount() { + // Given + Config config = new ConfigBuilder().build(); + + // When + Then + assertThat(config) + .hasFieldOrPropertyWithValue("namespace", "namespace-from-mounted-serviceaccount") + .extracting(Config::getAutoOAuthToken) + .asString() + .contains("token-from-mounted-serviceaccount"); + } + + @Test + @DisplayName("And User configuration via builder, then User Configuration takes precedence") + void whenUserConfigurationOverridesSomeFields_thenUserConfigurationGivenPrecedence() { + // Given + Config config = new ConfigBuilder() + .withMasterUrl("https://user-configuration-override:8443") + .withNamespace("namespace-from-user") + .build(); + + // When + Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://user-configuration-override:8443/") + .hasFieldOrPropertyWithValue("namespace", "namespace-from-user") + .extracting(Config::getAutoOAuthToken) + .asString() + .contains("token-from-mounted-serviceaccount"); + } + + @Test + @DisplayName("And System Properties configured, then System Properties takes precedence") + void whenSystemPropertiesUsedForSomeFields_thenSystemPropertiesGivenPrecedence() { + try { + System.setProperty("kubernetes.master", "https://properties-configuration-override:8443"); + System.setProperty("kubernetes.auth.token", "token-from-properties"); + Config config = new ConfigBuilder().build(); + + // When + Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://properties-configuration-override:8443/") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token-from-properties") + .hasFieldOrPropertyWithValue("namespace", "namespace-from-mounted-serviceaccount"); + } finally { + System.clearProperty("kubernetes.master"); + System.clearProperty("kubernetes.namespace"); + System.clearProperty("kubernetes.auth.token"); + } + } + + @AfterEach + void tearDown() { + System.clearProperty("kubernetes.auth.serviceAccount.token"); + System.clearProperty("kubenamespace"); + System.clearProperty("kubeconfig"); + } + } + + @Nested + @DisplayName("With Provided System Properties") + class SystemPropertiesSource { + @BeforeEach + void setUp() { + System.setProperty("kubernetes.master", "https://property-configuration-override:8443"); + System.setProperty("kubernetes.namespace", "namespace-set-via-properties"); + System.setProperty("kubernetes.auth.token", "token-set-via-properties"); + } + + @Test + @DisplayName("then read from System properties") + void whenNoOtherSourceProvided_thenUseSystemProperties() { + assertThat(new ConfigBuilder().build()) + .hasFieldOrPropertyWithValue("masterUrl", "https://property-configuration-override:8443/") + .hasFieldOrPropertyWithValue("namespace", "namespace-set-via-properties") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token-set-via-properties"); + } + + @Test + @DisplayName("And User configuration via builder, then User Configuration via builder takes precedence") + void whenUserConfigurationOverridesSomeFields_thenUserConfigurationGivenPrecedence() { + // Given + Config config = new ConfigBuilder() + .withMasterUrl("https://user-configuration-override:8443") + .withNamespace("namespace-overridden-by-user") + .build(); + + // When + Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://user-configuration-override:8443/") + .hasFieldOrPropertyWithValue("namespace", "namespace-overridden-by-user") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token-set-via-properties"); + } + + @AfterEach + void tearDown() { + System.clearProperty("kubernetes.master"); + System.clearProperty("kubernetes.namespace"); + System.clearProperty("kubernetes.auth.token"); + } + } +} diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigTest.java index 51ccf348c9d..f8f90b18f31 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/ConfigTest.java @@ -17,13 +17,20 @@ import io.fabric8.kubernetes.api.model.ExecConfig; import io.fabric8.kubernetes.api.model.ExecConfigBuilder; +import io.fabric8.kubernetes.api.model.NamedContext; +import io.fabric8.kubernetes.api.model.NamedContextBuilder; import io.fabric8.kubernetes.client.http.TlsVersion; import io.fabric8.kubernetes.client.lib.FileSystem; import io.fabric8.kubernetes.client.utils.Utils; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; import java.io.File; import java.io.IOException; @@ -39,14 +46,6 @@ import java.util.Objects; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNotSame; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.condition.OS.WINDOWS; class ConfigTest { @@ -93,530 +92,737 @@ class ConfigTest { .filePath(ConfigTest.class.getResource("/test-kubeconfig-exec-win-cert-auth-ec-invalid")); private static final String TEST_CERT_GENERATOR_FILE = Utils.filePath(ConfigTest.class.getResource("/cert-generator")); - @BeforeEach - public void setUp() { - System.getProperties().remove(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_OAUTH_TOKEN_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_AUTH_BASIC_USERNAME_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_AUTH_BASIC_PASSWORD_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_DISABLE_HOSTNAME_VERIFICATION_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_CA_CERTIFICATE_FILE_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_CA_CERTIFICATE_DATA_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_CLIENT_CERTIFICATE_FILE_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_CLIENT_CERTIFICATE_DATA_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_CLIENT_KEY_FILE_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_CLIENT_KEY_DATA_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_CLIENT_KEY_ALGO_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_CLIENT_KEY_PASSPHRASE_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_CLIENT_KEY_FILE_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_MAX_CONCURRENT_REQUESTS); - System.getProperties().remove(Config.KUBERNETES_MAX_CONCURRENT_REQUESTS_PER_HOST); - System.getProperties().remove(Config.KUBERNETES_WATCH_RECONNECT_INTERVAL_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_WATCH_RECONNECT_LIMIT_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_REQUEST_TIMEOUT_SYSTEM_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_HTTP_PROXY); - System.getProperties().remove(Config.KUBERNETES_KUBECONFIG_FILE); - System.getProperties().remove(Config.KUBERNETES_NAMESPACE_FILE); - System.getProperties().remove(Config.KUBERNETES_TLS_VERSIONS); - System.getProperties().remove(Config.KUBERNETES_TRUSTSTORE_FILE_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_TRUSTSTORE_PASSPHRASE_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_KEYSTORE_FILE_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_KEYSTORE_PASSPHRASE_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_SERVICE_HOST_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_SERVICE_PORT_PROPERTY); - System.getProperties().remove(Config.KUBERNETES_IMPERSONATE_USERNAME); - System.getProperties().remove(Config.KUBERNETES_IMPERSONATE_GROUP); - } - - @AfterEach - public void tearDown() { - setUp(); - } - - @Test - void testWithSystemProperties() { - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, "http://somehost:80"); - System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "testns"); - - System.setProperty(Config.KUBERNETES_OAUTH_TOKEN_SYSTEM_PROPERTY, "token"); - System.setProperty(Config.KUBERNETES_AUTH_BASIC_USERNAME_SYSTEM_PROPERTY, "user"); - System.setProperty(Config.KUBERNETES_AUTH_BASIC_PASSWORD_SYSTEM_PROPERTY, "pass"); - System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); - System.setProperty(Config.KUBERNETES_DISABLE_HOSTNAME_VERIFICATION_SYSTEM_PROPERTY, "true"); - System.setProperty(Config.KUBERNETES_CA_CERTIFICATE_FILE_SYSTEM_PROPERTY, "/path/to/cert"); - System.setProperty(Config.KUBERNETES_CA_CERTIFICATE_DATA_SYSTEM_PROPERTY, "cacertdata"); - System.setProperty(Config.KUBERNETES_CLIENT_CERTIFICATE_FILE_SYSTEM_PROPERTY, "/path/to/clientcert"); - System.setProperty(Config.KUBERNETES_CLIENT_CERTIFICATE_DATA_SYSTEM_PROPERTY, "clientcertdata"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_FILE_SYSTEM_PROPERTY, "/path/to/clientkey"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_DATA_SYSTEM_PROPERTY, "clientkeydata"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_ALGO_SYSTEM_PROPERTY, "algo"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_PASSPHRASE_SYSTEM_PROPERTY, "passphrase"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_FILE_SYSTEM_PROPERTY, "/path/to/clientkey"); - System.setProperty(Config.KUBERNETES_MAX_CONCURRENT_REQUESTS, "120"); - System.setProperty(Config.KUBERNETES_MAX_CONCURRENT_REQUESTS_PER_HOST, "20"); - System.setProperty(Config.KUBERNETES_WATCH_RECONNECT_INTERVAL_SYSTEM_PROPERTY, "5000"); - System.setProperty(Config.KUBERNETES_WATCH_RECONNECT_LIMIT_SYSTEM_PROPERTY, "5"); - System.setProperty(Config.KUBERNETES_REQUEST_TIMEOUT_SYSTEM_PROPERTY, "5000"); - System.setProperty(Config.KUBERNETES_HTTP_PROXY, "httpProxy"); - - System.setProperty(Config.KUBERNETES_TLS_VERSIONS, "TLSv1.2,TLSv1.1"); - - System.setProperty(Config.KUBERNETES_TRUSTSTORE_FILE_PROPERTY, "/path/to/truststore"); - System.setProperty(Config.KUBERNETES_TRUSTSTORE_PASSPHRASE_PROPERTY, "truststorePassphrase"); - System.setProperty(Config.KUBERNETES_KEYSTORE_FILE_PROPERTY, "/path/to/keystore"); - System.setProperty(Config.KUBERNETES_KEYSTORE_PASSPHRASE_PROPERTY, "keystorePassphrase"); - - System.setProperty(Config.KUBERNETES_UPLOAD_REQUEST_TIMEOUT_SYSTEM_PROPERTY, "600000"); - - Config config = new Config(); - assertConfig(config, true); - - config = new ConfigBuilder().build(); - assertConfig(config, true); - } - - @Test - void testWithBuilder() { - Config config = new ConfigBuilder() - .withMasterUrl("http://somehost:80") - .withApiVersion("v1") - .withNamespace("testns") - .withOauthToken("token") - .withUsername("user") - .withPassword("pass") - .withTrustCerts(true) - .withDisableHostnameVerification(true) - .withCaCertFile("/path/to/cert") - .withCaCertData("cacertdata") - .withClientCertFile("/path/to/clientcert") - .withClientCertData("clientcertdata") - .withClientKeyFile("/path/to/clientkey") - .withClientKeyData("clientkeydata") - .withClientKeyAlgo("algo") - .withClientKeyPassphrase("passphrase") - .withMaxConcurrentRequests(120) - .withMaxConcurrentRequestsPerHost(20) - .withWatchReconnectInterval(5000) - .withWatchReconnectLimit(5) - .withRequestTimeout(5000) - .withUploadRequestTimeout(600000) - .withHttpProxy("httpProxy") - .withTlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1) - .withTrustStoreFile("/path/to/truststore") - .withTrustStorePassphrase("truststorePassphrase") - .withKeyStoreFile("/path/to/keystore") - .withKeyStorePassphrase("keystorePassphrase") - .build(); + @Nested + @DisplayName("System Properties Configured") + class SystemPropertiesConfigured { + @BeforeEach + void setUp() { + System.setProperty("kubernetes.master", "http://somehost:80"); + System.setProperty("kubernetes.namespace", "testns"); + System.setProperty("kubernetes.auth.token", "token"); + System.setProperty("kubernetes.auth.basic.username", "user"); + System.setProperty("kubernetes.auth.basic.password", "pass"); + System.setProperty("kubernetes.trust.certificates", "true"); + System.setProperty("kubernetes.disable.hostname.verification", "true"); + System.setProperty("kubernetes.certs.ca.file", "/path/to/cert"); + System.setProperty("kubernetes.certs.ca.data", "cacertdata"); + System.setProperty("kubernetes.certs.client.file", "/path/to/clientcert"); + System.setProperty("kubernetes.certs.client.data", "clientcertdata"); + System.setProperty("kubernetes.certs.client.key.file", "/path/to/clientkey"); + System.setProperty("kubernetes.certs.client.key.data", "clientkeydata"); + System.setProperty("kubernetes.certs.client.key.algo", "algo"); + System.setProperty("kubernetes.certs.client.key.passphrase", "passphrase"); + System.setProperty("kubernetes.certs.client.key.file", "/path/to/clientkey"); + System.setProperty("kubernetes.max.concurrent.requests", "120"); + System.setProperty("kubernetes.max.concurrent.requests.per.host", "20"); + System.setProperty("kubernetes.watch.reconnectInterval", "5000"); + System.setProperty("kubernetes.watch.reconnectLimit", "5"); + System.setProperty("kubernetes.request.timeout", "5000"); + System.setProperty("http.proxy", "httpProxy"); + System.setProperty("kubernetes.tls.versions", "TLSv1.2,TLSv1.1"); + System.setProperty("kubernetes.truststore.file", "/path/to/truststore"); + System.setProperty("kubernetes.truststore.passphrase", "truststorePassphrase"); + System.setProperty("kubernetes.keystore.file", "/path/to/keystore"); + System.setProperty("kubernetes.keystore.passphrase", "keystorePassphrase"); + System.setProperty("kubernetes.upload.request.timeout", "600000"); + System.setProperty("kubernetes.websocket.ping.interval", "1000"); + System.setProperty("kubernetes.connection.timeout", "1000"); + System.setProperty("kubernetes.scale.timeout", "1000"); + System.setProperty("https.proxy", "httpsProxy"); + System.setProperty("no.proxy", "no-proxy-url1.io,no-proxy-url2.io"); + System.setProperty("proxy.username", "proxyUsername"); + System.setProperty("proxy.password", "proxyPassword"); + } - assertConfig(config, false); - } + @AfterEach + void tearDown() { + System.clearProperty("kubernetes.master"); + System.clearProperty("kubernetes.namespace"); + System.clearProperty("kubernetes.auth.token"); + System.clearProperty("kubernetes.auth.basic.username"); + System.clearProperty("kubernetes.auth.basic.password"); + System.clearProperty("kubernetes.trust.certificates"); + System.clearProperty("kubernetes.disable.hostname.verification"); + System.clearProperty("kubernetes.certs.ca.file"); + System.clearProperty("kubernetes.certs.ca.data"); + System.clearProperty("kubernetes.certs.client.file"); + System.clearProperty("kubernetes.certs.client.data"); + System.clearProperty("kubernetes.certs.client.key.file"); + System.clearProperty("kubernetes.certs.client.key.data"); + System.clearProperty("kubernetes.certs.client.key.algo"); + System.clearProperty("kubernetes.certs.client.key.passphrase"); + System.clearProperty("kubernetes.certs.client.key.file"); + System.clearProperty("kubernetes.max.concurrent.requests"); + System.clearProperty("kubernetes.max.concurrent.requests.per.host"); + System.clearProperty("kubernetes.watch.reconnectInterval"); + System.clearProperty("kubernetes.watch.reconnectLimit"); + System.clearProperty("kubernetes.request.timeout"); + System.clearProperty("http.proxy"); + System.clearProperty("kubernetes.tls.versions"); + System.clearProperty("kubernetes.truststore.file"); + System.clearProperty("kubernetes.truststore.passphrase"); + System.clearProperty("kubernetes.keystore.file"); + System.clearProperty("kubernetes.keystore.passphrase"); + System.clearProperty("kubernetes.upload.request.timeout"); + System.clearProperty("kubernetes.websocket.ping.interval"); + System.clearProperty("kubernetes.connection.timeout"); + System.clearProperty("kubernetes.scale.timeout"); + System.clearProperty("https.proxy"); + System.clearProperty("no.proxy"); + System.clearProperty("proxy.username"); + System.clearProperty("proxy.password"); + } - @Test - void testWithBuilderAndSystemProperties() { - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, "http://tobeoverriden:80"); - System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "tobeoverriden"); - - System.setProperty(Config.KUBERNETES_OAUTH_TOKEN_SYSTEM_PROPERTY, "token"); - System.setProperty(Config.KUBERNETES_AUTH_BASIC_USERNAME_SYSTEM_PROPERTY, "user"); - System.setProperty(Config.KUBERNETES_AUTH_BASIC_PASSWORD_SYSTEM_PROPERTY, "pass"); - System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); - System.setProperty(Config.KUBERNETES_DISABLE_HOSTNAME_VERIFICATION_SYSTEM_PROPERTY, "true"); - System.setProperty(Config.KUBERNETES_CA_CERTIFICATE_FILE_SYSTEM_PROPERTY, "/path/to/cert"); - System.setProperty(Config.KUBERNETES_CA_CERTIFICATE_DATA_SYSTEM_PROPERTY, "cacertdata"); - System.setProperty(Config.KUBERNETES_CLIENT_CERTIFICATE_FILE_SYSTEM_PROPERTY, "/path/to/clientcert"); - System.setProperty(Config.KUBERNETES_CLIENT_CERTIFICATE_DATA_SYSTEM_PROPERTY, "clientcertdata"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_FILE_SYSTEM_PROPERTY, "/path/to/clientkey"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_DATA_SYSTEM_PROPERTY, "clientkeydata"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_ALGO_SYSTEM_PROPERTY, "algo"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_PASSPHRASE_SYSTEM_PROPERTY, "passphrase"); - System.setProperty(Config.KUBERNETES_CLIENT_KEY_FILE_SYSTEM_PROPERTY, "/path/to/clientkey"); - System.setProperty(Config.KUBERNETES_MAX_CONCURRENT_REQUESTS, "120"); - System.setProperty(Config.KUBERNETES_MAX_CONCURRENT_REQUESTS_PER_HOST, "20"); - System.setProperty(Config.KUBERNETES_WATCH_RECONNECT_INTERVAL_SYSTEM_PROPERTY, "5000"); - System.setProperty(Config.KUBERNETES_WATCH_RECONNECT_LIMIT_SYSTEM_PROPERTY, "5"); - System.setProperty(Config.KUBERNETES_REQUEST_TIMEOUT_SYSTEM_PROPERTY, "5000"); - System.setProperty(Config.KUBERNETES_HTTP_PROXY, "httpProxy"); - - System.setProperty(Config.KUBERNETES_TLS_VERSIONS, "TLSv1.2,TLSv1.1"); - - System.setProperty(Config.KUBERNETES_TRUSTSTORE_FILE_PROPERTY, "/path/to/truststore"); - System.setProperty(Config.KUBERNETES_TRUSTSTORE_PASSPHRASE_PROPERTY, "truststorePassphrase"); - System.setProperty(Config.KUBERNETES_KEYSTORE_FILE_PROPERTY, "/path/to/keystore"); - System.setProperty(Config.KUBERNETES_KEYSTORE_PASSPHRASE_PROPERTY, "keystorePassphrase"); - - System.setProperty(Config.KUBERNETES_UPLOAD_REQUEST_TIMEOUT_SYSTEM_PROPERTY, "600000"); + @Test + @DisplayName("no args Config constructor, should load from properties") + void zeroArgumentConstructor_whenInvoked_shouldLoadFromProperties() { + assertConfig(new Config(), "http://somehost:80/", "testns", true); + } - Config config = new ConfigBuilder() - .withMasterUrl("http://somehost:80") - .withNamespace("testns") - .build(); + @Test + @DisplayName("ConfigBuilder, should load from properties") + void configBuilder_whenInvoked_shouldLoadFromProperties() { + assertConfig(new ConfigBuilder().build(), "http://somehost:80/", "testns", true); + } - assertConfig(config, true); - } + @Test + @DisplayName("ConfigBuilder, with builder methods, should override properties") + void configBuilder_withBuilderMethods_shouldOverrideFieldsConfiguredViaProperties() { + Config config = new ConfigBuilder() + .withMasterUrl("http://somehost-via-builder:80") + .withNamespace("testns-via-builder") + .build(); - @Test - void testMasterUrlWithServiceAccount() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, "/dev/null"); - System.setProperty(Config.KUBERNETES_SERVICE_HOST_PROPERTY, "10.0.0.1"); - System.setProperty(Config.KUBERNETES_SERVICE_PORT_PROPERTY, "443"); - Config config = Config.autoConfigure(null); - assertNotNull(config); - assertEquals("https://10.0.0.1:443/", config.getMasterUrl()); - assertEquals(null, config.getFile()); + assertConfig(config, "http://somehost-via-builder:80/", "testns-via-builder", true); + } } - @Test - void testAutoConfig() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, "/dev/null"); - Config config = Config.autoConfigure(null); - assertNotNull(config); - assertNull(config.getFile()); - assertTrue(config.getAutoConfigure()); + @Nested + @DisplayName("ConfigBuilder") + class BuilderConfigured { + @Test + @DisplayName("when fields configured via builder, then fields get most precedence") + void testWithBuilder() { + // Given + When + Config config = new ConfigBuilder() + .withMasterUrl("http://somehost:80") + .withApiVersion("v1") + .withNamespace("testns") + .withOauthToken("token") + .withUsername("user") + .withPassword("pass") + .withTrustCerts(true) + .withDisableHostnameVerification(true) + .withCaCertFile("/path/to/cert") + .withCaCertData("cacertdata") + .withClientCertFile("/path/to/clientcert") + .withClientCertData("clientcertdata") + .withClientKeyFile("/path/to/clientkey") + .withClientKeyData("clientkeydata") + .withClientKeyAlgo("algo") + .withClientKeyPassphrase("passphrase") + .withMaxConcurrentRequests(120) + .withMaxConcurrentRequestsPerHost(20) + .withWatchReconnectInterval(5000) + .withWatchReconnectLimit(5) + .withRequestTimeout(5000) + .withUploadRequestTimeout(600000) + .withHttpProxy("httpProxy") + .withHttpsProxy("httpsProxy") + .withProxyUsername("proxyUsername") + .withProxyPassword("proxyPassword") + .withNoProxy("no-proxy-url1.io", "no-proxy-url2.io") + .withTlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1) + .withTrustStoreFile("/path/to/truststore") + .withTrustStorePassphrase("truststorePassphrase") + .withKeyStoreFile("/path/to/keystore") + .withKeyStorePassphrase("keystorePassphrase") + .withHttp2Disable(false) + .withWebsocketPingInterval(1000L) + .withConnectionTimeout(1000) + .withScaleTimeout(1000L) + .build(); + // Then + assertConfig(config, "http://somehost:80/", "testns", false); + } - // ensure that refresh creates a new instance - Config refresh = config.refresh(); - assertNotSame(config, refresh); - assertNull(refresh.getFile()); - assertTrue(refresh.getAutoConfigure()); + @Test + @DisplayName("no additional config, should use default value for webSocketPingInterval") + void shouldHonorDefaultWebsocketPingInterval() { + // Given + When + Config config = new ConfigBuilder().build(); + // Then + assertThat(config.getWebsocketPingInterval()) + .isEqualTo(30000L); + } } - @Test - void testMasterUrlWithServiceAccountIPv6() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, "/dev/null"); - System.setProperty(Config.KUBERNETES_SERVICE_HOST_PROPERTY, "2001:db8:1f70::999:de8:7648:6e8"); - System.setProperty(Config.KUBERNETES_SERVICE_PORT_PROPERTY, "443"); - Config config = Config.autoConfigure(null); - assertNotNull(config); - assertEquals("https://[2001:db8:1f70::999:de8:7648:6e8]:443/", config.getMasterUrl()); - assertEquals(null, config.getFile()); - } + @Nested + @DisplayName("Inside Kubernetes cluster") + class InCluster { + @BeforeEach + void setUp() { + System.setProperty("kubeconfig", "/dev/null"); + System.clearProperty("kubernetes.master"); + } - @Test - void testWithKubeConfig() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_FILE); - Config config = new Config(); - assertNotNull(config); + @AfterEach + void tearDown() { + System.clearProperty("kubeconfig"); + } - assertEquals("https://172.28.128.4:8443/", config.getMasterUrl()); - assertEquals("testns", config.getNamespace()); - assertEquals("token", config.getAutoOAuthToken()); - assertTrue(config.getCaCertFile().endsWith("testns/ca.pem".replace("/", File.separator))); - assertTrue(new File(config.getCaCertFile()).isAbsolute()); - assertEquals(new File(TEST_KUBECONFIG_FILE), config.getFile()); - } + @Test + void testMasterUrlWithServiceAccount() { + try { + // Given + System.setProperty("KUBERNETES_SERVICE_HOST", "10.0.0.1"); + System.setProperty("KUBERNETES_SERVICE_PORT", "443"); + // When + Config config = Config.autoConfigure(null); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://10.0.0.1:443/") + .hasFieldOrPropertyWithValue("file", null); + } finally { + System.clearProperty("KUBERNETES_SERVICE_HOST"); + System.clearProperty("KUBERNETES_SERVICE_PORT"); + } + } - @Test - void testWithKubeConfigAndOverrideContext() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_FILE); - Config config = Config.autoConfigure("production/172-28-128-4:8443/root"); - assertNotNull(config); + @Test + void testAutoConfig() { + Config config = Config.autoConfigure(null); + assertThat(config) + .hasFieldOrPropertyWithValue("file", null) + .hasFieldOrPropertyWithValue("autoConfigure", true); + + // ensure that refresh creates a new instance + Config refresh = config.refresh(); + assertThat(refresh) + .isNotSameAs(config) + .hasFieldOrPropertyWithValue("file", null) + .hasFieldOrPropertyWithValue("autoConfigure", true); + } - assertEquals("https://172.28.128.4:8443/", config.getMasterUrl()); - assertEquals("production", config.getNamespace()); - assertEquals("supertoken", config.getAutoOAuthToken()); - assertTrue(config.getCaCertFile().endsWith("testns/ca.pem".replace("/", File.separator))); - assertTrue(new File(config.getCaCertFile()).isAbsolute()); - } + @Test + void testMasterUrlWithServiceAccountIPv6() { + try { + // Given + System.setProperty("KUBERNETES_SERVICE_HOST", "2001:db8:1f70::999:de8:7648:6e8"); + System.setProperty("KUBERNETES_SERVICE_PORT", "443"); + // When + Config config = Config.autoConfigure(null); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://[2001:db8:1f70::999:de8:7648:6e8]:443/") + .hasFieldOrPropertyWithValue("file", null); + } finally { + System.clearProperty("KUBERNETES_SERVICE_HOST"); + System.clearProperty("KUBERNETES_SERVICE_PORT"); + } + } - @Test - void testWithMultipleKubeConfigAndOverrideContext() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_FILE + File.pathSeparator + "some-other-file"); + @Test + @DisplayName("when ServiceAccount token file provided, then use it as autoOAuthToken") + void whenServiceAccountTokenPathProvided_thenUseThatToken() { + try { + // Given + System.setProperty("kubernetes.auth.serviceAccount.token", + Utils.filePath(ConfigTest.class.getResource("/test-serviceaccount/token"))); + // When + Config config = new ConfigBuilder().build(); + // Then + assertThat(config.getAutoOAuthToken()).contains("token-from-mounted-serviceaccount"); + } finally { + System.clearProperty("kubernetes.auth.serviceAccount.token"); + } + } - Config config = Config.autoConfigure("production/172-28-128-4:8443/root"); - assertNotNull(config); + @Test + @DisplayName("when ServiceAccount certificate file provided, then use it as caCertFile") + void whenServiceAccountCertFilePathProvided_thenUseThatToken() { + try { + // Given + String certFilePath = Utils.filePath(ConfigTest.class.getResource("/test-serviceaccount/ca.crt")); + System.setProperty("kubernetes.certs.ca.file", certFilePath); + // When + Config config = new ConfigBuilder().build(); + // Then + assertThat(config.getCaCertFile()).isEqualTo(certFilePath); + } finally { + System.clearProperty("kubernetes.certs.ca.file"); + } + } - assertEquals("https://172.28.128.4:8443/", config.getMasterUrl()); - assertEquals("production", config.getNamespace()); - assertEquals("supertoken", config.getAutoOAuthToken()); - assertTrue(config.getCaCertFile().endsWith("testns/ca.pem".replace("/", File.separator))); - assertTrue(new File(config.getCaCertFile()).isAbsolute()); + @Test + @DisplayName("when kubernetes.tryNamespacePath=false, then do NOT read ServiceAccount files") + void whenTryNamespacePathDisabled_thenDoNotUseServiceAccountAttributes() { + try { + // Given + System.setProperty("kubernetes.auth.tryServiceAccount", "false"); + System.setProperty("kubernetes.auth.serviceAccount.token", + Utils.filePath(ConfigTest.class.getResource("/test-serviceaccount/token"))); + // When + Config config = new ConfigBuilder().build(); + // Then + assertThat(config.getAutoOAuthToken()).isNull(); + } finally { + System.clearProperty("kubernetes.auth.tryServiceAccount"); + System.clearProperty("kubernetes.auth.serviceAccount.token"); + } + } } - @Test - void testWithKubeConfigAndSystemProperties() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_FILE); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, "http://somehost:80"); + @Nested + @DisplayName("kubeconfig present") + class KubeConfigPresent { + @BeforeEach + void setUp() { + System.setProperty("kubeconfig", TEST_KUBECONFIG_FILE); + System.clearProperty("kubernetes.namespace"); + } - Config config = new Config(); - assertNotNull(config); - assertEquals("http://somehost:80/", config.getMasterUrl()); - assertEquals("testns", config.getNamespace()); - assertEquals("token", config.getAutoOAuthToken()); - assertEquals(new File(TEST_KUBECONFIG_FILE), config.getFile()); - } + @Test + @DisplayName("new Config() should auto configure from kubeconfig") + void noArgConstructor_shouldAutoConfigureFromKubeConfig() { + assertThat(new Config()) + .isNotNull() + .hasFieldOrPropertyWithValue("masterUrl", "https://172.28.128.4:8443/") + .hasFieldOrPropertyWithValue("namespace", "testns") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token") + .satisfies(c -> assertThat(c.getCaCertFile()).endsWith("testns/ca.pem".replace("/", File.separator))) + .satisfies(c -> assertThat(new File(c.getCaCertFile())).isAbsolute()) + .hasFieldOrPropertyWithValue("file", new File(TEST_KUBECONFIG_FILE)); + } - @Test - void testWithKubeConfigAndSytemPropertiesAndBuilder() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_FILE); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, "http://somehost:80"); + @Test + @DisplayName("Config.autoConfigure with overridden context") + void testOverrideContext() { + assertThat(Config.autoConfigure("production/172-28-128-4:8443/root")) + .isNotNull() + .hasFieldOrPropertyWithValue("masterUrl", "https://172.28.128.4:8443/") + .hasFieldOrPropertyWithValue("namespace", "production") + .hasFieldOrPropertyWithValue("autoOAuthToken", "supertoken") + .satisfies(c -> assertThat(c.getCaCertFile()).endsWith("testns/ca.pem".replace("/", File.separator))) + .satisfies(c -> assertThat(new File(c.getCaCertFile())).isAbsolute()); + } - Config config = new ConfigBuilder() - .withNamespace("testns2") - .build(); + @Test + @DisplayName("override via system property should get more precedence over kubeconfig") + void testOverrideViaSystemProperties() { + try { + // Given + System.setProperty("kubernetes.master", "http://somehost:80"); + + // When + Then + assertThat(new Config()) + .isNotNull() + .hasFieldOrPropertyWithValue("masterUrl", "http://somehost:80/") + .hasFieldOrPropertyWithValue("namespace", "testns") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token") + .hasFieldOrPropertyWithValue("file", new File(TEST_KUBECONFIG_FILE)) + .satisfies(c -> assertThat(new File(c.getCaCertFile())).isAbsolute()); + } finally { + System.clearProperty("kubernetes.master"); + } + } - assertNotNull(config); - assertEquals("http://somehost:80/", config.getMasterUrl()); - assertEquals("token", config.getAutoOAuthToken()); - assertEquals("testns2", config.getNamespace()); + @Test + void testSystemPropertiesAndBuilderGetMorePrecedenceOverKubeconfig() { + try { + // Given + System.setProperty("kubernetes.master", "http://somehost:80"); + // When + Config config = new ConfigBuilder() + .withNamespace("testns2") + .build(); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("masterUrl", "http://somehost:80/") + .hasFieldOrPropertyWithValue("namespace", "testns2") + .hasFieldOrPropertyWithValue("autoOAuthToken", "token"); + } finally { + System.clearProperty("kubernetes.master"); + } + } } - @Test - void testFromKubeconfigContent() throws IOException { - File configFile = new File(TEST_KUBECONFIG_FILE); - final String configYAML = String.join("\n", Files.readAllLines(configFile.toPath())); - final Config config = Config.fromKubeconfig(configYAML); - assertEquals("https://172.28.128.4:8443/", config.getMasterUrl()); + @Nested + @DisplayName("load fromKubeConfig") + class FromKubeConfig { + @BeforeEach + void setUp() { + System.clearProperty("kubeconfig"); + System.clearProperty("kubernetes.master"); + } + + @Test + @DisplayName("standard kubeconfig file") + void testFromKubeconfigContent() throws IOException { + // Given + When + final Config config = Config.fromKubeconfig(prepareKubeConfigYamlFrom(TEST_KUBECONFIG_FILE)); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://172.28.128.4:8443/") + .hasFieldOrPropertyWithValue("autoConfigure", false) + .hasFieldOrPropertyWithValue("file", null) + .isSameAs(config.refresh()); + } + + @Test + @DisplayName("kubeconfig with EC Private Data in client key") + void testFromKubeconfigKeyAlgo() throws IOException { + // Given + When + final Config config = Config.fromKubeconfig(prepareKubeConfigYamlFrom(TEST_EC_KUBECONFIG_FILE)); + // Then + assertThat(config.getClientKeyAlgo()).isEqualTo("EC"); + } - assertFalse(config.getAutoConfigure()); - assertNull(config.getFile()); - assertSame(config, config.refresh()); + private String prepareKubeConfigYamlFrom(String filePath) throws IOException { + File configFile = new File(filePath); + return String.join(System.lineSeparator(), Files.readAllLines(configFile.toPath())); + } } @Test - void testFromKubeconfigKeyAlgo() throws IOException { - File configFile = new File(TEST_EC_KUBECONFIG_FILE); - final String configYAML = String.join("\n", Files.readAllLines(configFile.toPath())); - final Config config = Config.fromKubeconfig(configYAML); - assertEquals("EC", config.getClientKeyAlgo()); + void testWithMultipleKubeConfigAndOverrideContext() { + try { + // Given + System.setProperty("kubeconfig", TEST_KUBECONFIG_FILE + File.pathSeparator + "some-other-file"); + // When + Config config = Config.autoConfigure("production/172-28-128-4:8443/root"); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("masterUrl", "https://172.28.128.4:8443/") + .hasFieldOrPropertyWithValue("namespace", "production") + .hasFieldOrPropertyWithValue("autoOAuthToken", "supertoken") + .satisfies(c -> assertThat(c.getCaCertFile()).endsWith("testns/ca.pem".replace("/", File.separator))) + .satisfies(c -> assertThat(new File(c.getCaCertFile())).isAbsolute()); + } finally { + System.clearProperty("kubeconfig"); + } } @Test void testWithNamespacePath() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, "nokubeconfigfile"); - System.setProperty(Config.KUBERNETES_NAMESPACE_FILE, TEST_NAMESPACE_FILE); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, "http://somehost:80"); - - Config config = new Config(); - assertNotNull(config); - assertEquals("http://somehost:80/", config.getMasterUrl()); - assertEquals("testnsfrompath", config.getNamespace()); + try { + // Given + System.setProperty("kubeconfig", "nokubeconfigfile"); + System.setProperty("kubenamespace", TEST_NAMESPACE_FILE); + System.setProperty("kubernetes.master", "http://somehost:80"); + // When + Config config = new Config(); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("masterUrl", "http://somehost:80/") + .hasFieldOrPropertyWithValue("namespace", "testnsfrompath"); + } finally { + System.clearProperty("kubeconfig"); + System.clearProperty("kubenamespace"); + System.clearProperty("kubernetes.master"); + } } @Test void testWithNonExistingNamespacePath() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, "nokubeconfigfile"); - System.setProperty(Config.KUBERNETES_NAMESPACE_FILE, "nonamespace"); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, "http://somehost:80"); - - Config config = new Config(); - assertNotNull(config); - assertEquals("http://somehost:80/", config.getMasterUrl()); - assertNull(config.getNamespace()); + try { + // Given + System.setProperty("kubeconfig", "nokubeconfigfile"); + System.setProperty("kubenamespace", "nonamespace"); + System.setProperty("kubernetes.master", "http://somehost:80"); + // When + Config config = new Config(); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("masterUrl", "http://somehost:80/") + .hasFieldOrPropertyWithValue("namespace", null); + } finally { + System.clearProperty("kubeconfig"); + System.clearProperty("kubenamespace"); + System.clearProperty("kubernetes.master"); + } } @Test void testWithNamespacePathAndSystemProperties() { - System.setProperty(Config.KUBERNETES_NAMESPACE_FILE, TEST_NAMESPACE_FILE); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, "http://somehost:80"); - System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "testns"); - - Config config = new Config(); - assertNotNull(config); - assertEquals("http://somehost:80/", config.getMasterUrl()); - assertEquals("testns", config.getNamespace()); + try { + // Given + System.setProperty("kubenamespace", TEST_NAMESPACE_FILE); + System.setProperty("kubernetes.master", "http://somehost:80"); + System.setProperty("kubernetes.namespace", "testns"); + // When + Config config = new Config(); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("masterUrl", "http://somehost:80/") + .hasFieldOrPropertyWithValue("namespace", "testns"); + } finally { + System.clearProperty("kubenamespace"); + System.clearProperty("kubernetes.master"); + System.clearProperty("kubernetes.namespace"); + } } @Test void testWithKubeConfigAndNoContext() { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_NO_CURRENT_CONTEXT_FILE); - Config config = new Config(); - assertNotNull(config); - - assertNull(config.getCurrentContext()); - assertEquals(3, config.getContexts().size()); - assertEquals(Config.DEFAULT_MASTER_URL + "/", config.getMasterUrl()); - assertNull(config.getNamespace()); + try { + // Given + System.setProperty("kubeconfig", TEST_KUBECONFIG_NO_CURRENT_CONTEXT_FILE); + // When + Config config = new Config(); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("currentContext", null) + .hasFieldOrPropertyWithValue("namespace", null) + .hasFieldOrPropertyWithValue("masterUrl", "https://kubernetes.default.svc/") + .extracting(Config::getContexts) + .asInstanceOf(InstanceOfAssertFactories.list(NamedContext.class)) + .hasSize(3); + } finally { + System.clearProperty("kubeconfig"); + } } @Test - void testWithNamespacePathAndSytemPropertiesAndBuilder() { - System.setProperty(Config.KUBERNETES_NAMESPACE_FILE, TEST_NAMESPACE_FILE); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, "http://somehost:80"); - System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "tobeoverriden"); - - Config config = new ConfigBuilder() - .withNamespace("testns2") - .build(); - - assertNotNull(config); - assertEquals("http://somehost:80/", config.getMasterUrl()); - assertEquals("testns2", config.getNamespace()); + void testWithNamespacePathAndSystemPropertiesAndBuilder() { + try { + // Given + System.setProperty("kubenamespace", TEST_NAMESPACE_FILE); + System.setProperty("kubernetes.master", "http://somehost:80"); + System.setProperty("kubernetes.namespace", "tobeoverriden"); + // When + Config config = new ConfigBuilder() + .withNamespace("testns2") + .build(); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "http://somehost:80/") + .hasFieldOrPropertyWithValue("namespace", "testns2"); + } finally { + System.clearProperty("kubenamespace"); + System.clearProperty("kubernetes.master"); + System.clearProperty("kubernetes.namespace"); + } } @Test void testWithCustomHeader() { + // Given Map customHeaders = new HashMap<>(); customHeaders.put("user-id", "test-user"); customHeaders.put("cluster-id", "test-cluster"); + // When Config config = new ConfigBuilder() .withCustomHeaders(customHeaders) .build(); - - assertNotNull(config); - assertNotNull(config.getCustomHeaders()); - assertEquals(2, config.getCustomHeaders().size()); + // Then + assertThat(config) + .isNotNull() + .extracting(Config::getCustomHeaders) + .asInstanceOf(InstanceOfAssertFactories.MAP) + .hasSize(2); } @Test void shouldSetImpersonateUsernameAndGroupFromSystemProperty() { + try { + // Given + System.setProperty("kubernetes.impersonate.username", "username"); + System.setProperty("kubernetes.impersonate.group", "group"); + final Map> extras = new HashMap<>(); + extras.put("c", Collections.singletonList("d")); + // When + final Config config = new ConfigBuilder() + .withImpersonateUsername("a") + .withImpersonateExtras(extras) + .build(); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("requestConfig.impersonateUsername", "a") + .hasFieldOrPropertyWithValue("requestConfig.impersonateGroups", new String[] { "group" }) + .hasFieldOrPropertyWithValue("requestConfig.impersonateExtras", + Collections.singletonMap("c", Collections.singletonList("d"))); + } finally { + System.clearProperty("kubernetes.impersonate.username"); + System.clearProperty("kubernetes.impersonate.group"); + } + } - System.setProperty(Config.KUBERNETES_IMPERSONATE_USERNAME, "username"); - System.setProperty(Config.KUBERNETES_IMPERSONATE_GROUP, "group"); - - final Map> extras = new HashMap<>(); - extras.put("c", Collections.singletonList("d")); - - final Config config = new ConfigBuilder() - .withImpersonateUsername("a") - .withImpersonateExtras(extras) - .build(); - - assertEquals("a", config.getImpersonateUsername()); - assertArrayEquals(new String[] { "group" }, config.getImpersonateGroups()); - assertEquals(Collections.singletonList("d"), config.getImpersonateExtras().get("c")); - + @Test + @EnabledOnOs(OS.WINDOWS) + void honorClientAuthenticatorCommandsOnWindows() { + try { + // Given + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_WIN_FILE); + // When + Config config = Config.autoConfigure(null); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("autoOAuthToken", "HELLO WORLD"); + } finally { + System.clearProperty("kubeconfig"); + } } @Test + @DisabledOnOs(OS.WINDOWS) void honorClientAuthenticatorCommands() throws Exception { - switch (FileSystem.getCurrent()) { - case WINDOWS: - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_WIN_FILE); - break; - default: - Files.setPosixFilePermissions(Paths.get(TEST_TOKEN_GENERATOR_FILE), PosixFilePermissions.fromString("rwxrwxr-x")); - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_FILE); + try { + // Given + Files.setPosixFilePermissions(Paths.get(TEST_TOKEN_GENERATOR_FILE), PosixFilePermissions.fromString("rwxrwxr-x")); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE); + // When + Config config = Config.autoConfigure(null); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("autoOAuthToken", "HELLO WORLD"); + } finally { + System.clearProperty("kubeconfig"); } - - Config config = Config.autoConfigure(null); - assertNotNull(config); - assertEquals("HELLO WORLD", config.getAutoOAuthToken()); } @Test void should_accept_client_authentication_commands_with_null_args() throws Exception { try { + // Given if (FileSystem.getCurrent() == FileSystem.WINDOWS) { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_FILE_WIN_NULL_ARGS); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_WIN_NULL_ARGS); } else { Files.setPosixFilePermissions(Paths.get(TEST_TOKEN_GENERATOR_FILE), PosixFilePermissions.fromString("rwxrwxr-x")); - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_FILE_NULL_ARGS); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_NULL_ARGS); } - + // When Config config = Config.autoConfigure(null); - assertNotNull(config); - assertEquals("HELLO", config.getAutoOAuthToken()); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("autoOAuthToken", "HELLO"); } finally { - System.clearProperty(Config.KUBERNETES_KUBECONFIG_FILE); + System.clearProperty("kubeconfig"); } } @Test void testClientAuthenticationWithCert() throws Exception { try { + // Given if (FileSystem.getCurrent() == FileSystem.WINDOWS) { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_WIN_FILE_CERT_AUTH); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_WIN_FILE_CERT_AUTH); } else { Files.setPosixFilePermissions(Paths.get(TEST_CERT_GENERATOR_FILE), PosixFilePermissions.fromString("rwxrwxr-x")); - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_FILE_CERT_AUTH); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_CERT_AUTH); } - + // When Config config = Config.autoConfigure(null); - assertNotNull(config); - assertEquals("CERT DATA", config.getClientCertData()); - assertEquals("KEY DATA", config.getClientKeyData()); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("clientCertData", "CERT DATA") + .hasFieldOrPropertyWithValue("clientKeyData", "KEY DATA"); } finally { - System.clearProperty(Config.KUBERNETES_KUBECONFIG_FILE); + System.clearProperty("kubeconfig"); } } @Test void testClientAuthenticationWithCertAndECInvalid() throws Exception { try { + // Given if (FileSystem.getCurrent() == FileSystem.WINDOWS) { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_WIN_FILE_CERT_AUTH_EC_INVALID); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_WIN_FILE_CERT_AUTH_EC_INVALID); } else { Files.setPosixFilePermissions(Paths.get(TEST_CERT_GENERATOR_FILE), PosixFilePermissions.fromString("rwxrwxr-x")); - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_FILE_CERT_AUTH_EC_INVALID); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_CERT_AUTH_EC_INVALID); } - + // When Config config = Config.autoConfigure(null); - assertNotNull(config); - assertNull(config.getClientCertData()); - assertNull(config.getClientKeyData()); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("clientCertData", null) + .hasFieldOrPropertyWithValue("clientKeyData", null); } finally { - System.clearProperty(Config.KUBERNETES_KUBECONFIG_FILE); + System.clearProperty("kubeconfig"); } } @Test void should_accept_client_authentication_commands_args_with_spaces() throws Exception { try { + // Given if (FileSystem.getCurrent() == FileSystem.WINDOWS) { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_FILE_ARGS_WITH_SPACES_WIN); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_ARGS_WITH_SPACES_WIN); } else { Files.setPosixFilePermissions(Paths.get(TEST_TOKEN_GENERATOR_FILE_WITH_SPACES), PosixFilePermissions.fromString("rwxrwxr-x")); - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_FILE_ARGS_WITH_SPACES); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_ARGS_WITH_SPACES); } - + // When Config config = Config.autoConfigure(null); - assertNotNull(config); - assertEquals("HELLO W O R L D", config.getAutoOAuthToken()); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("autoOAuthToken", "HELLO W O R L D"); } finally { - System.clearProperty(Config.KUBERNETES_KUBECONFIG_FILE); + System.clearProperty("kubeconfig"); } } @Test void should_accept_client_authentication_commands_with_spaces() throws Exception { try { + // Given if (FileSystem.getCurrent() == FileSystem.WINDOWS) { - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_FILE_WITH_SPACES_WIN); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_WITH_SPACES_WIN); } else { Files.setPosixFilePermissions(Paths.get(TEST_TOKEN_GENERATOR_FILE_WITH_SPACES), PosixFilePermissions.fromString("rwxrwxr-x")); - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, TEST_KUBECONFIG_EXEC_FILE_WITH_SPACES); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_WITH_SPACES); } - + // When Config config = Config.autoConfigure(null); - assertNotNull(config); - assertEquals("HELLO WORLD", config.getAutoOAuthToken()); + // Then + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("autoOAuthToken", "HELLO WORLD"); } finally { - System.clearProperty(Config.KUBERNETES_KUBECONFIG_FILE); + System.clearProperty("kubeconfig"); } } @Test void shouldBeUsedTokenSuppliedByProvider() { - + // Given Config config = new ConfigBuilder().withOauthToken("oauthToken") .withOauthTokenProvider(() -> "PROVIDER_TOKEN") .build(); + // When + Then // this is mostly a configuration error, and // the provider does not modify the oauthtoken field - assertEquals("oauthToken", config.getOauthToken()); - } - - @Test - void shouldHonorDefaultWebsocketPingInterval() { - Config config = new ConfigBuilder().build(); - - assertEquals(30000L, config.getWebsocketPingInterval()); + assertThat(config.getOauthToken()).isEqualTo("oauthToken"); } @Test void testKubeConfigWithAuthConfigProvider() throws URISyntaxException { - System.setProperty("kubeconfig", new File(getClass().getResource("/test-kubeconfig").toURI()).getAbsolutePath()); - Config config = Config.autoConfigure("production/172-28-128-4:8443/mmosley"); - - assertEquals("https://172.28.128.4:8443/", config.getMasterUrl()); - assertEquals( - "eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw", - config.getAutoOAuthToken()); + try { + // Given + System.setProperty("kubeconfig", new File(getClass().getResource("/test-kubeconfig").toURI()).getAbsolutePath()); + // When + Config config = Config.autoConfigure("production/172-28-128-4:8443/mmosley"); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("masterUrl", "https://172.28.128.4:8443/") + .hasFieldOrPropertyWithValue("autoOAuthToken", + "eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw"); + } finally { + System.clearProperty("kubeconfig"); + } } @Test @@ -653,45 +859,111 @@ void testEmptyConfig() { .satisfies(e -> assertThat(e.getUserAgent()).isNotNull()); } - private void assertConfig(Config config, boolean autoToken) { - assertNotNull(config); - assertTrue(config.isTrustCerts()); - assertTrue(config.isDisableHostnameVerification()); - assertEquals("http://somehost:80/", config.getMasterUrl()); - assertEquals("testns", config.getNamespace()); + @Test + void deprecatedOldConfigConstructor() { + // Given + When + Config config = new Config("https://api.example.testing:6443", "v1", "ns1", true, true, + "ca.crt", "certificate-authority-data", "client.crt", "client-authority-data", "client-key.crt", + "client-key-data", "EC", "client-key-passphrase", "test-user", "secret", "sha256~secret", "sha256~auto-token", + 500, 5, 5000, 5000, 0, 100000, 10000, 5, 10, "http://proxy-url", "https://proxy-url", + new String[] { "https://noproxy-url1" }, Collections.emptyMap(), "fabric8-kubernetes-client/ConfigTest", + new TlsVersion[] { TlsVersion.TLS_1_3 }, 10000L, "proxy-username", "proxy-password", "truststore.jks", + "truststore-password", "k8s.keystore", "keystore-password", "jane.doe@example.com", new String[] { "developers" }, + Collections.singletonMap("scope", Arrays.asList("view", "development"))); + // Then + assertThat(config) + .hasFieldOrPropertyWithValue("autoConfigure", false) + .hasFieldOrPropertyWithValue("apiVersion", "v1") + .hasFieldOrPropertyWithValue("namespace", "ns1") + .hasFieldOrPropertyWithValue("masterUrl", "https://api.example.testing:6443/") + .hasFieldOrPropertyWithValue("contexts", Collections.emptyList()) + .hasFieldOrPropertyWithValue("caCertFile", "ca.crt") + .hasFieldOrPropertyWithValue("caCertData", "certificate-authority-data") + .hasFieldOrPropertyWithValue("clientCertFile", "client.crt") + .hasFieldOrPropertyWithValue("clientCertData", "client-authority-data") + .hasFieldOrPropertyWithValue("clientKeyFile", "client-key.crt") + .hasFieldOrPropertyWithValue("clientKeyData", "client-key-data") + .hasFieldOrPropertyWithValue("clientKeyPassphrase", "client-key-passphrase") + .hasFieldOrPropertyWithValue("username", "test-user") + .hasFieldOrPropertyWithValue("password", "secret") + .hasFieldOrPropertyWithValue("oauthToken", "sha256~secret") + .hasFieldOrPropertyWithValue("autoOAuthToken", "sha256~auto-token") + .hasFieldOrPropertyWithValue("httpProxy", "http://proxy-url") + .hasFieldOrPropertyWithValue("httpsProxy", "https://proxy-url") + .hasFieldOrPropertyWithValue("noProxy", new String[] { "https://noproxy-url1" }) + .hasFieldOrPropertyWithValue("proxyUsername", "proxy-username") + .hasFieldOrPropertyWithValue("proxyPassword", "proxy-password") + .hasFieldOrPropertyWithValue("trustStoreFile", "truststore.jks") + .hasFieldOrPropertyWithValue("trustStorePassphrase", "truststore-password") + .hasFieldOrPropertyWithValue("keyStoreFile", "k8s.keystore") + .hasFieldOrPropertyWithValue("keyStorePassphrase", "keystore-password") + .hasFieldOrPropertyWithValue("maxConcurrentRequests", 5) + .hasFieldOrPropertyWithValue("maxConcurrentRequestsPerHost", 10) + .hasFieldOrPropertyWithValue("trustCerts", true) + .hasFieldOrPropertyWithValue("disableHostnameVerification", true) + .hasFieldOrPropertyWithValue("clientKeyAlgo", "EC") + .hasFieldOrPropertyWithValue("clientKeyPassphrase", "client-key-passphrase") + .hasFieldOrPropertyWithValue("watchReconnectInterval", 500) + .hasFieldOrPropertyWithValue("watchReconnectLimit", 5) + .hasFieldOrPropertyWithValue("connectionTimeout", 5000) + .hasFieldOrPropertyWithValue("requestTimeout", 5000) + .hasFieldOrPropertyWithValue("scaleTimeout", 100000L) + .hasFieldOrPropertyWithValue("loggingInterval", 10000) + .hasFieldOrPropertyWithValue("websocketPingInterval", 10000L) + .hasFieldOrPropertyWithValue("uploadRequestTimeout", 120000) + .hasFieldOrPropertyWithValue("impersonateUsername", "jane.doe@example.com") + .satisfies(e -> assertThat(e.getImpersonateGroups()).containsExactly("developers")) + .hasFieldOrPropertyWithValue("impersonateExtras", + Collections.singletonMap("scope", Arrays.asList("view", "development"))) + .hasFieldOrPropertyWithValue("http2Disable", false) + .hasFieldOrPropertyWithValue("tlsVersions", new TlsVersion[] { TlsVersion.TLS_1_3 }) + .satisfies(e -> assertThat(e.getUserAgent()).isEqualTo("fabric8-kubernetes-client/ConfigTest")); + } + + private void assertConfig(Config config, String masterUrl, String namespace, boolean autoToken) { + assertThat(config) + .isNotNull() + .hasFieldOrPropertyWithValue("trustCerts", true) + .hasFieldOrPropertyWithValue("disableHostnameVerification", true) + .hasFieldOrPropertyWithValue("masterUrl", masterUrl) + .hasFieldOrPropertyWithValue("namespace", namespace) + .hasFieldOrPropertyWithValue("username", "user") + .hasFieldOrPropertyWithValue("password", "pass") + .hasFieldOrPropertyWithValue("caCertFile", "/path/to/cert") + .hasFieldOrPropertyWithValue("caCertData", "cacertdata") + .hasFieldOrPropertyWithValue("clientCertFile", "/path/to/clientcert") + .hasFieldOrPropertyWithValue("clientCertData", "clientcertdata") + .hasFieldOrPropertyWithValue("clientKeyFile", "/path/to/clientkey") + .hasFieldOrPropertyWithValue("clientKeyData", "clientkeydata") + .hasFieldOrPropertyWithValue("clientKeyAlgo", "algo") + .hasFieldOrPropertyWithValue("clientKeyPassphrase", "passphrase") + .hasFieldOrPropertyWithValue("httpProxy", "httpProxy") + .hasFieldOrPropertyWithValue("watchReconnectInterval", 5000) + .hasFieldOrPropertyWithValue("watchReconnectLimit", 5) + .hasFieldOrPropertyWithValue("requestTimeout", 5000) + .hasFieldOrPropertyWithValue("requestConfig.uploadRequestTimeout", 600000) + .hasFieldOrPropertyWithValue("tlsVersions", new TlsVersion[] { TlsVersion.TLS_1_2, TlsVersion.TLS_1_1 }) + .hasFieldOrPropertyWithValue("trustStoreFile", "/path/to/truststore") + .hasFieldOrPropertyWithValue("trustStorePassphrase", "truststorePassphrase") + .hasFieldOrPropertyWithValue("keyStoreFile", "/path/to/keystore") + .hasFieldOrPropertyWithValue("keyStorePassphrase", "keystorePassphrase") + .hasFieldOrPropertyWithValue("maxConcurrentRequests", 120) + .hasFieldOrPropertyWithValue("maxConcurrentRequestsPerHost", 20) + .hasFieldOrPropertyWithValue("websocketPingInterval", 1000L) + .hasFieldOrPropertyWithValue("connectionTimeout", 1000) + .hasFieldOrPropertyWithValue("scaleTimeout", 1000L) + .hasFieldOrPropertyWithValue("watchReconnectInterval", 5000) + .hasFieldOrPropertyWithValue("http2Disable", false) + .hasFieldOrPropertyWithValue("httpsProxy", "httpsProxy") + .hasFieldOrPropertyWithValue("proxyUsername", "proxyUsername") + .hasFieldOrPropertyWithValue("proxyPassword", "proxyPassword") + .hasFieldOrPropertyWithValue("noProxy", new String[] { "no-proxy-url1.io", "no-proxy-url2.io" }); + if (autoToken) { - assertEquals("token", config.getAutoOAuthToken()); + assertThat(config.getAutoOAuthToken()).isEqualTo("token"); } else { - assertEquals("token", config.getOauthToken()); + assertThat(config.getOauthToken()).isEqualTo("token"); } - assertEquals("user", config.getUsername()); - assertEquals("pass", config.getPassword()); - assertEquals("/path/to/cert", config.getCaCertFile()); - assertEquals("cacertdata", config.getCaCertData()); - assertEquals("/path/to/clientcert", config.getClientCertFile()); - assertEquals("clientcertdata", config.getClientCertData()); - - assertEquals("/path/to/clientkey", config.getClientKeyFile()); - assertEquals("clientkeydata", config.getClientKeyData()); - assertEquals("algo", config.getClientKeyAlgo()); - assertEquals("passphrase", config.getClientKeyPassphrase()); - - assertEquals("httpProxy", config.getHttpProxy()); - - assertEquals(5000, config.getWatchReconnectInterval()); - assertEquals(5, config.getWatchReconnectLimit()); - assertEquals(5000, config.getRequestTimeout()); - assertEquals(600000, config.getRequestConfig().getUploadRequestTimeout()); - - assertArrayEquals(new TlsVersion[] { TlsVersion.TLS_1_2, TlsVersion.TLS_1_1 }, config.getTlsVersions()); - - assertEquals("/path/to/truststore", config.getTrustStoreFile()); - assertEquals("truststorePassphrase", config.getTrustStorePassphrase()); - assertEquals("/path/to/keystore", config.getKeyStoreFile()); - assertEquals("keystorePassphrase", config.getKeyStorePassphrase()); - - assertEquals(120, config.getMaxConcurrentRequests()); - assertEquals(20, config.getMaxConcurrentRequestsPerHost()); } @Test @@ -699,7 +971,7 @@ void testGetAuthenticatorCommandFromExecConfig() throws IOException { // Given File commandFolder = Files.createTempDirectory("test").toFile(); File commandFile = new File(commandFolder, "aws"); - boolean isNewFileCreated = commandFile.createNewFile(); + Files.createFile(commandFile.toPath()); String systemPathValue = getTestPathValue(commandFolder); ExecConfig execConfig = new ExecConfigBuilder() .withApiVersion("client.authentication.k8s.io/v1alpha1") @@ -712,18 +984,14 @@ void testGetAuthenticatorCommandFromExecConfig() throws IOException { systemPathValue); // Then - assertTrue(isNewFileCreated); - assertNotNull(processBuilderArgs); - assertEquals(3, processBuilderArgs.size()); + assertThat(processBuilderArgs) + .isNotNull() + .hasSize(3); assertPlatformPrefixes(processBuilderArgs); List commandParts = Arrays.asList(processBuilderArgs.get(2).split(" ")); - assertEquals(commandFile.getAbsolutePath(), commandParts.get(0)); - assertEquals("--region", commandParts.get(1)); - assertEquals("us-west2", commandParts.get(2)); - assertEquals("eks", commandParts.get(3)); - assertEquals("get-token", commandParts.get(4)); - assertEquals("--cluster-name", commandParts.get(5)); - assertEquals("api-eks.example.com", commandParts.get(6)); + assertThat(commandParts) + .containsExactly(commandFile.getAbsolutePath(), "--region", "us-west2", "eks", + "get-token", "--cluster-name", "api-eks.example.com"); } @Test @@ -744,16 +1012,18 @@ void testGetAuthenticatorCommandFromExecConfigNullArgs() throws IOException { execConfigNoArgs, null, systemPathValue); // Then - assertNotNull(processBuilderArgs); - assertEquals(3, processBuilderArgs.size()); + assertThat(processBuilderArgs) + .isNotNull() + .hasSize(3) + .satisfies(pb -> assertThat(pb.get(2)).isEqualTo(commandFile.getPath())); assertPlatformPrefixes(processBuilderArgs); - assertEquals(commandFile.getPath(), processBuilderArgs.get(2)); } private void assertPlatformPrefixes(List processBuilderArgs) { List platformArgsExpected = Utils.getCommandPlatformPrefix(); - assertEquals(platformArgsExpected.get(0), processBuilderArgs.get(0)); - assertEquals(platformArgsExpected.get(1), processBuilderArgs.get(1)); + assertThat(processBuilderArgs) + .satisfies(p -> assertThat(p.get(0)).isEqualTo(platformArgsExpected.get(0))) + .satisfies(p -> assertThat(p.get(1)).isEqualTo(platformArgsExpected.get(1))); } private String getTestPathValue(File commandFolder) { @@ -768,90 +1038,89 @@ private String getTestPathValue(File commandFolder) { } } - @Test - void getHomeDir_shouldUseHomedriveHomepathOnWindows_WhenHomeEnvVariableIsNotSet() { - String osNamePropToRestore = System.getProperty("os.name"); - try { - - System.setProperty("os.name", "Windows"); - - Map envVars = new HashMap(); - envVars.put("HOMEDRIVE", "C:\\Users\\"); - envVars.put("HOMEPATH", "user"); - envVars.put("USERPROFILE", "C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); + @Nested + @DisplayName("Config.getHomeDir") + class GetHomeDir { + @Nested + @DisplayName("os.name=Windows") + class OsNameWindows { + private String osNamePropToRestore; + + @BeforeEach + void setUp() { + osNamePropToRestore = System.getProperty("os.name"); + System.setProperty("os.name", "Windows"); + } - assertEquals("C:\\Users\\user", Config.getHomeDir(f -> true, envVars::get)); + @Test + void shouldUseHomeDriveHomePathOnWindows_WhenHomeEnvVariableIsNotSet() { + // Given + Map envVars = new HashMap<>(); + envVars.put("HOMEDRIVE", "C:\\Users\\"); + envVars.put("HOMEPATH", "user"); + envVars.put("USERPROFILE", "C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); - } finally { - System.setProperty("os.name", osNamePropToRestore); - } - } - - @Test - void getHomeDir_shouldUseUserprofileOnWindows_WhenHomeHomedriveHomepathEnvVariablesAreNotSet() { - String osNamePropToRestore = System.getProperty("os.name"); - try { + // When + Then + assertThat(Config.getHomeDir(f -> true, envVars::get)).isEqualTo("C:\\Users\\user"); + } - System.setProperty("os.name", "Windows"); + @Test + void shouldUseUserprofileOnWindows_WhenHomeHomeDriveHomePathEnvVariablesAreNotSet() { + // Given + Map envVars = new HashMap<>(); + envVars.put("USERPROFILE", "C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); - Map envVars = new HashMap(); - envVars.put("USERPROFILE", "C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); + // When + Then + assertThat(Config.getHomeDir(f -> true, envVars::get)) + .isEqualTo("C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); + } - assertEquals("C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\", - Config.getHomeDir(f -> true, envVars::get)); + @Test + void shouldUseHomeEnvVariableOnWindows_WhenHomeEnvVariableIsSet() { + // Given + Map envVars = new HashMap<>(); + envVars.put("HOMEDRIVE", "C:\\Users\\"); + envVars.put("HOMEPATH", "user"); + envVars.put("HOME", "C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); + + // When + Then + assertThat(Config.getHomeDir(f -> true, envVars::get)) + .isEqualTo("C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); + } - } finally { - System.setProperty("os.name", osNamePropToRestore); + @AfterEach + void tearDown() { + System.setProperty("os.name", osNamePropToRestore); + } } - } - - @Test - void getHomeDir_shouldUseHomeEnvVariableOnWindows_WhenHomeEnvVariableIsSet() { - String osNamePropToRestore = System.getProperty("os.name"); - try { - System.setProperty("os.name", "Windows"); - - Map envVars = new HashMap(); + @Test + @EnabledOnOs(WINDOWS) + void shouldUseHomeEnvVariable_WhenEnabledOnWindows_WhenHomeEnvVariableIsSet() { + // Given + Map envVars = new HashMap<>(); envVars.put("HOMEDRIVE", "C:\\Users\\"); envVars.put("HOMEPATH", "user"); envVars.put("HOME", "C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); - assertEquals("C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\", - Config.getHomeDir(f -> true, envVars::get)); - - } finally { - System.setProperty("os.name", osNamePropToRestore); + // When + Then + assertThat(Config.getHomeDir(f -> true, envVars::get)) + .isEqualTo("C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); } - } - - @Test - @EnabledOnOs({ WINDOWS }) - void getHomeDir_shouldUseHomeEnvVariable_WhenEnabledOnWindows_WhenHomeEnvVariableIsSet() { - - Map envVars = new HashMap(); - envVars.put("HOMEDRIVE", "C:\\Users\\"); - envVars.put("HOMEPATH", "user"); - envVars.put("HOME", "C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\"); - - assertEquals("C:\\Users\\user\\workspace\\myworkspace\\tools\\cygwin\\", - Config.getHomeDir(f -> true, envVars::get)); - - } - - @Test - void getHomeDir_shouldReturnUserHomeProp_WhenHomeEnvVariablesAreNotSet() { - String userHomePropToRestore = System.getProperty("user.home"); - try { - - System.setProperty("user.home", "/home/user"); - Map emptyEnvVars = Collections.emptyMap(); - - assertEquals("/home/user", Config.getHomeDir(f -> true, emptyEnvVars::get)); - - } finally { - System.setProperty("user.home", userHomePropToRestore); + @Test + void shouldReturnUserHomeProp_WhenHomeEnvVariablesAreNotSet() { + String userHomePropToRestore = System.getProperty("user.home"); + try { + // Given + System.setProperty("user.home", "/home/user"); + Map emptyEnvVars = Collections.emptyMap(); + + // When + Then + assertThat(Config.getHomeDir(f -> true, emptyEnvVars::get)).isEqualTo("/home/user"); + } finally { + System.setProperty("user.home", userHomePropToRestore); + } } } @@ -873,14 +1142,175 @@ void refresh_whenOAuthTokenSourceSetToUser_thenConfigUnchanged() { @Test void givenEmptyKubeConfig_whenConfigCreated_thenShouldNotProduceNPE() throws URISyntaxException { - // Given - System.setProperty(Config.KUBERNETES_KUBECONFIG_FILE, - new File(Objects.requireNonNull(getClass().getResource("/test-empty-kubeconfig")).toURI()).getAbsolutePath()); + try { + // Given + System.setProperty("kubeconfig", + new File(Objects.requireNonNull(getClass().getResource("/test-empty-kubeconfig")).toURI()).getAbsolutePath()); - // When - Config config = new ConfigBuilder().build(); + // When + Config config = new ConfigBuilder().build(); - // Then - assertThat(config).isNotNull(); + // Then + assertThat(config).isNotNull(); + } finally { + System.clearProperty("kubeconfig"); + } + + } + + @Nested + @DisplayName("autoConfigure disabled") + class NoAutoConfiguration { + @Nested + @DisplayName("system properties present should be ignored with auto configuration disabled") + class SystemPropertiesConfigured extends AutoConfiguredDisabledScenarios { + @BeforeEach + void setUp() { + System.setProperty("kubernetes.master", "http://somehost:80"); + System.setProperty("kubernetes.namespace", "testns"); + } + + @AfterEach + void tearDown() { + System.clearProperty("kubernetes.master"); + System.clearProperty("kubernetes.namespace"); + } + } + + @Nested + @DisplayName("kubeconfig present should be ignored with auto configuration disabled") + class KubeConfigPresent extends AutoConfiguredDisabledScenarios { + @BeforeEach + void setUp() throws IOException { + if (FileSystem.getCurrent() == FileSystem.WINDOWS) { + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_WIN_NULL_ARGS); + } else { + Files.setPosixFilePermissions(Paths.get(TEST_TOKEN_GENERATOR_FILE), PosixFilePermissions.fromString("rwxrwxr-x")); + System.setProperty("kubeconfig", TEST_KUBECONFIG_EXEC_FILE_NULL_ARGS); + } + } + + @AfterEach + void tearDown() { + System.clearProperty("kubeconfig"); + } + } + } + + private abstract static class AutoConfiguredDisabledScenarios { + private final NamedContext userConfiguredNamedContext = new NamedContextBuilder() + .withName("context1") + .withNewContext() + .withCluster("api-test-openshiftapps-com:6443") + .withUser("testuser/api-test-openshiftapps-com:6443") + .endContext() + .build(); + + @Nested + @DisplayName("kubernetes.disable.autoConfig=true") + class AutoConfigDisabledViaProperty { + @BeforeEach + void setUp() { + System.setProperty("kubernetes.disable.autoConfig", "true"); + } + + @Test + @DisplayName("no user configuration, the use default values") + void whenConfigDisabledViaPropertyAndUserProvidesNoConfiguration_thenUseConfigDefaultValues() { + assertConfigUsesDefaultValues(new ConfigBuilder().build()); + } + + @Test + @DisplayName("user configuration via builder, the user configuration used") + void whenConfigDisabledViaPropertyAndUserProvidesConfigurationViaConfigBuilder_thenUseConfigDefaultValues() { + assertConfigUsesUserProvidedValues(createConfigBuilderWithUserConfiguration().build()); + } + + @AfterEach + void tearDown() { + System.clearProperty("kubernetes.disable.autoConfig"); + } + } + + private io.fabric8.kubernetes.client.ConfigBuilder createConfigBuilderWithUserConfiguration() { + return new ConfigBuilder() + .withMasterUrl("https://api-test.openshiftapps.com:6443") + .withContexts(userConfiguredNamedContext) + .withCurrentContext(userConfiguredNamedContext) + .withMaxConcurrentRequests(30) + .withMaxConcurrentRequestsPerHost(10) + .withTrustCerts() + .withDisableHostnameVerification() + .withClientKeyAlgo("EC") + .withWatchReconnectInterval(500) + .withWatchReconnectLimit(10) + .withConnectionTimeout(1000) + .withRequestTimeout(1000) + .withScaleTimeout(1000) + .withLoggingInterval(1000) + .withWebsocketPingInterval(10000L) + .withUploadRequestTimeout(1000) + .withImpersonateExtras(Collections.singletonMap("acme%2Fproject", Collections.singletonList("some-project"))) + .withHttp2Disable(true) + .withTlsVersions(new TlsVersion[] { TlsVersion.TLS_1_3 }) + .withCurrentContext(userConfiguredNamedContext) + .withImpersonateGroups("developer", "admin") + .withUserAgent("custom-user-agent"); + } + + void assertConfigUsesDefaultValues(Config configWithoutAutoConfigure) { + assertThat(configWithoutAutoConfigure) + .hasFieldOrPropertyWithValue("autoConfigure", false) + .hasFieldOrPropertyWithValue("masterUrl", "https://kubernetes.default.svc/") + .hasFieldOrPropertyWithValue("contexts", Collections.emptyList()) + .hasFieldOrPropertyWithValue("maxConcurrentRequests", 64) + .hasFieldOrPropertyWithValue("maxConcurrentRequestsPerHost", 5) + .hasFieldOrPropertyWithValue("trustCerts", false) + .hasFieldOrPropertyWithValue("disableHostnameVerification", false) + .hasFieldOrPropertyWithValue("clientKeyAlgo", "RSA") + .hasFieldOrPropertyWithValue("clientKeyPassphrase", "changeit") + .hasFieldOrPropertyWithValue("watchReconnectInterval", 1000) + .hasFieldOrPropertyWithValue("watchReconnectLimit", -1) + .hasFieldOrPropertyWithValue("connectionTimeout", 10000) + .hasFieldOrPropertyWithValue("requestTimeout", 10000) + .hasFieldOrPropertyWithValue("scaleTimeout", 600000L) + .hasFieldOrPropertyWithValue("loggingInterval", 20000) + .hasFieldOrPropertyWithValue("websocketPingInterval", 30000L) + .hasFieldOrPropertyWithValue("uploadRequestTimeout", 120000) + .hasFieldOrPropertyWithValue("impersonateExtras", Collections.emptyMap()) + .hasFieldOrPropertyWithValue("http2Disable", false) + .hasFieldOrPropertyWithValue("tlsVersions", new TlsVersion[] { TlsVersion.TLS_1_3, TlsVersion.TLS_1_2 }) + .satisfies(e -> assertThat(e.getCurrentContext()).isNull()) + .satisfies(e -> assertThat(e.getImpersonateGroups()).isEmpty()) + .satisfies(e -> assertThat(e.getUserAgent()).isNotNull()); + } + + void assertConfigUsesUserProvidedValues(Config config) { + assertThat(config) + .hasFieldOrPropertyWithValue("autoConfigure", false) + .hasFieldOrPropertyWithValue("masterUrl", "https://api-test.openshiftapps.com:6443/") + .hasFieldOrPropertyWithValue("contexts", Collections.singletonList(userConfiguredNamedContext)) + .hasFieldOrPropertyWithValue("maxConcurrentRequests", 30) + .hasFieldOrPropertyWithValue("maxConcurrentRequestsPerHost", 10) + .hasFieldOrPropertyWithValue("trustCerts", true) + .hasFieldOrPropertyWithValue("disableHostnameVerification", true) + .hasFieldOrPropertyWithValue("clientKeyAlgo", "EC") + .hasFieldOrPropertyWithValue("clientKeyPassphrase", "changeit") + .hasFieldOrPropertyWithValue("watchReconnectInterval", 500) + .hasFieldOrPropertyWithValue("watchReconnectLimit", 10) + .hasFieldOrPropertyWithValue("connectionTimeout", 1000) + .hasFieldOrPropertyWithValue("requestTimeout", 1000) + .hasFieldOrPropertyWithValue("scaleTimeout", 1000L) + .hasFieldOrPropertyWithValue("loggingInterval", 1000) + .hasFieldOrPropertyWithValue("websocketPingInterval", 10000L) + .hasFieldOrPropertyWithValue("uploadRequestTimeout", 1000) + .hasFieldOrPropertyWithValue("impersonateExtras", + Collections.singletonMap("acme%2Fproject", Collections.singletonList("some-project"))) + .hasFieldOrPropertyWithValue("http2Disable", true) + .hasFieldOrPropertyWithValue("tlsVersions", new TlsVersion[] { TlsVersion.TLS_1_3 }) + .satisfies(e -> assertThat(e.getCurrentContext()).isEqualTo(userConfiguredNamedContext)) + .satisfies(e -> assertThat(e.getImpersonateGroups()).containsExactly("developer", "admin")) + .satisfies(e -> assertThat(e.getUserAgent()).isEqualTo("custom-user-agent")); + } } } diff --git a/kubernetes-client-api/src/test/resources/config-source-precedence/kube-config b/kubernetes-client-api/src/test/resources/config-source-precedence/kube-config new file mode 100644 index 00000000000..609a87417cf --- /dev/null +++ b/kubernetes-client-api/src/test/resources/config-source-precedence/kube-config @@ -0,0 +1,33 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority: ca.crt + extensions: + - extension: + last-update: Mon, 22 Jul 2024 15:23:30 IST + provider: test.sigs.k8s.io + version: v1.33.1 + name: cluster_info + server: https://172.28.128.4:8443 + name: test +contexts: +- context: + cluster: test + extensions: + - extension: + last-update: Mon, 22 Jul 2024 15:23:30 IST + provider: test.sigs.k8s.io + version: v1.33.1 + name: context_info + namespace: namespace-from-kubeconfig + user: test + name: test +current-context: test +kind: Config +preferences: {} +users: +- name: test + user: + client-certificate: client.crt + client-key: client.key + token: token-from-kubeconfig diff --git a/kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/ca.crt b/kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/ca.crt new file mode 100644 index 00000000000..aa85b93d9a3 --- /dev/null +++ b/kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/ca.crt @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +cert-data-from-mounted-serviceaccount +-----END CERTIFICATE----- diff --git a/kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/namespace b/kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/namespace new file mode 100644 index 00000000000..4d767d5bd72 --- /dev/null +++ b/kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/namespace @@ -0,0 +1 @@ +namespace-from-mounted-serviceaccount diff --git a/kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/token b/kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/token new file mode 100644 index 00000000000..d4ed81c2751 --- /dev/null +++ b/kubernetes-client-api/src/test/resources/config-source-precedence/serviceaccount/token @@ -0,0 +1 @@ +token-from-mounted-serviceaccount diff --git a/kubernetes-client-api/src/test/resources/test-serviceaccount/ca.crt b/kubernetes-client-api/src/test/resources/test-serviceaccount/ca.crt new file mode 100644 index 00000000000..442e7ec6bd7 --- /dev/null +++ b/kubernetes-client-api/src/test/resources/test-serviceaccount/ca.crt @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +cert-data +-----END CERTIFICATE----- diff --git a/kubernetes-client-api/src/test/resources/test-serviceaccount/token b/kubernetes-client-api/src/test/resources/test-serviceaccount/token new file mode 100644 index 00000000000..d4ed81c2751 --- /dev/null +++ b/kubernetes-client-api/src/test/resources/test-serviceaccount/token @@ -0,0 +1 @@ +token-from-mounted-serviceaccount diff --git a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/DisableAutoConfigurationIT.java b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/DisableAutoConfigurationIT.java new file mode 100644 index 00000000000..4afd7ef4a8e --- /dev/null +++ b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/DisableAutoConfigurationIT.java @@ -0,0 +1,63 @@ +/* + * 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; + +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.ConfigBuilder; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClientBuilder; +import io.fabric8.kubernetes.client.KubernetesClientException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Collections; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +class DisableAutoConfigurationIT { + KubernetesClient client; + + @Test + @DisplayName("kubernetes.disable.autoConfig=true, then client should not load kubeconfig contents") + void givenDisableAutoConfigPropertyTrue_shouldNotLoadLocalKubeConfig() { + try { + // Given + System.setProperty(Config.KUBERNETES_DISABLE_AUTO_CONFIG_SYSTEM_PROPERTY, "true"); + client = new KubernetesClientBuilder().withConfig(new ConfigBuilder() + .withRequestRetryBackoffLimit(0) + .build()).build(); + + // When + Then + assertThat(client.getConfiguration()) + .hasFieldOrPropertyWithValue("namespace", null) + .hasFieldOrPropertyWithValue("masterUrl", "https://kubernetes.default.svc/") + .hasFieldOrPropertyWithValue("contexts", Collections.emptyList()) + .hasFieldOrPropertyWithValue("currentContext", null) + .hasFieldOrPropertyWithValue("username", null) + .hasFieldOrPropertyWithValue("clientCertFile", null) + .hasFieldOrPropertyWithValue("clientKeyFile", null) + .hasFieldOrPropertyWithValue("clientCertData", null) + .hasFieldOrPropertyWithValue("caCertFile", null) + .hasFieldOrPropertyWithValue("caCertData", null); + assertThatExceptionOfType(KubernetesClientException.class) + .isThrownBy(() -> client.pods().list()) + .withMessageContaining("Operation: [list] for kind: [Pod] with name: [null] in namespace: [null] failed."); + } finally { + System.clearProperty(Config.KUBERNETES_DISABLE_AUTO_CONFIG_SYSTEM_PROPERTY); + } + } +}