Skip to content

Commit 76824d0

Browse files
author
Eric Menendez
committed
Refresh exec-based API credentials when they expire (for Kubernetes client v11.0.0)
This is a partial fix for kubernetes-client/python#741, based on the version of this repo included in `kubernetes-client` v11.0.0 (https://github.com/kubernetes-client/python/tree/v11.0.0). As described in kubernetes-client/python#741, some of the authentication schemes supported by Kubernetes require updating the client's credentials from time to time. The Kubernetes Python client currently does not support this, except for when using the `gcp` auth scheme. This is because the OpenAPI-generated code does not generally expect credentials to change after the client is configured. However, in OpenAPITools/openapi-generator#3594, the OpenAPI-generated code added a (undocumented) hook on the `Configuration` object which provides a method for the client credentials to be refreshed as needed. Unfortunately, this version of the Kubernetes client is too old to have that hook, but this patch adds it with a subclass of `Configuration`. Then the `load_kube_config()` function, used by the Kubernetes API to set up the `Configuration` object from the client's local k8s config, just needs to be updated to take advantage of this hook. This patch does this for `exec`-based authentication, which is a partial fix for kubernetes-client/python#741. The plan is to follow up to support this for all other authentication schemes which may require refreshing credentials. The follow-up patch will be based on the latest Kubernetes client and won't need the `Configuration` subclass. As noted above, `load_kube_config()` already has a special-case monkeypatch to refresh GCP tokens. I presume this functionality was added before the OpenAPI generator added support for the refresh hook. A complete fix will probably include refactoring the GCP token refreshing to use the new hook.
1 parent d30f1e6 commit 76824d0

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

config/kube_config.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,13 @@ def token(self):
175175
expiry=parse_rfc3339(data['credential']['token_expiry']))
176176

177177

178+
class ConfigurationWithRefreshHook(Configuration):
179+
def get_api_key_with_prefix(self, identifier):
180+
if self.refresh_api_key_hook is not None:
181+
self.refresh_api_key_hook(self)
182+
return super(ConfigurationWithRefreshHook, self).get_api_key_with_prefix(identifier)
183+
184+
178185
class KubeConfigLoader(object):
179186

180187
def __init__(self, config_dict, active_context=None,
@@ -476,6 +483,8 @@ def _load_from_exec_plugin(self):
476483
logging.error('exec: missing token field in plugin output')
477484
return None
478485
self.token = "Bearer %s" % status['token']
486+
if 'expirationTimestamp' in status:
487+
self.expiry = parse_rfc3339(status['expirationTimestamp'])
479488
return True
480489
except Exception as e:
481490
logging.error(str(e))
@@ -540,6 +549,13 @@ def _gcp_get_api_key(*args):
540549
# Note: this line runs for GCP auth tokens as well, but this entry
541550
# will not be updated upon GCP token refresh.
542551
client_configuration.api_key['authorization'] = self.token
552+
553+
def _refresh_api_key(client_configuration):
554+
if ('expiry' in self.__dict__ and
555+
self.expiry < datetime.datetime.now(tz=UTC)):
556+
self._load_authentication()
557+
self._set_config(client_configuration)
558+
client_configuration.refresh_api_key_hook = _refresh_api_key
543559
# copy these keys directly from self to configuration object
544560
keys = ['host', 'ssl_ca_cert', 'cert_file', 'key_file', 'verify_ssl']
545561
for key in keys:
@@ -739,7 +755,7 @@ def load_kube_config(config_file=None, context=None,
739755
persist_config=persist_config)
740756

741757
if client_configuration is None:
742-
config = type.__call__(Configuration)
758+
config = type.__call__(ConfigurationWithRefreshHook)
743759
loader.load_and_set(config)
744760
Configuration.set_default(config)
745761
else:

0 commit comments

Comments
 (0)