# HG changeset patch # User Thierry Florac # Date 1520249432 -3600 # Node ID 9f88cbe859809ff3dfbdd52721a17897322fca50 # Parent cd55139c5bae229a9099016728a498be7b915a44 Added 0MQ authentication and access control diff -r cd55139c5bae -r 9f88cbe85980 src/pyams_scheduler/include.py --- a/src/pyams_scheduler/include.py Sun Feb 18 15:30:56 2018 +0100 +++ b/src/pyams_scheduler/include.py Mon Mar 05 12:30:32 2018 +0100 @@ -22,7 +22,8 @@ import sys # import interfaces -from pyams_scheduler.interfaces import SCHEDULER_HANDLER_KEY, SCHEDULER_STARTER_KEY, SCHEDULER_NAME +from pyams_scheduler.interfaces import SCHEDULER_NAME, SCHEDULER_HANDLER_KEY, SCHEDULER_STARTER_KEY, \ + SCHEDULER_AUTH_KEY, SCHEDULER_CLIENTS_KEY from pyams_utils.interfaces import PYAMS_APPLICATION_SETTINGS_KEY, PYAMS_APPLICATION_DEFAULT_NAME from pyramid.interfaces import IApplicationCreated from zope.interface.interfaces import ComponentLookupError @@ -83,7 +84,10 @@ else: # create scheduler process process = SchedulerProcess(settings.get(SCHEDULER_HANDLER_KEY, '127.0.0.1:5555'), - SchedulerMessageHandler, registry) + SchedulerMessageHandler, + settings.get(SCHEDULER_AUTH_KEY, 'admin:admin'), + settings.get(SCHEDULER_CLIENTS_KEY, '127.0.0.1'), + registry) # load tasks for task in scheduler_util.values(): trigger = task.get_trigger(registry) diff -r cd55139c5bae -r 9f88cbe85980 src/pyams_scheduler/interfaces/__init__.py --- a/src/pyams_scheduler/interfaces/__init__.py Sun Feb 18 15:30:56 2018 +0100 +++ b/src/pyams_scheduler/interfaces/__init__.py Mon Mar 05 12:30:32 2018 +0100 @@ -88,6 +88,8 @@ SCHEDULER_NAME = 'Tasks scheduler' SCHEDULER_STARTER_KEY = 'pyams_scheduler.start_handler' SCHEDULER_HANDLER_KEY = 'pyams_scheduler.tcp_handler' +SCHEDULER_AUTH_KEY = 'pyams_scheduler.allow_auth' +SCHEDULER_CLIENTS_KEY = 'pyams_scheduler.allow_clients' SCHEDULER_JOBSTORE_KEY = 'pyams_scheduler.jobs' @@ -118,6 +120,9 @@ internal_id = Attribute("Internal ID") + def get_socket(self): + """Get ZMQ socket matching scheduler utility""" + def get_task(self, task_id): """Get task matching given task ID""" diff -r cd55139c5bae -r 9f88cbe85980 src/pyams_scheduler/process.py --- a/src/pyams_scheduler/process.py Sun Feb 18 15:30:56 2018 +0100 +++ b/src/pyams_scheduler/process.py Mon Mar 05 12:30:32 2018 +0100 @@ -206,8 +206,8 @@ class SchedulerProcess(ZMQProcess): """ØMQ tasks scheduler process""" - def __init__(self, zmq_address, handler, registry): - ZMQProcess.__init__(self, zmq_address, handler) + def __init__(self, zmq_address, handler, auth, clients, registry): + ZMQProcess.__init__(self, zmq_address, handler, auth, clients) self.registry = registry self.scheduler = BackgroundScheduler() self.jobstore = MemoryJobStore() diff -r cd55139c5bae -r 9f88cbe85980 src/pyams_scheduler/scheduler.py --- a/src/pyams_scheduler/scheduler.py Sun Feb 18 15:30:56 2018 +0100 +++ b/src/pyams_scheduler/scheduler.py Mon Mar 05 12:30:32 2018 +0100 @@ -16,7 +16,7 @@ # import standard library # import interfaces -from pyams_scheduler.interfaces import IScheduler, ISchedulerHandler, SCHEDULER_HANDLER_KEY +from pyams_scheduler.interfaces import IScheduler, ISchedulerHandler, SCHEDULER_HANDLER_KEY, SCHEDULER_AUTH_KEY from zope.intid.interfaces import IIntIds # import packages @@ -62,20 +62,21 @@ if intids is not None: return intids.register(self) + @staticmethod + def get_socket(): + """Open ØMQ socket""" + registry = get_current_registry() + handler = registry.settings.get(SCHEDULER_HANDLER_KEY, False) + if handler: + return zmq_socket(handler, auth=registry.settings.get(SCHEDULER_AUTH_KEY)) + def get_task(self, task_id): intids = query_utility(IIntIds) if intids is not None: return intids.queryObject(task_id) - def _get_socket(self): - """Open ØMQ socket""" - registry = get_current_registry() - handler = registry.settings.get(SCHEDULER_HANDLER_KEY, False) - if handler: - return zmq_socket(handler) - def get_jobs(self): - socket = self._get_socket() + socket = self.get_socket() if socket is None: return [501, "No socket handler defined in configuration file"] socket.send_json(['get_jobs', {}]) @@ -83,7 +84,7 @@ def test_process(self): """Send test request to scheduler process""" - socket = self._get_socket() + socket = self.get_socket() if socket is None: return [501, "No socket handler defined in configuration file"] socket.send_json(['test', {}]) diff -r cd55139c5bae -r 9f88cbe85980 src/pyams_scheduler/task.py --- a/src/pyams_scheduler/task.py Sun Feb 18 15:30:56 2018 +0100 +++ b/src/pyams_scheduler/task.py Mon Mar 05 12:30:32 2018 +0100 @@ -9,7 +9,6 @@ # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # -from pyramid.threadlocal import RequestContext __docformat__ = 'restructuredtext' @@ -24,8 +23,8 @@ from io import StringIO # import interfaces -from pyams_scheduler.interfaces import ITaskHistory, ITask, ITaskHistoryContainer, ITaskSchedulingMode, IScheduler, \ - SCHEDULER_HANDLER_KEY, AfterRunJobEvent, SCHEDULER_NAME, BeforeRunJobEvent, ITaskInfo +from pyams_scheduler.interfaces import IScheduler, ITask, ITaskInfo, ITaskHistory, ITaskHistoryContainer, \ + ITaskSchedulingMode, SCHEDULER_NAME, SCHEDULER_HANDLER_KEY, SCHEDULER_AUTH_KEY, AfterRunJobEvent, BeforeRunJobEvent from pyams_utils.interfaces import PYAMS_APPLICATION_DEFAULT_NAME, PYAMS_APPLICATION_SETTINGS_KEY from pyramid_mailer.interfaces import IMailer from transaction.interfaces import ITransactionManager @@ -47,6 +46,7 @@ from pyams_utils.zodb import ZODBConnection from pyams_zmq.socket import zmq_socket, zmq_response from pyramid.events import subscriber +from pyramid.threadlocal import RequestContext from pyramid_mailer.message import Message from zope.container.contained import Contained from zope.container.folder import Folder @@ -199,7 +199,7 @@ 'task_name': self.__name__, 'job_id': kwargs.get('job_id')} logger.debug("Resetting task {0.name} with {1!r}".format(self, zmq_settings)) - socket = zmq_socket(handler) + socket = zmq_socket(handler, auth=request.registry.settings.get(SCHEDULER_AUTH_KEY)) socket.send_json(['reset_task', zmq_settings]) zmq_response(socket) @@ -224,7 +224,7 @@ 'task_name': self.__name__, 'job_id': kwargs.get('job_id')} logger.debug("Running task {0.name} with {1!r}".format(self, zmq_settings)) - socket = zmq_socket(handler) + socket = zmq_socket(handler, auth=request.registry.settings.get(SCHEDULER_AUTH_KEY)) socket.send_json(['run_task', zmq_settings]) zmq_response(socket) @@ -377,6 +377,6 @@ 'task_name': task.__name__, 'job_id': task.internal_id} logger.debug("Removing task {0.name} with {1!r}".format(task, zmq_settings)) - socket = zmq_socket(handler) + socket = zmq_socket(handler, auth=request.registry.settings.get(SCHEDULER_AUTH_KEY)) socket.send_json(['remove_task', zmq_settings]) zmq_response(socket) diff -r cd55139c5bae -r 9f88cbe85980 src/pyams_scheduler/zmi/scheduler.py --- a/src/pyams_scheduler/zmi/scheduler.py Sun Feb 18 15:30:56 2018 +0100 +++ b/src/pyams_scheduler/zmi/scheduler.py Mon Mar 05 12:30:32 2018 +0100 @@ -21,7 +21,7 @@ # import interfaces from pyams_form.interfaces.form import IWidgetsSuffixViewletsManager -from pyams_scheduler.interfaces import IScheduler, SCHEDULER_HANDLER_KEY +from pyams_scheduler.interfaces import IScheduler from pyams_scheduler.zmi.interfaces import ISchedulerMenu from pyams_skin.interfaces import IInnerPage, IPageHeader from pyams_skin.interfaces.container import ITableElementEditor @@ -54,7 +54,6 @@ from pyams_zmi.control_panel import UtilitiesTable from pyams_zmi.form import AdminDialogEditForm, AdminDialogDisplayForm, AdminDialogAddForm from pyams_zmi.view import AdminView -from pyams_zmq.socket import zmq_socket, zmq_response from pyramid.url import resource_url from pyramid.view import view_config from z3c.form import field, button @@ -377,16 +376,10 @@ @property def values(self): - handler = self.request.registry.settings.get(SCHEDULER_HANDLER_KEY, False) - if handler: - socket = zmq_socket(handler) - socket.send_json(['get_jobs', {}]) - status, response = zmq_response(socket) - if status == 200: - return response - else: # error - return () - else: + status, response = self.context.get_jobs() + if status == 200: + return response + else: # error return ()