Skip to content

Commit

Permalink
fix: SnakeYaml uses SafeConstructor or delegates to Fabric8 Kubernete…
Browse files Browse the repository at this point in the history
…s Client

Signed-off-by: Marc Nuri <marc@marcnuri.com>
  • Loading branch information
manusa committed Jan 19, 2022
1 parent d8825b7 commit 77d4245
Show file tree
Hide file tree
Showing 17 changed files with 336 additions and 281 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -42,6 +42,7 @@ Usage:
* Fix #1190: OpenShiftBuildService doesn't apply resources in configured namespace
* Fix #1209: Remove WildFly Swarm support
* Fix #1219: Bump kubernetes-client to 5.11.2
* Fix #1213: SnakeYaml dependency from Kubernetes Client + uses SafeConstructor

### 1.5.1 (2021-10-28)
* Fix #1084: Gradle dependencies should be test or provided scope
Expand Down
Expand Up @@ -13,23 +13,16 @@
*/
package org.eclipse.jkube.kit.build.api.auth.handler;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.function.UnaryOperator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jkube.kit.build.api.auth.AuthConfig;
import org.eclipse.jkube.kit.build.api.auth.RegistryAuthConfig;
import org.eclipse.jkube.kit.build.api.auth.RegistryAuthHandler;
import org.eclipse.jkube.kit.common.KitLogger;
import org.yaml.snakeyaml.Yaml;

import static org.eclipse.jkube.kit.build.api.helper.KubernetesConfigAuthUtil.readKubeConfigAuth;

/**
* @author roland
Expand Down Expand Up @@ -63,7 +56,7 @@ public AuthConfig create(RegistryAuthConfig.Kind kind, String user, String regis
return null;
}
log.debug("AuthConfig: OpenShift credentials");
return validateMandatoryOpenShiftLogin(parseOpenShiftConfig());
return validateMandatoryOpenShiftLogin(readKubeConfigAuth());
}

boolean useOpenShiftAuth =
Expand All @@ -72,7 +65,7 @@ public AuthConfig create(RegistryAuthConfig.Kind kind, String user, String regis
.orElse(false);
if (useOpenShiftAuth) {
log.debug("AuthConfig: OpenShift credentials");
return validateMandatoryOpenShiftLogin(parseOpenShiftConfig());
return validateMandatoryOpenShiftLogin(readKubeConfigAuth());
}

return null;
Expand All @@ -87,87 +80,6 @@ private AuthConfig validateMandatoryOpenShiftLogin(AuthConfig openShiftRegistryA
throw new IllegalArgumentException(
String.format("OpenShift auth check enabled, but not active user and/or token found in %s. " +
"Please use 'oc login' for connecting to OpenShift.", kubeConfigEnv != null ? kubeConfigEnv : "~/.kube/config"));

}

// Parse OpenShift config to get credentials, but return null if not found
private AuthConfig parseOpenShiftConfig() {
Map kubeConfig = readKubeConfig();
if (kubeConfig == null) {
return null;
}

String currentContextName = (String) kubeConfig.get("current-context");
if (currentContextName == null) {
return null;
}

for (Map contextMap : (List<Map>) kubeConfig.get("contexts")) {
if (currentContextName.equals(contextMap.get("name"))) {
return parseContext(kubeConfig, (Map) contextMap.get("context"));
}
}

return null;
}

private Map<String, ?> readKubeConfig() {
String kubeConfig = System.getenv("KUBECONFIG");
Optional<Reader> reader =
getFileReaderFromDir(kubeConfig == null ? new File(getHomeDir(), ".kube/config") : new File(kubeConfig));

return (Map<String, ?>) reader.map(r -> new Yaml().load(r)).orElse(null);
}

private Optional<Reader> getFileReaderFromDir(File file) {
try {
return Optional.of(new FileReader(file));
} catch (FileNotFoundException e) {
return Optional.empty();
}
}

private File getHomeDir() {
String homeDir = System.getProperty("user.home") != null ? System.getProperty("user.home") : System.getenv("HOME");
return new File(homeDir);
}

private AuthConfig parseContext(Map kubeConfig, Map context) {
if (context == null) {
return null;
}
String userName = (String) context.get("user");
if (userName == null) {
return null;
}

List<Map> users = (List<Map>) kubeConfig.get("users");
if (users == null) {
return null;
}

for (Map userMap : users) {
if (userName.equals(userMap.get("name"))) {
return parseUser(userName, (Map) userMap.get("user"));
}
}
return null;
}

private AuthConfig parseUser(String userName, Map user) {
if (user == null) {
return null;
}
String token = (String) user.get("token");
if (token == null) {
return null;
}

// Strip off stuff after username
Matcher matcher = Pattern.compile("^([^/]+).*$").matcher(userName);
return AuthConfig.builder()
.username(matcher.matches() ? matcher.group(1) : userName)
.password(token)
.build();
}
}
Expand Up @@ -13,15 +13,6 @@
*/
package org.eclipse.jkube.kit.build.api.helper;

import com.google.gson.Gson;
import com.google.gson.JsonObject;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.jkube.kit.common.JKubeFileInterpolator;
import org.eclipse.jkube.kit.config.image.ImageConfiguration;
import org.eclipse.jkube.kit.config.image.build.BuildConfiguration;
import org.yaml.snakeyaml.Yaml;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
Expand All @@ -41,6 +32,14 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jkube.kit.common.JKubeFileInterpolator;
import org.eclipse.jkube.kit.config.image.ImageConfiguration;
import org.eclipse.jkube.kit.config.image.build.BuildConfiguration;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.apache.commons.lang3.StringUtils;

/**
* Utility class for dealing with dockerfiles
* @author roland
Expand Down Expand Up @@ -215,19 +214,6 @@ public static String[] extractDelimiters(String filter) {
return new String[] { filter, filter };
}

public static Map<String,?> readKubeConfig() {
String kubeConfig = System.getenv("KUBECONFIG");

Reader reader = kubeConfig == null
? getFileReaderFromDir(new File(getHomeDir(),".kube/config"))
: getFileReaderFromDir(new File(kubeConfig));
if (reader != null) {
Yaml ret = new Yaml();
return ret.load(reader);
}
return null;
}

public static boolean isSimpleDockerFileMode(File projectBaseDirectory) {
if (projectBaseDirectory != null) {
return getTopLevelDockerfile(projectBaseDirectory).exists();
Expand Down
@@ -0,0 +1,116 @@
/**
* 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.build.api.helper;


import com.fasterxml.jackson.core.type.TypeReference;
import io.fabric8.kubernetes.client.utils.Serialization;
import org.eclipse.jkube.kit.build.api.auth.AuthConfig;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class KubernetesConfigAuthUtil {

private static final String KUBECONFIG_ENV = "KUBECONFIG";
private static final Path KUBECONFIG_FILE = Paths.get(".kube", "config");

private KubernetesConfigAuthUtil() {
}

public static AuthConfig readKubeConfigAuth() {
Map<String, ?> kubeConfig = readKubeConfig();
if (kubeConfig == null) {
return null;
}
String currentContextName = (String) kubeConfig.get("current-context");
if (currentContextName == null) {
return null;
}

for (Map<String, ?> contextMap : (List<Map<String, ?>>) kubeConfig.get("contexts")) {
if (currentContextName.equals(contextMap.get("name"))) {
return parseContext(kubeConfig, (Map<String, ?>) contextMap.get("context"));
}
}

return null;
}

private static AuthConfig parseContext(Map<String, ?> kubeConfig, Map<String, ?> context) {
if (context == null) {
return null;
}
String userName = (String) context.get("user");
if (userName == null) {
return null;
}

List<Map<String, ?>> users = (List<Map<String, ?>>) kubeConfig.get("users");
if (users == null) {
return null;
}

for (Map<String, ?> userMap : users) {
if (userName.equals(userMap.get("name"))) {
return parseUser(userName, (Map<String, ?>) userMap.get("user"));
}
}
return null;
}

private static AuthConfig parseUser(String userName, Map<String, ?> user) {
if (user == null) {
return null;
}
String token = (String) user.get("token");
if (token == null) {
return null;
}

// Strip off stuff after username
Matcher matcher = Pattern.compile("^([^/]+).*$").matcher(userName);
return AuthConfig.builder()
.username(matcher.matches() ? matcher.group(1) : userName)
.password(token)
.build();
}

private static Map<String, Object> readKubeConfig() {
String kubeConfig = System.getenv(KUBECONFIG_ENV);
final File applicableFile = kubeConfig == null ?
getHomeDir().toPath().resolve(KUBECONFIG_FILE).toFile() : new File(kubeConfig);
if (applicableFile.exists()) {
try (FileInputStream fis = new FileInputStream(applicableFile)) {
return Serialization.unmarshal(fis, new TypeReference<Map<String, Object>>() {});
} catch (IOException ex) {
// Ignore
}
}
return Collections.emptyMap();
}

private static File getHomeDir() {
String homeDir = System.getProperty("user.home") != null ? System.getProperty("user.home") : System.getenv("HOME");
return new File(homeDir);
}
}
Expand Up @@ -46,13 +46,13 @@ public class OpenShiftRegistryAuthHandlerTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();

@Mocked
KitLogger log;

OpenShiftRegistryAuthHandler handler;

@Before
public void setup() {
log = new KitLogger.SilentLogger();
RegistryAuthConfig registryAuthConfig = RegistryAuthConfig.builder()
.skipExtendedAuthentication(false)
.propertyPrefix("docker")
Expand Down

0 comments on commit 77d4245

Please sign in to comment.