Added 0MQ authentication and access control
authorThierry Florac <thierry.florac@onf.fr>
Mon, 05 Mar 2018 12:30:32 +0100
changeset 54 9f88cbe85980
parent 53 cd55139c5bae
child 55 8ba86a8b057b
Added 0MQ authentication and access control
src/pyams_scheduler/include.py
src/pyams_scheduler/interfaces/__init__.py
src/pyams_scheduler/process.py
src/pyams_scheduler/scheduler.py
src/pyams_scheduler/task.py
src/pyams_scheduler/zmi/scheduler.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)
--- 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"""
 
--- 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()
--- 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', {}])
--- 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)
--- 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 ()