Closes #18540: Track installed plugins in registry

This commit is contained in:
Jeremy Stretch 2025-02-03 13:10:40 -05:00
parent 5d1070796d
commit 43841939a0
7 changed files with 21 additions and 8 deletions

View File

@ -9,6 +9,7 @@ from django.conf import settings
from django.core.cache import cache from django.core.cache import cache
from netbox.plugins import PluginConfig from netbox.plugins import PluginConfig
from netbox.registry import registry
from utilities.datetime import datetime_from_timestamp from utilities.datetime import datetime_from_timestamp
USER_AGENT_STRING = f'NetBox/{settings.RELEASE.version} {settings.RELEASE.edition}' USER_AGENT_STRING = f'NetBox/{settings.RELEASE.version} {settings.RELEASE.edition}'
@ -76,7 +77,7 @@ def get_local_plugins(plugins=None):
local_plugins = {} local_plugins = {}
# Gather all locally-installed plugins # Gather all locally-installed plugins
for plugin_name in settings.PLUGINS: for plugin_name in registry['plugins']['installed']:
plugin = importlib.import_module(plugin_name) plugin = importlib.import_module(plugin_name)
plugin_config: PluginConfig = plugin.config plugin_config: PluginConfig = plugin.config

View File

@ -22,6 +22,7 @@ from rq.worker_registration import clean_worker_registry
from core.utils import delete_rq_job, enqueue_rq_job, get_rq_jobs_from_status, requeue_rq_job, stop_rq_job from core.utils import delete_rq_job, enqueue_rq_job, get_rq_jobs_from_status, requeue_rq_job, stop_rq_job
from netbox.config import get_config, PARAMS from netbox.config import get_config, PARAMS
from netbox.registry import registry
from netbox.views import generic from netbox.views import generic
from netbox.views.generic.base import BaseObjectView from netbox.views.generic.base import BaseObjectView
from netbox.views.generic.mixins import TableMixin from netbox.views.generic.mixins import TableMixin
@ -560,7 +561,7 @@ class SystemView(UserPassesTestMixin, View):
params = [param.name for param in PARAMS] params = [param.name for param in PARAMS]
data = { data = {
**stats, **stats,
'plugins': settings.PLUGINS, 'plugins': registry['plugins']['installed'],
'config': { 'config': {
k: getattr(config, k) for k in sorted(params) k: getattr(config, k) for k in sorted(params)
}, },

View File

@ -16,6 +16,7 @@ from .utils import *
# Initialize plugin registry # Initialize plugin registry
registry['plugins'].update({ registry['plugins'].update({
'installed': [],
'graphql_schemas': [], 'graphql_schemas': [],
'menus': [], 'menus': [],
'menu_items': {}, 'menu_items': {},

View File

@ -1,11 +1,11 @@
from importlib import import_module from importlib import import_module
from django.apps import apps from django.apps import apps
from django.conf import settings
from django.conf.urls import include from django.conf.urls import include
from django.urls import path from django.urls import path
from django.utils.module_loading import import_string, module_has_submodule from django.utils.module_loading import import_string, module_has_submodule
from netbox.registry import registry
from . import views from . import views
plugin_patterns = [] plugin_patterns = []
@ -15,7 +15,7 @@ plugin_api_patterns = [
] ]
# Register base/API URL patterns for each plugin # Register base/API URL patterns for each plugin
for plugin_path in settings.PLUGINS: for plugin_path in registry['plugins']['installed']:
plugin = import_module(plugin_path) plugin = import_module(plugin_path)
plugin_name = plugin_path.split('.')[-1] plugin_name = plugin_path.split('.')[-1]
app = apps.get_app_config(plugin_name) app = apps.get_app_config(plugin_name)

View File

@ -2,6 +2,8 @@ from django.apps import apps
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from netbox.registry import registry
__all__ = ( __all__ = (
'get_installed_plugins', 'get_installed_plugins',
'get_plugin_config', 'get_plugin_config',
@ -13,7 +15,7 @@ def get_installed_plugins():
Return a dictionary mapping the names of installed plugins to their versions. Return a dictionary mapping the names of installed plugins to their versions.
""" """
plugins = {} plugins = {}
for plugin_name in settings.PLUGINS: for plugin_name in registry['plugins']['installed']:
plugin_name = plugin_name.rsplit('.', 1)[-1] plugin_name = plugin_name.rsplit('.', 1)[-1]
plugin_config = apps.get_app_config(plugin_name) plugin_config = apps.get_app_config(plugin_name)
plugins[plugin_name] = getattr(plugin_config, 'version', None) plugins[plugin_name] = getattr(plugin_config, 'version', None)

View File

@ -1,7 +1,6 @@
from collections import OrderedDict from collections import OrderedDict
from django.apps import apps from django.apps import apps
from django.conf import settings
from django.urls.exceptions import NoReverseMatch from django.urls.exceptions import NoReverseMatch
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import extend_schema
from rest_framework import permissions from rest_framework import permissions
@ -9,6 +8,8 @@ from rest_framework.response import Response
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
from rest_framework.views import APIView from rest_framework.views import APIView
from netbox.registry import registry
@extend_schema(exclude=True) @extend_schema(exclude=True)
class InstalledPluginsAPIView(APIView): class InstalledPluginsAPIView(APIView):
@ -34,7 +35,10 @@ class InstalledPluginsAPIView(APIView):
} }
def get(self, request, format=None): def get(self, request, format=None):
return Response([self._get_plugin_data(apps.get_app_config(plugin)) for plugin in settings.PLUGINS]) return Response([
self._get_plugin_data(apps.get_app_config(plugin))
for plugin in registry['plugins']['installed']
])
@extend_schema(exclude=True) @extend_schema(exclude=True)
@ -64,7 +68,7 @@ class PluginsAPIRootView(APIView):
def get(self, request, format=None): def get(self, request, format=None):
entries = [] entries = []
for plugin in settings.PLUGINS: for plugin in registry['plugins']['installed']:
app_config = apps.get_app_config(plugin) app_config = apps.get_app_config(plugin)
entry = self._get_plugin_entry(plugin, app_config, request, format) entry = self._get_plugin_entry(plugin, app_config, request, format)
if entry is not None: if entry is not None:

View File

@ -16,6 +16,7 @@ from django.utils.translation import gettext_lazy as _
from netbox.config import PARAMS as CONFIG_PARAMS from netbox.config import PARAMS as CONFIG_PARAMS
from netbox.constants import RQ_QUEUE_DEFAULT, RQ_QUEUE_HIGH, RQ_QUEUE_LOW from netbox.constants import RQ_QUEUE_DEFAULT, RQ_QUEUE_HIGH, RQ_QUEUE_LOW
from netbox.plugins import PluginConfig from netbox.plugins import PluginConfig
from netbox.registry import registry
from utilities.release import load_release_data from utilities.release import load_release_data
from utilities.string import trailing_slash from utilities.string import trailing_slash
@ -813,6 +814,9 @@ for plugin_name in PLUGINS:
f"__init__.py file and point to the PluginConfig subclass." f"__init__.py file and point to the PluginConfig subclass."
) )
# Register the plugin as installed successfully
registry['plugins']['installed'].append(plugin_name)
plugin_module = "{}.{}".format(plugin_config.__module__, plugin_config.__name__) # type: ignore plugin_module = "{}.{}".format(plugin_config.__module__, plugin_config.__name__) # type: ignore
# Gather additional apps to load alongside this plugin # Gather additional apps to load alongside this plugin