diff --git a/netbox/extras/plugins/__init__.py b/netbox/extras/plugins/__init__.py index 83c7a7bb0e2..8736a319794 100644 --- a/netbox/extras/plugins/__init__.py +++ b/netbox/extras/plugins/__init__.py @@ -2,7 +2,6 @@ from importlib import import_module from django.apps import AppConfig -from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils.module_loading import import_string from packaging import version @@ -146,23 +145,3 @@ def validate(cls, user_config, netbox_version): for setting, value in cls.default_settings.items(): if setting not in user_config: user_config[setting] = value - - -# -# Utilities -# - -def get_plugin_config(plugin_name, parameter, default=None): - """ - Return the value of the specified plugin configuration parameter. - - Args: - plugin_name: The name of the plugin - parameter: The name of the configuration parameter - default: The value to return if the parameter is not defined (default: None) - """ - try: - plugin_config = settings.PLUGINS_CONFIG[plugin_name] - return plugin_config.get(parameter, default) - except KeyError: - raise ImproperlyConfigured(f"Plugin {plugin_name} is not registered.") diff --git a/netbox/extras/plugins/utils.py b/netbox/extras/plugins/utils.py new file mode 100644 index 00000000000..c260f156db6 --- /dev/null +++ b/netbox/extras/plugins/utils.py @@ -0,0 +1,37 @@ +from django.apps import apps +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured + +__all__ = ( + 'get_installed_plugins', + 'get_plugin_config', +) + + +def get_installed_plugins(): + """ + Return a dictionary mapping the names of installed plugins to their versions. + """ + plugins = {} + for plugin_name in settings.PLUGINS: + plugin_name = plugin_name.rsplit('.', 1)[-1] + plugin_config = apps.get_app_config(plugin_name) + plugins[plugin_name] = getattr(plugin_config, 'version', None) + + return dict(sorted(plugins.items())) + + +def get_plugin_config(plugin_name, parameter, default=None): + """ + Return the value of the specified plugin configuration parameter. + + Args: + plugin_name: The name of the plugin + parameter: The name of the configuration parameter + default: The value to return if the parameter is not defined (default: None) + """ + try: + plugin_config = settings.PLUGINS_CONFIG[plugin_name] + return plugin_config.get(parameter, default) + except KeyError: + raise ImproperlyConfigured(f"Plugin {plugin_name} is not registered.") diff --git a/netbox/extras/tests/test_plugins.py b/netbox/extras/tests/test_plugins.py index cb7629ad24e..42dde43fdff 100644 --- a/netbox/extras/tests/test_plugins.py +++ b/netbox/extras/tests/test_plugins.py @@ -5,8 +5,9 @@ from django.test import Client, TestCase, override_settings from django.urls import reverse -from extras.plugins import PluginMenu, get_plugin_config +from extras.plugins import PluginMenu from extras.tests.dummy_plugin import config as dummy_config +from extras.plugins.utils import get_plugin_config from netbox.graphql.schema import Query from netbox.registry import registry diff --git a/netbox/netbox/api/views.py b/netbox/netbox/api/views.py index 5c55697ff6c..97f690762b7 100644 --- a/netbox/netbox/api/views.py +++ b/netbox/netbox/api/views.py @@ -11,6 +11,7 @@ from rest_framework.views import APIView from rq.worker import Worker +from extras.plugins.utils import get_installed_plugins from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired @@ -61,19 +62,11 @@ def get(self, request): installed_apps[app_config.name] = version installed_apps = {k: v for k, v in sorted(installed_apps.items())} - # Gather installed plugins - plugins = {} - for plugin_name in settings.PLUGINS: - plugin_name = plugin_name.rsplit('.', 1)[-1] - plugin_config = apps.get_app_config(plugin_name) - plugins[plugin_name] = getattr(plugin_config, 'version', None) - plugins = {k: v for k, v in sorted(plugins.items())} - return Response({ 'django-version': DJANGO_VERSION, 'installed-apps': installed_apps, 'netbox-version': settings.VERSION, - 'plugins': plugins, + 'plugins': get_installed_plugins(), 'python-version': platform.python_version(), 'rq-workers-running': Worker.count(get_connection('default')), }) diff --git a/netbox/netbox/views/errors.py b/netbox/netbox/views/errors.py index c74c67cef06..a81d45cb5cb 100644 --- a/netbox/netbox/views/errors.py +++ b/netbox/netbox/views/errors.py @@ -11,6 +11,8 @@ from django.views.generic import View from sentry_sdk import capture_message +from extras.plugins.utils import get_installed_plugins + __all__ = ( 'handler_404', 'handler_500', @@ -53,4 +55,5 @@ def handler_500(request, template_name=ERROR_500_TEMPLATE_NAME): 'exception': str(type_), 'netbox_version': settings.VERSION, 'python_version': platform.python_version(), + 'plugins': get_installed_plugins(), })) diff --git a/netbox/templates/500.html b/netbox/templates/500.html index 6cface941cd..0257e7c4370 100644 --- a/netbox/templates/500.html +++ b/netbox/templates/500.html @@ -30,7 +30,10 @@
{{ error }} Python version: {{ python_version }} -NetBox version: {{ netbox_version }} +NetBox version: {{ netbox_version }} +Plugins: {% for plugin, version in plugins.items %} + {{ plugin }}: {{ version }}{% empty %}None installed{% endfor %} +

If further assistance is required, please post to the NetBox discussion forum on GitHub.