From 3e805cef344b88d2fa34cb23eb7383d0b86f9471 Mon Sep 17 00:00:00 2001 From: Parayya Vastrad Date: Tue, 7 Dec 2021 12:28:25 +0000 Subject: [PATCH 1/5] Adding audit log server Signed-off-by: Parayya Vastrad --- py-utils/setup.py | 3 +- py-utils/src/utils/audit_log/__init__.py | 21 +++++++ .../src/utils/audit_log/audit_log_server.py | 63 +++++++++++++++++++ py-utils/src/utils/audit_log/error.py | 36 +++++++++++ .../src/utils/utils_server/utils_server.py | 6 +- .../test/audit_log/test_audit_log_server.py | 40 ++++++++++++ 6 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 py-utils/src/utils/audit_log/__init__.py create mode 100644 py-utils/src/utils/audit_log/audit_log_server.py create mode 100644 py-utils/src/utils/audit_log/error.py create mode 100644 py-utils/test/audit_log/test_audit_log_server.py diff --git a/py-utils/setup.py b/py-utils/setup.py index 347b33d9c..943b97bbe 100644 --- a/py-utils/setup.py +++ b/py-utils/setup.py @@ -113,7 +113,8 @@ def get_requirements_files() -> list: 'cortx.utils.discovery', 'cortx.utils.common', 'cortx.utils.shared_storage', 'cortx.utils.support_framework', 'cortx.utils.manifest', 'cortx.utils.setup.openldap', - 'cortx.utils.setup.consul', 'cortx.utils.setup.elasticsearch' + 'cortx.utils.setup.consul', 'cortx.utils.setup.elasticsearch', + 'cortx.utils.audit_log' ], package_data={ 'cortx': ['py.typed'], diff --git a/py-utils/src/utils/audit_log/__init__.py b/py-utils/src/utils/audit_log/__init__.py new file mode 100644 index 000000000..b9e81dd07 --- /dev/null +++ b/py-utils/src/utils/audit_log/__init__.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +# CORTX-Py-Utils: CORTX Python common library. +# Copyright (c) 2021 Seagate Technology LLC and/or its Affiliates +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# For any questions about this software or licensing, +# please email opensource@seagate.com or cortx-questions@seagate.com. + +__title__ = 'audit_log' + +from cortx.utils.audit_log.audit_log_server import AuditLogRequestHandler +from cortx.utils.audit_log.error import AuditLogError \ No newline at end of file diff --git a/py-utils/src/utils/audit_log/audit_log_server.py b/py-utils/src/utils/audit_log/audit_log_server.py new file mode 100644 index 000000000..8965c8bb4 --- /dev/null +++ b/py-utils/src/utils/audit_log/audit_log_server.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 + +# CORTX-Py-Utils: CORTX Python common library. +# Copyright (c) 2021 Seagate Technology LLC and/or its Affiliates +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# For any questions about this software or licensing, +# please email opensource@seagate.com or cortx-questions@seagate.com. + +import json +from aiohttp import web + +from cortx.utils.utils_server import RestServer +from cortx.utils.audit_log.error import AuditLogError +from cortx.utils.utils_server.error import RestServerError +from cortx.utils.log import Log + +routes = web.RouteTableDef() + + +class AuditLogRequestHandler(RestServer): + """ Rest interface of Audit log """ + @staticmethod + async def receive(request): + Log.debug(f"Received POST request for audit message") + try: + payload = await request.json() + messages = payload['messages'] + # TODO Store audit logs messages to a persistent storage. + except AuditLogError as e: + status_code = e.rc + error_message = e.desc + Log.error(f"Unable to receive audit messages, status code: {status_code}," \ + f" error: {error_message}") + response_obj = {'error_code': status_code, 'exception': \ + ['AuditLogError', {'message': error_message}]} + except Exception as e: + exception_key = type(e).__name__ + exception = RestServerError(exception_key).http_error() + status_code = exception[0] + error_message = exception[1] + Log.error(f"Internal error while receiving audit messages." \ + f"status code: {status_code}, error: {error_message}") + response_obj = {'error_code': status_code, 'exception': \ + [exception_key, {'message': error_message}]} + raise AuditLogError(status_code, error_message) from e + else: + status_code = 200 # No exception, Success + response_obj = {} + Log.debug(f"Receiving audit messages using POST method finished with status " \ + f"code: {status_code}") + response_obj = {'status_code': status_code, 'status': 'success'} + finally: + return web.Response(text=json.dumps(response_obj), \ + status=status_code) \ No newline at end of file diff --git a/py-utils/src/utils/audit_log/error.py b/py-utils/src/utils/audit_log/error.py new file mode 100644 index 000000000..78a76a07a --- /dev/null +++ b/py-utils/src/utils/audit_log/error.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +# CORTX-Py-Utils: CORTX Python common library. +# Copyright (c) 2021 Seagate Technology LLC and/or its Affiliates +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# For any questions about this software or licensing, +# please email opensource@seagate.com or cortx-questions@seagate.com. + +class AuditLogError(Exception): + """ Generic Exception with error code and output """ + + def __init__(self, rc, message, *args): + self._rc = rc + self._desc = message % (args) + + @property + def rc(self): + return self._rc + + @property + def desc(self): + return self._desc + + def __str__(self): + if self._rc == 0: + return self._desc + return "error(%d): %s" % (self._rc, self._desc) \ No newline at end of file diff --git a/py-utils/src/utils/utils_server/utils_server.py b/py-utils/src/utils/utils_server/utils_server.py index 0db977625..e52198828 100644 --- a/py-utils/src/utils/utils_server/utils_server.py +++ b/py-utils/src/utils/utils_server/utils_server.py @@ -29,12 +29,16 @@ def __init__(self): app = web.Application() from cortx.utils.iem_framework import IemRequestHandler from cortx.utils.message_bus import MessageBusRequestHandler + from cortx.utils.audit_log import AuditLogRequestHandler app.add_routes([web.post('/EventMessage/event', IemRequestHandler.send), \ web.get('/EventMessage/event', IemRequestHandler.receive), \ web.post('/MessageBus/message/{message_type}', \ MessageBusRequestHandler.send), \ web.get('/MessageBus/message/{message_type}', \ - MessageBusRequestHandler.receive)]) + MessageBusRequestHandler.receive), + web.post('/AuditLog/message/', \ + AuditLogRequestHandler.receive) + ]) Log.info("Starting Message Server 0.0.0.0 on port 28300") web.run_app(app, port=28300) diff --git a/py-utils/test/audit_log/test_audit_log_server.py b/py-utils/test/audit_log/test_audit_log_server.py new file mode 100644 index 000000000..2c899ad9e --- /dev/null +++ b/py-utils/test/audit_log/test_audit_log_server.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +# CORTX Python common library. +# Copyright (c) 2021 Seagate Technology LLC and/or its Affiliates +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# For any questions about this software or licensing, +# please email opensource@seagate.com or cortx-questions@seagate.com. + + +import json +import unittest +import requests + + +class TestMessage(unittest.TestCase): + """Test AuditLog rest server functionality.""" + _base_url = 'http://127.0.0.1:28300/AuditLog/message/' + + def test_post(self): + """Test send message.""" + url = self._base_url + data = json.dumps({'messages': ['Hello', 'How are you?']}) + headers = {'content-type': 'application/json'} + response = requests.post(url=url, data=data, headers=headers) + self.assertEqual(response.json()['status'], 'success') + self.assertEqual(response.status_code, 200) + + +if __name__ == '__main__': + unittest.main() From 5daae7a640c048610d7386ae09afcded229c8302 Mon Sep 17 00:00:00 2001 From: Parayya Vastrad Date: Wed, 8 Dec 2021 07:52:00 +0000 Subject: [PATCH 2/5] Codacy issues Signed-off-by: Parayya Vastrad --- py-utils/src/utils/audit_log/__init__.py | 10 +++++++++- py-utils/src/utils/audit_log/audit_log_server.py | 4 ++-- py-utils/src/utils/audit_log/error.py | 3 ++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/py-utils/src/utils/audit_log/__init__.py b/py-utils/src/utils/audit_log/__init__.py index b9e81dd07..18159aca0 100644 --- a/py-utils/src/utils/audit_log/__init__.py +++ b/py-utils/src/utils/audit_log/__init__.py @@ -18,4 +18,12 @@ __title__ = 'audit_log' from cortx.utils.audit_log.audit_log_server import AuditLogRequestHandler -from cortx.utils.audit_log.error import AuditLogError \ No newline at end of file +from cortx.utils.audit_log.error import AuditLogError + +__doc__ = """ +Audit Log + +""" + +# adds all above defined packages in import * +__all__ = ('AuditLogRequestHandler', 'AuditLogError') \ No newline at end of file diff --git a/py-utils/src/utils/audit_log/audit_log_server.py b/py-utils/src/utils/audit_log/audit_log_server.py index 8965c8bb4..d6dfb0cde 100644 --- a/py-utils/src/utils/audit_log/audit_log_server.py +++ b/py-utils/src/utils/audit_log/audit_log_server.py @@ -27,10 +27,10 @@ class AuditLogRequestHandler(RestServer): - """ Rest interface of Audit log """ + """Rest interface of Audit log.""" @staticmethod async def receive(request): - Log.debug(f"Received POST request for audit message") + Log.debug("Received POST request for audit message") try: payload = await request.json() messages = payload['messages'] diff --git a/py-utils/src/utils/audit_log/error.py b/py-utils/src/utils/audit_log/error.py index 78a76a07a..afd1fb6e3 100644 --- a/py-utils/src/utils/audit_log/error.py +++ b/py-utils/src/utils/audit_log/error.py @@ -16,9 +16,10 @@ # please email opensource@seagate.com or cortx-questions@seagate.com. class AuditLogError(Exception): - """ Generic Exception with error code and output """ + """Generic Exception with error code and output.""" def __init__(self, rc, message, *args): + """Generic Exception with error code and output.""" self._rc = rc self._desc = message % (args) From 5fc1a0e75bd3354450439cac636f4dce2dc687d1 Mon Sep 17 00:00:00 2001 From: Parayya Vastrad Date: Thu, 9 Dec 2021 12:21:34 +0000 Subject: [PATCH 3/5] For error.pt makes use of UtilsError Signed-off-by: Parayya Vastrad --- py-utils/src/utils/audit_log/error.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/py-utils/src/utils/audit_log/error.py b/py-utils/src/utils/audit_log/error.py index afd1fb6e3..da7cb818f 100644 --- a/py-utils/src/utils/audit_log/error.py +++ b/py-utils/src/utils/audit_log/error.py @@ -15,23 +15,11 @@ # For any questions about this software or licensing, # please email opensource@seagate.com or cortx-questions@seagate.com. -class AuditLogError(Exception): - """Generic Exception with error code and output.""" +from cortx.utils.errors import UtilsError - def __init__(self, rc, message, *args): - """Generic Exception with error code and output.""" - self._rc = rc - self._desc = message % (args) - - @property - def rc(self): - return self._rc - @property - def desc(self): - return self._desc +class SharedStorageError(UtilsError): + """ Generic Exception with error code and output. """ - def __str__(self): - if self._rc == 0: - return self._desc - return "error(%d): %s" % (self._rc, self._desc) \ No newline at end of file + def __init__(self, rc, message, *args): + super().__init__(rc, message, *args) \ No newline at end of file From 454ec0c849c004ec10577b90b780b4d6df0ccd41 Mon Sep 17 00:00:00 2001 From: Parayya Vastrad Date: Thu, 9 Dec 2021 12:28:37 +0000 Subject: [PATCH 4/5] AuditLogError Signed-off-by: Parayya Vastrad --- py-utils/src/utils/audit_log/error.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-utils/src/utils/audit_log/error.py b/py-utils/src/utils/audit_log/error.py index da7cb818f..949322927 100644 --- a/py-utils/src/utils/audit_log/error.py +++ b/py-utils/src/utils/audit_log/error.py @@ -18,7 +18,7 @@ from cortx.utils.errors import UtilsError -class SharedStorageError(UtilsError): +class AuditLogError(UtilsError): """ Generic Exception with error code and output. """ def __init__(self, rc, message, *args): From 7b2d0507875ef7e8b887623ab62c3f067ceb38e5 Mon Sep 17 00:00:00 2001 From: Rahul Tripathi Date: Mon, 13 Dec 2021 03:23:31 -0700 Subject: [PATCH 5/5] EOS-26021: fixed codacy and pr comments Signed-off-by: Rahul Tripathi --- py-utils/src/utils/audit_log/__init__.py | 3 ++- py-utils/src/utils/audit_log/error.py | 1 + py-utils/test/audit_log/test_audit_log_server.py | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/py-utils/src/utils/audit_log/__init__.py b/py-utils/src/utils/audit_log/__init__.py index 18159aca0..d507688c6 100644 --- a/py-utils/src/utils/audit_log/__init__.py +++ b/py-utils/src/utils/audit_log/__init__.py @@ -21,8 +21,9 @@ from cortx.utils.audit_log.error import AuditLogError __doc__ = """ -Audit Log +Audit Log Server. +Audit log server can be used to send/recieve Audit logs to/from a webhook. """ # adds all above defined packages in import * diff --git a/py-utils/src/utils/audit_log/error.py b/py-utils/src/utils/audit_log/error.py index 949322927..1bbb0b997 100644 --- a/py-utils/src/utils/audit_log/error.py +++ b/py-utils/src/utils/audit_log/error.py @@ -22,4 +22,5 @@ class AuditLogError(UtilsError): """ Generic Exception with error code and output. """ def __init__(self, rc, message, *args): + """Initialize AuditLogError.""" super().__init__(rc, message, *args) \ No newline at end of file diff --git a/py-utils/test/audit_log/test_audit_log_server.py b/py-utils/test/audit_log/test_audit_log_server.py index 2c899ad9e..52e484066 100644 --- a/py-utils/test/audit_log/test_audit_log_server.py +++ b/py-utils/test/audit_log/test_audit_log_server.py @@ -22,12 +22,12 @@ import requests -class TestMessage(unittest.TestCase): +class TestAuditLog(unittest.TestCase): """Test AuditLog rest server functionality.""" _base_url = 'http://127.0.0.1:28300/AuditLog/message/' - def test_post(self): - """Test send message.""" + def test_send_audit_log(self): + """Send Audit log message.""" url = self._base_url data = json.dumps({'messages': ['Hello', 'How are you?']}) headers = {'content-type': 'application/json'}