From df68a90e057c2e1e3427d6b8497b437c8a4c3b7e Mon Sep 17 00:00:00 2001 From: Jerry Sun Date: Tue, 11 Jun 2019 15:04:04 -0400 Subject: [PATCH] Fix unauthenticated requests to create locks Kubernetes requests to create locks in the lock_and_thread decorator were being done without the bearer token. This creates authentication errors when communicating with a Kubernetes cluster configured with an external auth backend. This commit uses the bearer token when creating the Kubernetes client used to create a lock object for lock_and_thread The bearer token is obtained from the tiller object passed to the function being decorated by lock_and_thread. Currently, all functions decorated by lock_and_thread passes a tiller object to obtain a token from. If no tiller object is found in the params, this will be logged to assist with potential debugging in the future. An exception is not thrown because a Kubernetes cluster without external auth can be used without passing any bearer tokens around. Change-Id: Ic9329c2f605cb508750065ebd0c756869be94199 Signed-off-by: Jerry Sun --- armada/handlers/lock.py | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/armada/handlers/lock.py b/armada/handlers/lock.py index 80510804..fcef2b87 100644 --- a/armada/handlers/lock.py +++ b/armada/handlers/lock.py @@ -21,6 +21,7 @@ from oslo_config import cfg from oslo_log import log as logging from armada.handlers.k8s import K8s +from armada.handlers.tiller import Tiller CONF = cfg.CONF @@ -51,7 +52,22 @@ def lock_and_thread(lock_name="lock"): @functools.wraps(func) def func_wrapper(*args, **kwargs): - with Lock(lock_name) as lock: + bearer_token = None + found_tiller = False + for arg in args: + if type(arg) == Tiller: + bearer_token = arg.bearer_token + found_tiller = True + + # we did not find a Tiller object to extract a bearer token from + # log this to assist with potential debugging in the future + if not found_tiller: + LOG.info("no Tiller object found in parameters of function " + "decorated by lock_and_thread, this might create " + "authentication issues in Kubernetes clusters with " + "external auth backend") + + with Lock(lock_name, bearer_token=bearer_token) as lock: pool = ThreadPoolExecutor(1) future = pool.submit(func, *args, **kwargs) start = time.time() @@ -69,7 +85,7 @@ def lock_and_thread(lock_name="lock"): class Lock: - def __init__(self, lock_name, additional_data=None): + def __init__(self, lock_name, bearer_token=None, additional_data=None): """Creates a lock with the specified name and data. When a lock with that name already exists then this will continuously attempt to acquire it until: @@ -87,7 +103,9 @@ class Lock: self.timeout = CONF.lock_acquire_timeout self.acquire_delay = CONF.lock_acquire_delay self.lock_config = LockConfig( - name=lock_name, additional_data=additional_data) + name=lock_name, + bearer_token=bearer_token, + additional_data=additional_data) def _test_lock_ownership(self): # If the uid of the current lock is the same as the one given when we @@ -166,7 +184,7 @@ class Lock: class LockConfig: - def __init__(self, name, additional_data=None): + def __init__(self, name, bearer_token=None, additional_data=None): self.name = name data = additional_data or dict() self.full_name = "{}.{}.{}".format(LOCK_PLURAL, LOCK_GROUP, self.name) @@ -179,7 +197,7 @@ class LockConfig: } self.delete_options = {} - self.k8s = K8s() + self.k8s = K8s(bearer_token=bearer_token) def create_lock(self): """ Creates the Lock custom resource object