Просмотр исходного кода

15093 Allow plugins to register events pipeline (#17717)

* 15093 add events_pipeline registration to plugins

* 15093 use list

* 15093 add documentation

* Update docs/configuration/index.md

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* Update docs/configuration/miscellaneous.md

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* 15093 review changes

* 15093 review changes

* Formatting & readability

* 15093 review changes

* 15093 add test

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Arthur Hanson 1 год назад
Родитель
Сommit
b9c6def8ab

+ 9 - 0
docs/configuration/miscellaneous.md

@@ -106,6 +106,15 @@ By default, NetBox will prevent the creation of duplicate prefixes and IP addres
 
 ---
 
+## EVENTS_PIPELINE
+
+
+Default: `['extras.events.process_event_queue',]`
+
+NetBox will call dotted paths to the functions listed here for events (create, update, delete) on models as well as when custom EventRules are fired.
+
+---
+
 ## FILE_UPLOAD_MAX_MEMORY_SIZE
 
 Default: `2621440` (2.5 MB)

+ 1 - 0
docs/plugins/development/index.md

@@ -114,6 +114,7 @@ NetBox looks for the `config` variable within a plugin's `__init__.py` to load i
 | `max_version`         | Maximum version of NetBox with which the plugin is compatible                                                            |
 | `middleware`          | A list of middleware classes to append after NetBox's build-in middleware                                                |
 | `queues`              | A list of custom background task queues to create                                                                        |
+| `events_pipeline`     | A list of handlers to add to [`EVENTS_PIPELINE`](./miscellaneous.md#events_pipeline), identified by dotted paths         |
 | `search_extensions`   | The dotted path to the list of search index classes (default: `search.indexes`)                                          |
 | `data_backends`       | The dotted path to the list of data source backend classes (default: `data_backends.backends`)                           |
 | `template_extensions` | The dotted path to the list of template extension classes (default: `template_content.template_extensions`)              |

+ 1 - 0
netbox/netbox/plugins/__init__.py

@@ -78,6 +78,7 @@ class PluginConfig(AppConfig):
     menu_items = None
     template_extensions = None
     user_preferences = None
+    events_pipeline = []
 
     def _load_resource(self, name):
         # Import from the configured path, if defined.

+ 13 - 2
netbox/netbox/settings.py

@@ -110,9 +110,9 @@ DEFAULT_PERMISSIONS = getattr(configuration, 'DEFAULT_PERMISSIONS', {
 DEVELOPER = getattr(configuration, 'DEVELOPER', False)
 DOCS_ROOT = getattr(configuration, 'DOCS_ROOT', os.path.join(os.path.dirname(BASE_DIR), 'docs'))
 EMAIL = getattr(configuration, 'EMAIL', {})
-EVENTS_PIPELINE = getattr(configuration, 'EVENTS_PIPELINE', (
+EVENTS_PIPELINE = getattr(configuration, 'EVENTS_PIPELINE', [
     'extras.events.process_event_queue',
-))
+])
 EXEMPT_VIEW_PERMISSIONS = getattr(configuration, 'EXEMPT_VIEW_PERMISSIONS', [])
 FIELD_CHOICES = getattr(configuration, 'FIELD_CHOICES', {})
 FILE_UPLOAD_MAX_MEMORY_SIZE = getattr(configuration, 'FILE_UPLOAD_MAX_MEMORY_SIZE', 2621440)
@@ -787,6 +787,10 @@ STRAWBERRY_DJANGO = {
 
 PLUGIN_CATALOG_URL = 'https://api.netbox.oss.netboxlabs.com/v1/plugins'
 
+EVENTS_PIPELINE = list(EVENTS_PIPELINE)
+if 'extras.events.process_event_queue' not in EVENTS_PIPELINE:
+    EVENTS_PIPELINE.insert(0, 'extras.events.process_event_queue')
+
 # Register any configured plugins
 for plugin_name in PLUGINS:
     try:
@@ -857,6 +861,13 @@ for plugin_name in PLUGINS:
         f"{plugin_name}.{queue}": RQ_PARAMS for queue in plugin_config.queues
     })
 
+    events_pipeline = plugin_config.events_pipeline
+    if events_pipeline:
+        if type(events_pipeline) in (list, tuple):
+            EVENTS_PIPELINE.extend(events_pipeline)
+        else:
+            raise ImproperlyConfigured(f"events_pipline in plugin: {plugin_name} must be a list or tuple")
+
 # UNSUPPORTED FUNCTIONALITY: Import any local overrides.
 try:
     from .local_settings import *

+ 3 - 0
netbox/netbox/tests/dummy_plugin/__init__.py

@@ -17,6 +17,9 @@ class DummyPluginConfig(PluginConfig):
         'testing-medium',
         'testing-high'
     ]
+    events_pipeline = [
+        'netbox.tests.dummy_plugin.events.process_events_queue'
+    ]
 
 
 config = DummyPluginConfig

+ 2 - 0
netbox/netbox/tests/dummy_plugin/events.py

@@ -0,0 +1,2 @@
+def process_events_queue(events):
+    pass

+ 7 - 0
netbox/netbox/tests/test_plugins.py

@@ -203,3 +203,10 @@ class PluginTest(TestCase):
         self.assertEqual(get_plugin_config(plugin, 'foo'), 123)
         self.assertEqual(get_plugin_config(plugin, 'bar'), None)
         self.assertEqual(get_plugin_config(plugin, 'bar', default=456), 456)
+
+
+    def test_events_pipeline(self):
+        """
+        Check that events pipeline is registered.
+        """
+        self.assertIn('netbox.tests.dummy_plugin.events.process_events_queue', settings.EVENTS_PIPELINE)