@@ -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 () {
0 commit comments