Skip to content

Commit a4163e2

Browse files
committed
Handle environment variables.
1 parent 0c3ca98 commit a4163e2

File tree

2 files changed

+54
-18
lines changed

2 files changed

+54
-18
lines changed

util/src/main/java/io/kubernetes/client/util/KubeConfig.java

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ public String getAccessToken() {
249249
* href="https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins">
250250
* Authenticating » client-go credential plugins</a>
251251
*/
252+
@SuppressWarnings("unchecked")
252253
private String tokenViaExecCredential(Map<String, Object> execMap) {
253254
if (execMap == null) {
254255
return null;
@@ -260,8 +261,28 @@ private String tokenViaExecCredential(Map<String, Object> execMap) {
260261
return null;
261262
}
262263
String command = (String) execMap.get("command");
263-
List<Map<String, String>> env = (List) execMap.get("env");
264-
List<String> args = (List) execMap.get("args");
264+
JsonElement root = runExec(command, (List) execMap.get("args"), (List) execMap.get("env"));
265+
if (root == null) {
266+
return null;
267+
}
268+
// TODO verify .apiVersion and .kind = ExecCredential
269+
JsonObject status = root.getAsJsonObject().get("status").getAsJsonObject();
270+
JsonElement token = status.get("token");
271+
if (token == null) {
272+
// TODO handle clientCertificateData/clientKeyData
273+
// (KubeconfigAuthentication is not yet set up for that to be dynamic)
274+
log.warn("No token produced by {}", command);
275+
return null;
276+
}
277+
return token.getAsString();
278+
// TODO cache tokens between calls, up to .status.expirationTimestamp
279+
// TODO a 401 is supposed to force a refresh,
280+
// but KubeconfigAuthentication hardcodes AccessTokenAuthentication which does not support that
281+
// and anyway ClientBuilder only calls Authenticator.provide once per ApiClient;
282+
// we would need to do it on every request
283+
}
284+
285+
private JsonElement runExec(String command, List<String> args, List<Map<String, String>> env) {
265286
// TODO relativize command to basedir of config file (requires KubeConfig to be given a basedir)
266287
List<String> argv = new ArrayList<>();
267288
argv.add(command);
@@ -270,7 +291,9 @@ private String tokenViaExecCredential(Map<String, Object> execMap) {
270291
}
271292
ProcessBuilder pb = new ProcessBuilder(argv);
272293
if (env != null) {
273-
// TODO apply
294+
for (Map<String, String> entry : env) {
295+
pb.environment().put(entry.get("name"), entry.get("value"));
296+
}
274297
}
275298
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
276299
try {
@@ -288,25 +311,11 @@ private String tokenViaExecCredential(Map<String, Object> execMap) {
288311
log.error("{} failed with exit code {}", command, r);
289312
return null;
290313
}
291-
// TODO verify .apiVersion and .kind = ExecCredential
292-
JsonObject status = root.getAsJsonObject().get("status").getAsJsonObject();
293-
JsonElement token = status.get("token");
294-
if (token == null) {
295-
// TODO handle clientCertificateData/clientKeyData
296-
// (KubeconfigAuthentication is not yet set up for that to be dynamic)
297-
log.warn("No token produced by {}", command);
298-
return null;
299-
}
300-
return token.getAsString();
314+
return root;
301315
} catch (IOException | InterruptedException x) {
302316
log.error("Failed to run " + command, x);
303317
return null;
304318
}
305-
// TODO cache tokens between calls, up to .status.expirationTimestamp
306-
// TODO a 401 is supposed to force a refresh,
307-
// but KubeconfigAuthentication hardcodes AccessTokenAuthentication which does not support that
308-
// and anyway ClientBuilder only calls Authenticator.provide once per ApiClient;
309-
// we would need to do it on every request
310319
}
311320

312321
public boolean verifySSL() {

util/src/test/java/io/kubernetes/client/util/KubeConfigTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,4 +296,31 @@ public void testExecCredentials() throws Exception {
296296
KubeConfig kc = KubeConfig.loadKubeConfig(new StringReader(KUBECONFIG_EXEC));
297297
assertEquals("abc123", kc.getAccessToken());
298298
}
299+
300+
private static final String KUBECONFIG_EXEC_ENV =
301+
"apiVersion: v1\n"
302+
+ "current-context: c\n"
303+
+ "contexts:\n"
304+
+ "- name: c\n"
305+
+ " context:\n"
306+
+ " user: u\n"
307+
+ "users:\n"
308+
+ "- name: u\n"
309+
+ " user:\n"
310+
+ " exec:\n"
311+
+ " apiVersion: client.authentication.k8s.io/v1beta1\n"
312+
+ " command: sh\n"
313+
+ " env:\n"
314+
+ " - name: TOK\n"
315+
+ " value: abc\n"
316+
+ " args:\n"
317+
+ " - -c\n"
318+
+ " - >-\n"
319+
+ " echo '{\"apiVersion\": \"client.authentication.k8s.io/v1beta1\", \"kind\": \"ExecCredential\", \"status\": {\"token\": \"'$TOK'123\"}}'\n";
320+
321+
@Test
322+
public void testExecCredentialsEnv() throws Exception {
323+
KubeConfig kc = KubeConfig.loadKubeConfig(new StringReader(KUBECONFIG_EXEC_ENV));
324+
assertEquals("abc123", kc.getAccessToken());
325+
}
299326
}

0 commit comments

Comments
 (0)