Skip to content
This repository was archived by the owner on Apr 10, 2024. It is now read-only.

Commit 8e5f87f

Browse files
authored
Work around conflicts with existing kubeconfig file (#133)
In some environments, where the user has an existing `kubeconfig` file with an active context using the `client-key-data` or `client-certificate-data` fields, the `kubectl` client used in the Kube API server readiness check does not know what certificates to use and the API Server startup fails with the exception `JenvtestException: Kube API Server did not start properly`. This PR works around it by specifying the `KUBECONFIG` environment variable to an non-existent config file when calling `kubectl` in the readiness check. That makes the `kubectl` process not use the pre-existing `kubeconfig` with its certificates and makes everything work. This is not needed is the user asks for updating the `kubeconfig` file as in such case, the `kubeconfig` already contains the correct configuration and no special handling is needed. This should resolve #116 Signed-off-by: Jakub Scholz <[email protected]>
1 parent 3664f1a commit 8e5f87f

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

core/src/main/java/io/javaoperatorsdk/jenvtest/process/KubeAPIServerProcess.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public void waitUntilReady() {
9292
readinessChecker.waitUntilReady(apiServerPort, "readyz", KUBE_API_SERVER, true, timeout);
9393
int newTimout = (int) (timeout - (System.currentTimeMillis() - startTime));
9494
readinessChecker.waitUntilDefaultNamespaceAvailable(apiServerPort, binaryManager, certManager,
95-
newTimout);
95+
config, newTimout);
9696
}
9797

9898
public void stopApiServer() {

core/src/main/java/io/javaoperatorsdk/jenvtest/process/ProcessReadinessChecker.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.security.cert.X509Certificate;
1515
import java.time.LocalTime;
1616
import java.time.temporal.ChronoUnit;
17+
import java.util.Map;
1718
import java.util.function.BooleanSupplier;
1819

1920
import javax.net.ssl.SSLContext;
@@ -25,6 +26,7 @@
2526
import org.slf4j.LoggerFactory;
2627

2728
import io.javaoperatorsdk.jenvtest.JenvtestException;
29+
import io.javaoperatorsdk.jenvtest.KubeAPIServerConfig;
2830
import io.javaoperatorsdk.jenvtest.binary.BinaryManager;
2931
import io.javaoperatorsdk.jenvtest.cert.CertManager;
3032

@@ -36,23 +38,36 @@ public class ProcessReadinessChecker {
3638

3739
public static final int POLLING_INTERVAL = 200;
3840

39-
public void waitUntilDefaultNamespaceAvailable(int apiServerPort,
40-
BinaryManager binaryManager,
41-
CertManager certManager, int timeoutMillis) {
42-
pollWithTimeout(() -> defaultNamespaceExists(apiServerPort, binaryManager, certManager),
41+
public void waitUntilDefaultNamespaceAvailable(int apiServerPort, BinaryManager binaryManager,
42+
CertManager certManager, KubeAPIServerConfig config, int timeoutMillis) {
43+
pollWithTimeout(() -> defaultNamespaceExists(apiServerPort, binaryManager, certManager, config),
4344
KUBE_API_SERVER, timeoutMillis);
4445
}
4546

4647
private boolean defaultNamespaceExists(int apiServerPort, BinaryManager binaryManager,
47-
CertManager certManager) {
48+
CertManager certManager, KubeAPIServerConfig config) {
4849
try {
49-
Process process = new ProcessBuilder(binaryManager.binaries().getKubectl().getPath(),
50-
"--client-certificate=" + certManager.getClientCertPath(),
51-
"--client-key=" + certManager.getClientKeyPath(),
52-
"--certificate-authority=" + certManager.getAPIServerCertPath(),
53-
"--server=https://127.0.0.1:" + apiServerPort,
54-
"--request-timeout=5s",
55-
"get", "ns", "default").start();
50+
ProcessBuilder processBuilder =
51+
new ProcessBuilder(binaryManager.binaries().getKubectl().getPath(),
52+
"--client-certificate=" + certManager.getClientCertPath(),
53+
"--client-key=" + certManager.getClientKeyPath(),
54+
"--certificate-authority=" + certManager.getAPIServerCertPath(),
55+
"--server=https://127.0.0.1:" + apiServerPort,
56+
"--request-timeout=5s",
57+
"get", "ns", "default");
58+
59+
if (!config.isUpdateKubeConfig()) {
60+
// When the default kubeconfig file contains default context using client-certificate-data
61+
// or client-key-data, kubectl will fail because it will not know which one to use and the
62+
// readiness check will never pass. To avoid that, we set the KUBECONFIG environment
63+
// variable to an non-existent kubeconfig file. This cannot be done using the --kubeconfig
64+
// option to kubectl, because kubectl will complain if such file does not exist, but when
65+
// set through KUBECONFIG env. variable, it does not complain.
66+
Map<String, String> env = processBuilder.environment();
67+
env.put("KUBECONFIG", config.getJenvtestDir() + "/.kubeconfig");
68+
}
69+
70+
Process process = processBuilder.start();
5671
return process.waitFor() == 0;
5772
} catch (IOException e) {
5873
throw new JenvtestException(e);

0 commit comments

Comments
 (0)