From 3a1e41fecfe9e4b7dfa8391476202c3113456c89 Mon Sep 17 00:00:00 2001 From: Colleen Murphy Date: Tue, 26 Jul 2016 13:02:42 -0700 Subject: [PATCH] Add dummy domain_id column to cached role When token caching is turned on, upgrading from stable/liberty to stable/mitaka or master causes tokens to fail to be issued for the time-to-live of the cache. This is because as part of the token issuance the token's role is looked up, and the cached version of the role immediately after upgrade does not have a domain_id field, even though that column was successfully added to the role database. This patch hacks around that by artificially adding a null domain_id value to the role reference. This must be done in the manager, as opposed to the driver, because it is the manager that is caching the value and so modifying the value returned by the driver has no effect. Change-Id: I55c791486f2a26ae995f693370b016895176a16f Closes-bug: #1592169 (cherry picked from commit bc99dc76775d22eca01b818f37de35a76ece9d72) --- keystone/assignment/core.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/keystone/assignment/core.py b/keystone/assignment/core.py index 05368fbfb4..d9efe2e0c0 100644 --- a/keystone/assignment/core.py +++ b/keystone/assignment/core.py @@ -16,6 +16,7 @@ import abc import copy +import functools from oslo_cache import core as oslo_cache from oslo_config import cfg @@ -1495,6 +1496,31 @@ class RoleManager(manager.Manager): elif not isinstance(self.driver, RoleDriverV9): raise exception.UnsupportedDriverVersion(driver=role_driver) + def _append_null_domain_id(f): + """Append a domain_id field to a role dict if it is not already there. + + When caching is turned on, upgrading from liberty to + mitaka or master causes tokens to fail to be issued for the + time-to-live of the cache. This is because as part of the token + issuance the token's role is looked up, and the cached version of the + role immediately after upgrade does not have a domain_id field, even + though that column was successfully added to the role database. This + decorator artificially adds a null domain_id value to the role + reference so that the cached value acts like the updated schema. + + Note: This decorator must appear before the @MEMOIZE decorator + because it operates on the cached value returned by the MEMOIZE + function. + """ + @functools.wraps(f) + def wrapper(self, *args, **kwargs): + ref = f(self, *args, **kwargs) + if 'domain_id' not in ref: + ref['domain_id'] = None + return ref + return wrapper + + @_append_null_domain_id @MEMOIZE def get_role(self, role_id): return self.driver.get_role(role_id)