Skip to content

Commit

Permalink
fix (jkube-kit/common) : Update `KubernetesHelper.exportKubernetesCli…
Browse files Browse the repository at this point in the history
…entConfigToFile` to add opinionated Cluster Context

When using KubernetesClient with Kubernetes Mock Server,
`kubernetesClient.getConfiguration()` returns a Config object with no
context set.

Handle this case in KubernetesMockServerUtil to create opinionated Context until
this gets fixed in KubernetesMockServer

Signed-off-by: Rohan Kumar <[email protected]>
  • Loading branch information
rohanKanojia committed Jun 20, 2024
1 parent 8b3ddfa commit ef64498
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@
*/
package org.eclipse.jkube.kit.common.util;


import java.io.File;
import java.io.IOException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
Expand Down Expand Up @@ -860,6 +858,9 @@ private static NamedCluster createKubeConfigClusterFromClient(io.fabric8.kuberne
if (StringUtils.isNotBlank(kubernetesClientConfig.getCaCertData())) {
clusterBuilder.withCertificateAuthorityData(kubernetesClientConfig.getCaCertData());
}
if (kubernetesClientConfig.isTrustCerts()) {
clusterBuilder.withInsecureSkipTlsVerify(true);
}
return new NamedClusterBuilder().withName(Optional.ofNullable(kubernetesClientConfig.getCurrentContext())
.map(NamedContext::getContext)
.map(Context::getCluster)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import io.fabric8.kubernetes.api.model.runtime.RawExtension;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.http.TlsVersion;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
import org.assertj.core.api.InstanceOfAssertFactories;
Expand Down Expand Up @@ -72,6 +73,7 @@
import io.fabric8.openshift.api.model.Template;
import org.eclipse.jkube.kit.common.TestHttpStaticServer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down Expand Up @@ -454,6 +456,7 @@ void extractPodLabelSelector_withJobWithNoSelector_shouldReturnTemplateLabels()


@Test
@DisplayName("when invalid target kubeconfig file provided, then thrown exception")
void exportKubernetesClientConfigToFile_whenInvalidFileProvided_thenThrowException(@TempDir Path temporaryFolder) {
// Given
io.fabric8.kubernetes.client.Config kubernetesClientConfig = createKubernetesClientConfig();
Expand All @@ -465,6 +468,42 @@ void exportKubernetesClientConfigToFile_whenInvalidFileProvided_thenThrowExcepti
}

@Test
@DisplayName("should work with KubernetesClient config provided by KubernetesMockServer")
void exportKubernetesClientConfigToFile_whenTrustCertsEnabled_thenWriteKubeConfigWithInsecureSkipTlsVerify(@TempDir Path temporaryFolder) throws IOException {
// Given
io.fabric8.kubernetes.client.Config kubernetesClientConfig = new io.fabric8.kubernetes.client.ConfigBuilder(io.fabric8.kubernetes.client.Config.empty())
.withMasterUrl("https://localhost:32354")
.withTrustCerts()
.withTlsVersions(TlsVersion.TLS_1_2)
.withNamespace("test")
.withHttp2Disable()
.build();
// When
kubernetesClientConfig.setCurrentContext(KubernetesMockServerUtil.createOpinionatedKubernetesContextForMockKubernetesClientConfiguration(kubernetesClientConfig));
Path exportedKubeConfig = KubernetesHelper.exportKubernetesClientConfigToFile(kubernetesClientConfig, temporaryFolder.resolve("config"));

// Then
assertThat(exportedKubeConfig).isNotNull();
assertThat(Serialization.unmarshal(exportedKubeConfig.toFile(), io.fabric8.kubernetes.api.model.Config.class))
.hasFieldOrPropertyWithValue("currentContext", "jkube-context")
.satisfies(c -> assertThat(c.getContexts())
.singleElement(InstanceOfAssertFactories.type(NamedContext.class))
.hasFieldOrPropertyWithValue("name", "jkube-context")
.hasFieldOrPropertyWithValue("context.cluster", "localhost:32354")
.hasFieldOrPropertyWithValue("context.namespace", "test")
.hasFieldOrPropertyWithValue("context.user", "jkube"))
.satisfies(c -> assertThat(c.getClusters())
.singleElement(InstanceOfAssertFactories.type(NamedCluster.class))
.hasFieldOrPropertyWithValue("name", "localhost:32354")
.hasFieldOrPropertyWithValue("cluster.server", "https://localhost:32354/")
.hasFieldOrPropertyWithValue("cluster.insecureSkipTlsVerify", true))
.satisfies(c -> assertThat(c.getUsers())
.singleElement(InstanceOfAssertFactories.type(NamedAuthInfo.class))
.hasFieldOrPropertyWithValue("name", "jkube"));
}

@Test
@DisplayName("should work with valid kube config")
void exportKubernetesClientConfigToFile_whenValidTargetFile_thenWriteKubeConfigToFile(@TempDir Path temporaryFolder) throws IOException {
// Given
io.fabric8.kubernetes.client.Config kubernetesClientConfig = createKubernetesClientConfig();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2019 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at:
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.kit.common.util;

import io.fabric8.kubernetes.api.model.NamedContext;
import io.fabric8.kubernetes.api.model.NamedContextBuilder;
import io.fabric8.kubernetes.client.Config;
import org.eclipse.jkube.kit.common.JKubeException;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Optional;

public class KubernetesMockServerUtil {
private KubernetesMockServerUtil() { }

public static NamedContext createOpinionatedKubernetesContextForMockKubernetesClientConfiguration(Config kubernetesClientConfig) {
try {
if (kubernetesClientConfig != null && kubernetesClientConfig.getCurrentContext() == null) {
URI uri = new URI(kubernetesClientConfig.getMasterUrl());
return new NamedContextBuilder()
.withName("jkube-context")
.withNewContext()
.withNamespace(kubernetesClientConfig.getNamespace())
.withCluster(String.format("%s:%d", uri.getHost(), uri.getPort()))
.withUser(Optional.ofNullable(kubernetesClientConfig.getUsername())
.orElse("jkube"))
.endContext()
.build();
}
return null;
} catch (URISyntaxException uriSyntaxException) {
throw new JKubeException("Invalid Kubernetes cluster url ", uriSyntaxException);
}
}
}

0 comments on commit ef64498

Please sign in to comment.