From d12aa27712c12c6abc04274b1f4122f613667f4a Mon Sep 17 00:00:00 2001 From: Smruti Soumitra Khuntia Date: Wed, 20 Feb 2019 15:22:37 +0530 Subject: [PATCH] End user logging for audit traceabilty Changes for Client to support new end user header and add end user name to logs. Change-Id: Iea1e42eafa573960735415ce337a1558b864edfc --- python/drydock_provisioner/control/base.py | 9 ++++++++- python/drydock_provisioner/control/middleware.py | 10 ++++++++++ python/drydock_provisioner/drydock.py | 3 ++- python/drydock_provisioner/drydock_client/session.py | 5 +++++ python/tests/conftest.py | 3 ++- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/python/drydock_provisioner/control/base.py b/python/drydock_provisioner/control/base.py index 4e84a04d..039efceb 100644 --- a/python/drydock_provisioner/control/base.py +++ b/python/drydock_provisioner/control/base.py @@ -71,13 +71,15 @@ class BaseResource(object): resp.status = status_code def log_error(self, ctx, level, msg): - extra = {'user': 'N/A', 'req_id': 'N/A', 'external_ctx': 'N/A'} + extra = {'user': 'N/A', 'req_id': 'N/A', 'external_ctx': 'N/A', + 'end_user': 'N/A'} if ctx is not None: extra = { 'user': ctx.user, 'req_id': ctx.request_id, 'external_ctx': ctx.external_marker, + 'end_user': ctx.end_user, } self.logger.log(level, msg, extra=extra) @@ -130,6 +132,7 @@ class DrydockRequestContext(object): self.request_id = str(uuid.uuid4()) self.external_marker = '' self.policy_engine = None + self.end_user = None # Initial User @classmethod def from_dict(cls, d): @@ -160,6 +163,7 @@ class DrydockRequestContext(object): 'authenticated': self.authenticated, 'request_id': self.request_id, 'external_marker': self.external_marker, + 'end_user': self.end_user, } def set_log_level(self, level): @@ -187,6 +191,9 @@ class DrydockRequestContext(object): def set_policy_engine(self, engine): self.policy_engine = engine + def set_end_user(self, end_user): + self.end_user = end_user + def to_policy_view(self): policy_dict = {} diff --git a/python/drydock_provisioner/control/middleware.py b/python/drydock_provisioner/control/middleware.py index c03c854a..b5db9840 100644 --- a/python/drydock_provisioner/control/middleware.py +++ b/python/drydock_provisioner/control/middleware.py @@ -87,10 +87,18 @@ class ContextMiddleware(object): ctx = req.context ext_marker = req.get_header('X-Context-Marker') + end_user = req.get_header('X-End-User') if ext_marker is not None and self.marker_re.fullmatch(ext_marker): ctx.set_external_marker(ext_marker) + # Set end user from req header in context obj if available + # else set the user as end user. + if end_user is not None: + ctx.set_end_user(end_user) + else: + ctx.set_end_user(ctx.user) + class LoggingMiddleware(object): def __init__(self): @@ -101,6 +109,7 @@ class LoggingMiddleware(object): 'user': req.context.user, 'req_id': req.context.request_id, 'external_ctx': req.context.external_marker, + 'end_user': req.context.end_user, } self.logger.info( "Request: %s %s %s" % (req.method, req.uri, req.query_string), @@ -112,6 +121,7 @@ class LoggingMiddleware(object): 'user': ctx.user, 'req_id': ctx.request_id, 'external_ctx': ctx.external_marker, + 'end_user': ctx.end_user, } resp.append_header('X-Drydock-Req', ctx.request_id) self.logger.info( diff --git a/python/drydock_provisioner/drydock.py b/python/drydock_provisioner/drydock.py index 713ccdaf..944a5573 100644 --- a/python/drydock_provisioner/drydock.py +++ b/python/drydock_provisioner/drydock.py @@ -63,7 +63,8 @@ def start_drydock(enable_keystone=True): config.config_mgr.conf.logging.control_logger_name) logger.propagate = False formatter = logging.Formatter( - '%(asctime)s - %(levelname)s - %(user)s - %(req_id)s - %(external_ctx)s - %(message)s' + "%(asctime)s - %(levelname)s - %(user)s - %(req_id)s" + " - %(external_ctx)s - %(end_user)s - %(message)s" ) ch = logging.StreamHandler() diff --git a/python/drydock_provisioner/drydock_client/session.py b/python/drydock_provisioner/drydock_client/session.py index 711b3af0..b59720f9 100644 --- a/python/drydock_provisioner/drydock_client/session.py +++ b/python/drydock_provisioner/drydock_client/session.py @@ -39,6 +39,7 @@ class DrydockSession(object): scheme='http', auth_gen=None, marker=None, + end_user=None, timeout=None): self.logger = logging.getLogger(__name__) self.__session = requests.Session() @@ -47,8 +48,12 @@ class DrydockSession(object): self.set_auth() self.marker = marker + self.end_user = end_user self.__session.headers.update({'X-Context-Marker': marker}) + if end_user: + self.__session.headers.update({'X-End-User': end_user}) + self.host = host self.scheme = scheme diff --git a/python/tests/conftest.py b/python/tests/conftest.py index e4f9cda0..4cda5a0e 100644 --- a/python/tests/conftest.py +++ b/python/tests/conftest.py @@ -123,7 +123,8 @@ def setup_logging(): logger = logging.getLogger('drydock.control') logger.propagate = False formatter = logging.Formatter( - '%(asctime)s - %(levelname)s - %(user)s - %(req_id)s - %(external_ctx)s - %(message)s' + "%(asctime)s - %(levelname)s - %(user)s - %(req_id)s" + " - %(external_ctx)s - %(end_user)s - %(message)s" ) ch = logging.StreamHandler()