Skip to content
This repository was archived by the owner on Mar 13, 2022. It is now read-only.

Commit 423710c

Browse files
committed
Add option to refresh gcp token when config is cmd-path
1 parent a2d1024 commit 423710c

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

Diff for: config/kube_config.py

+69
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414

1515
import atexit
1616
import base64
17+
from collections import namedtuple
1718
import copy
1819
import datetime
1920
import json
2021
import logging
2122
import os
2223
import platform
24+
import subprocess
2325
import tempfile
2426
import time
2527

@@ -132,6 +134,46 @@ def as_data(self):
132134
self._data = f.read()
133135
return self._data
134136

137+
class CommandTokenSource(object):
138+
def __init__(self, cmd, args, tokenKey, expiryKey):
139+
140+
self._cmd = cmd
141+
self._args = args
142+
if not tokenKey:
143+
self._tokenKey = '{.access_token}'
144+
else:
145+
self._tokenKey = tokenKey
146+
if not expiryKey:
147+
self._expiryKey = '{.token_expiry}'
148+
else:
149+
self._expiryKey = expiryKey
150+
151+
def token(self):
152+
fullCmd = self._cmd + (" ") + " ".join(self._args)
153+
process = subprocess.Popen(
154+
[self._cmd] + self._args,
155+
stdout=subprocess.PIPE,
156+
stderr=subprocess.PIPE,
157+
universal_newlines=True)
158+
(stdout, stderr) = process.communicate()
159+
exit_code = process.wait()
160+
if exit_code != 0:
161+
msg = 'cmd-path: process returned %d' % exit_code
162+
msg += "\nCmd: %s" % fullCmd
163+
stderr = stderr.strip()
164+
if stderr:
165+
msg += '\nStderr: %s' % stderr
166+
raise ConfigException(msg)
167+
try:
168+
data = json.loads(stdout)
169+
except ValueError as de:
170+
raise ConfigException(
171+
'exec: failed to decode process output: %s' % de)
172+
A = namedtuple('A', [ 'token', 'expiry' ])
173+
return A(
174+
token=data['credential']['access_token'],
175+
expiry=parse_rfc3339(data['credential']['token_expiry']))
176+
135177

136178
class KubeConfigLoader(object):
137179

@@ -156,7 +198,34 @@ def __init__(self, config_dict, active_context=None,
156198
self._config_base_path = config_base_path
157199
self._config_persister = config_persister
158200

201+
def _refresh_credentials_with_cmd_path():
202+
config = self._user['auth-provider']['config']
203+
cmd = config['cmd-path']
204+
if len(cmd) == 0:
205+
raise ConfigException('missing access token cmd (cmd-path is an empty string in your kubeconfig file)')
206+
if 'scopes' in config and config['scopes'] != "":
207+
raise ConfigException('scopes can only be used when kubectl is using a gcp service account key')
208+
args = []
209+
if 'cmd-args' in config:
210+
args = config['cmd-args'].split()
211+
else:
212+
fields = config['cmd-path'].split()
213+
cmd = fields[0]
214+
args = fields[1:]
215+
216+
commandTokenSource = CommandTokenSource(
217+
cmd, args,
218+
config.safe_get('token-key'),
219+
config.safe_get('expiry-key'))
220+
return commandTokenSource.token()
221+
159222
def _refresh_credentials():
223+
# Refresh credentials using cmd-path
224+
if ('auth-provider' in self._user and
225+
'config' in self._user['auth-provider'] and
226+
'cmd-path' in self._user['auth-provider']['config']):
227+
return _refresh_credentials_with_cmd_path()
228+
160229
credentials, project_id = google.auth.default(scopes=[
161230
'https://www.googleapis.com/auth/cloud-platform',
162231
'https://www.googleapis.com/auth/userinfo.email'

0 commit comments

Comments
 (0)