diff --git a/CHANGES/5235.feature b/CHANGES/5235.feature new file mode 100644 index 0000000000..ca6e2f966f --- /dev/null +++ b/CHANGES/5235.feature @@ -0,0 +1 @@ +Added ``ENABLED_PLUGINS`` option to allow selecting installed plugins to be enabled. diff --git a/pulpcore/app/settings.py b/pulpcore/app/settings.py index d4220a2d36..2ce97d8007 100644 --- a/pulpcore/app/settings.py +++ b/pulpcore/app/settings.py @@ -12,9 +12,9 @@ from contextlib import suppress from importlib import import_module +from importlib.metadata import entry_points from logging import getLogger from pathlib import Path -from pkg_resources import iter_entry_points from cryptography.fernet import Fernet from django.core.exceptions import ImproperlyConfigured @@ -81,14 +81,6 @@ "pulpcore.app", ] -# Enumerate the installed Pulp plugins during the loading process for use in the status API -INSTALLED_PULP_PLUGINS = [] - -for entry_point in iter_entry_points("pulpcore.plugin"): - plugin_app_config = entry_point.load() - INSTALLED_PULP_PLUGINS.append(entry_point.module_name) - INSTALLED_APPS.append(plugin_app_config) - # Optional apps that help with development, or augment Pulp in some non-critical way OPTIONAL_APPS = [ "crispy_forms", @@ -317,9 +309,17 @@ # HERE STARTS DYNACONF EXTENSION LOAD (Keep at the very bottom of settings.py) # Read more at https://dynaconf.readthedocs.io/en/latest/guides/django.html -from dynaconf import DjangoDynaconf, Validator # noqa +from dynaconf import DjangoDynaconf, Dynaconf, Validator # noqa # Validators + +enabled_plugins_validator = Validator( + "ENABLED_PLUGINS", + is_type_of=list, + len_min=1, + when=Validator("ENABLED_PLUGINS", must_exist=True), +) + content_origin_validator = Validator( "CONTENT_ORIGIN", must_exist=True, @@ -407,19 +407,43 @@ authentication_json_header_validator & authentication_json_header_jq_filter_validator ) + +def load_plugin_config_hook(settings): + # Enumerate the installed Pulp plugins during the loading process for use in the status API + ENABLED_PLUGINS = getattr(settings, "ENABLED_PLUGINS", None) + installed_plugins = [] + installed_plugin_apps = [] + + for entry_point in entry_points().get("pulpcore.plugin", []): + if ENABLED_PLUGINS is not None and entry_point.name not in ENABLED_PLUGINS: + continue + installed_plugins.append(entry_point.module) + installed_plugin_apps.append(entry_point.load()) + + plugin_settings = Dynaconf( + PRELOAD_FOR_DYNACONF=[f"{module}.app.settings" for module in installed_plugins] + ) + + data = {"dynaconf_merge": True} + data.update(plugin_settings.as_dict()) + data.update(settings.as_dict()) + data["INSTALLED_APPS"].extend(installed_plugin_apps) + data["INSTALLED_APPS"].append("dynaconf_merge_unique") + return data + + settings = DjangoDynaconf( __name__, ENVVAR_PREFIX_FOR_DYNACONF="PULP", ENV_SWITCHER_FOR_DYNACONF="PULP_ENV", - PRELOAD_FOR_DYNACONF=[ - "{}.app.settings".format(plugin_name) for plugin_name in INSTALLED_PULP_PLUGINS - ], ENVVAR_FOR_DYNACONF="PULP_SETTINGS", + post_hooks=(load_plugin_config_hook,), load_dotenv=False, validators=[ api_root_validator, cache_validator, content_origin_validator, + enabled_plugins_validator, sha256_validator, storage_validator, unknown_algs_validator, diff --git a/pulpcore/tests/functional/__init__.py b/pulpcore/tests/functional/__init__.py index 0f2960e9aa..9a7f9b9fe5 100644 --- a/pulpcore/tests/functional/__init__.py +++ b/pulpcore/tests/functional/__init__.py @@ -1071,11 +1071,7 @@ def _monitor_task_group(task_group_href, timeout=TASK_TIMEOUT): @pytest.fixture(scope="session") def pulp_settings(): - import django - - django.setup() - - from django.conf import settings + from pulpcore.app import settings return settings diff --git a/requirements.txt b/requirements.txt index 811a0e9e3f..b095aa14fc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ djangorestframework-queryfields>=1.0,<=1.1.0 drf-access-policy>=1.1.2,<1.5.1 drf-nested-routers>=0.93.4,<=0.93.5 drf-spectacular==0.26.5 # We monkeypatch this so we need a very narrow requirement string -dynaconf>=3.1.12,<3.2.6 +dynaconf>=3.2.5,<3.2.6 gunicorn>=20.1,<=21.2.0 importlib-metadata>=6.0.1,<=6.0.1 # Pinned to fix opentelemetry dependency solving issues with pip jinja2>=3.1,<=3.1.3 diff --git a/staging_docs/admin/learn/settings.md b/staging_docs/admin/learn/settings.md index 84efeae6eb..8562593672 100644 --- a/staging_docs/admin/learn/settings.md +++ b/staging_docs/admin/learn/settings.md @@ -157,6 +157,11 @@ The password for Redis. Pulp defines the following settings itself: +### ENABLED_PLUGINS + +An optional list of plugin names. +If provided, Pulp will limit loading plugins to this list. +If omitted, Pulp will load all installed plugins. ### API_ROOT