Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#238: support client.authentication.k8s.io/v1beta1 ExecCredential #512

Merged
merged 11 commits into from
Mar 8, 2019
Prev Previous commit
Next Next commit
Honoring basedir for relative command paths.
  • Loading branch information
jglick committed Mar 4, 2019
commit 2d22dced9b7fc4f77f4f72720539f2ae155df125
Original file line number Diff line number Diff line change
Expand Up @@ -78,21 +78,23 @@ public static ClientBuilder standard() throws IOException {
public static ClientBuilder standard(boolean persistConfig) throws IOException {
final File kubeConfig = findConfigFromEnv();
if (kubeConfig != null) {
try (FileReader kubeConfigReader = new FileReader(kubeConfig)) {
try (FileReader kubeConfigReader = new FileReader(kubeConfig)) { // TODO UTF-8
KubeConfig kc = KubeConfig.loadKubeConfig(kubeConfigReader);
if (persistConfig) {
kc.setPersistConfig(new FilePersister(kubeConfig));
}
kc.setFile(kubeConfig);
return kubeconfig(kc);
}
}
final File config = findConfigInHomeDir();
if (config != null) {
try (FileReader configReader = new FileReader(config)) {
try (FileReader configReader = new FileReader(config)) { // TODO UTF-8
KubeConfig kc = KubeConfig.loadKubeConfig(configReader);
if (persistConfig) {
kc.setPersistConfig(new FilePersister(config));
}
kc.setFile(kubeConfig);
return kubeconfig(kc);
}
}
Expand Down
7 changes: 5 additions & 2 deletions util/src/main/java/io/kubernetes/client/util/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.kubernetes.client.ApiClient;
import io.kubernetes.client.util.credentials.AccessTokenAuthentication;
import io.kubernetes.client.util.credentials.UsernamePasswordAuthentication;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -73,11 +74,13 @@ public static ApiClient fromToken(String url, String token, boolean validateSSL)
}

public static ApiClient fromConfig(String fileName) throws IOException {
return fromConfig(new FileReader(fileName));
KubeConfig config = KubeConfig.loadKubeConfig(new FileReader(fileName)); // TODO UTF-8
config.setFile(new File(fileName));
return fromConfig(config);
}

public static ApiClient fromConfig(InputStream stream) throws IOException {
return fromConfig(new InputStreamReader(stream));
return fromConfig(new InputStreamReader(stream)); // TODO UTF-8
}

public static ApiClient fromConfig(Reader input) throws IOException {
Expand Down
24 changes: 22 additions & 2 deletions util/src/main/java/io/kubernetes/client/util/KubeConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.kubernetes.client.util.authenticators.Authenticator;
import io.kubernetes.client.util.authenticators.AzureActiveDirectoryAuthenticator;
import io.kubernetes.client.util.authenticators.GCPAuthenticator;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
Expand Down Expand Up @@ -61,6 +62,7 @@ public class KubeConfig {
String currentNamespace;
Object preferences;
ConfigPersister persister;
private File file;

public static void registerAuthenticator(Authenticator auth) {
synchronized (authenticators) {
Expand Down Expand Up @@ -283,9 +285,18 @@ private String tokenViaExecCredential(Map<String, Object> execMap) {
}

private JsonElement runExec(String command, List<String> args, List<Map<String, String>> env) {
// TODO relativize command to basedir of config file (requires KubeConfig to be given a basedir)
List<String> argv = new ArrayList<>();
argv.add(command);
if (command.startsWith("./")) {
jglick marked this conversation as resolved.
Show resolved Hide resolved
// TODO spec is unclear on what should be treated as a “relative command path”
File resolvedCommand = new File(file.getParentFile(), command);
if (!resolvedCommand.isFile()) {
log.error("No such file: {}", resolvedCommand);
return null;
}
argv.add(resolvedCommand.getAbsolutePath());
} else {
argv.add(command);
}
if (args != null) {
argv.addAll(args);
}
Expand Down Expand Up @@ -337,6 +348,15 @@ public void setPersistConfig(ConfigPersister persister) {
this.persister = persister;
}

/**
* Indicates a file from which this configuration was loaded.
*
* @param file a file path, available for use when resolving relative file paths
*/
public void setFile(File file) {
this.file = file;
}

public void setPreferences(Object preferences) {
this.preferences = preferences;
}
Expand Down
42 changes: 42 additions & 0 deletions util/src/test/java/io/kubernetes/client/util/KubeConfigTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ public void testRefreshToken() {
@Test
public void testExecCredentials() throws Exception {
KubeConfig kc = KubeConfig.loadKubeConfig(new StringReader(KUBECONFIG_EXEC));
kc.setFile(folder.newFile()); // just making sure it is ignored
assertEquals("abc123", kc.getAccessToken());
}

Expand Down Expand Up @@ -323,4 +324,45 @@ public void testExecCredentialsEnv() throws Exception {
KubeConfig kc = KubeConfig.loadKubeConfig(new StringReader(KUBECONFIG_EXEC_ENV));
assertEquals("abc123", kc.getAccessToken());
}

private static final String KUBECONFIG_EXEC_BASEDIR =
"apiVersion: v1\n"
+ "current-context: c\n"
+ "contexts:\n"
+ "- name: c\n"
+ " context:\n"
+ " user: u\n"
+ "users:\n"
+ "- name: u\n"
+ " user:\n"
+ " exec:\n"
+ " apiVersion: client.authentication.k8s.io/v1beta1\n"
+ " command: ./bin/authenticate\n";

private static final String AUTH_SCRIPT =
"#!/bin/sh\n"
+ "echo '{\"apiVersion\": \"client.authentication.k8s.io/v1beta1\", \"kind\": \"ExecCredential\", \"status\": {\"token\": \"abc123\"}}'\n";

@Test
public void testExecCredentialsBasedir() throws Exception {
File basedir = folder.newFolder();
File config = new File(basedir, ".kubeconfig");
try (FileWriter writer = new FileWriter(config)) {
writer.write(KUBECONFIG_EXEC_BASEDIR);
writer.flush();
}
File bindir = new File(basedir, "bin");
bindir.mkdir();
File script = new File(bindir, "authenticate");
try (FileWriter writer = new FileWriter(script)) {
writer.write(AUTH_SCRIPT);
writer.flush();
}
script.setExecutable(true);
try (FileReader reader = new FileReader(config)) {
KubeConfig kc = KubeConfig.loadKubeConfig(reader);
kc.setFile(config);
assertEquals("abc123", kc.getAccessToken());
}
}
}