From e2e2df57f98935bbf1bc2f1561527fa16934b983 Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Wed, 11 Dec 2024 20:28:07 +0000 Subject: [PATCH] feat: Manage Django Settings with Dynaconf --- awx/__init__.py | 3 +- awx/api/generics.py | 1 + awx/api/views/root.py | 1 + awx/main/tests/settings_for_test.py | 2 + awx/settings/__init__.py | 40 ++++++ awx/settings/defaults.py | 3 +- awx/settings/development.py | 129 ++---------------- awx/settings/development_defaults.py | 129 ++++++++++++++++++ .../{development_kube.py => kube_defaults.py} | 0 awx/settings/production.py | 114 ++-------------- awx/settings/production_defaults.py | 106 ++++++++++++++ ...development_quiet.py => quiet_defaults.py} | 7 - awx/urls.py | 15 +- requirements/requirements.in | 1 + requirements/requirements.txt | 2 + 15 files changed, 310 insertions(+), 243 deletions(-) create mode 100644 awx/settings/development_defaults.py rename awx/settings/{development_kube.py => kube_defaults.py} (100%) create mode 100644 awx/settings/production_defaults.py rename awx/settings/{development_quiet.py => quiet_defaults.py} (61%) diff --git a/awx/__init__.py b/awx/__init__.py index be80b5861499..b1f7e61d616b 100644 --- a/awx/__init__.py +++ b/awx/__init__.py @@ -81,7 +81,8 @@ def oauth2_getattribute(self, attr): def prepare_env(): # Update the default settings environment variable based on current mode. - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'awx.settings.%s' % MODE) + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'awx.settings') + os.environ.setdefault('AWX_MODE', MODE) # Hide DeprecationWarnings when running in production. Need to first load # settings to apply our filter after Django's own warnings filter. from django.conf import settings diff --git a/awx/api/generics.py b/awx/api/generics.py index 9c400d0b388e..6702ff816a41 100644 --- a/awx/api/generics.py +++ b/awx/api/generics.py @@ -161,6 +161,7 @@ def get_view_description(view, html=False): def get_default_schema(): + # TODO: get current_env if settings.SETTINGS_MODULE == 'awx.settings.development': from awx.api.swagger import AutoSchema diff --git a/awx/api/views/root.py b/awx/api/views/root.py index d0f3a88e4c21..4fdd4f86453f 100644 --- a/awx/api/views/root.py +++ b/awx/api/views/root.py @@ -82,6 +82,7 @@ class ApiVersionRootView(APIView): def get(self, request, format=None): '''List top level resources''' data = OrderedDict() + data["foo"] = settings.FOO data['ping'] = reverse('api:api_v2_ping_view', request=request) data['instances'] = reverse('api:instance_list', request=request) data['instance_groups'] = reverse('api:instance_group_list', request=request) diff --git a/awx/main/tests/settings_for_test.py b/awx/main/tests/settings_for_test.py index 5634494c3373..e025d982aa06 100644 --- a/awx/main/tests/settings_for_test.py +++ b/awx/main/tests/settings_for_test.py @@ -1,6 +1,8 @@ # Python import uuid +# TODO: move to settings test + # Load development settings for base variables. from awx.settings.development import * # NOQA diff --git a/awx/settings/__init__.py b/awx/settings/__init__.py index e484e62be15d..358c49d819a6 100644 --- a/awx/settings/__init__.py +++ b/awx/settings/__init__.py @@ -1,2 +1,42 @@ # Copyright (c) 2015 Ansible, Inc. # All Rights Reserved. +from ansible_base.lib.dynamic_config import factory, export +from .application_name import get_application_name +from dynaconf import Validator + + +def set_application_name(settings): + data = {"dynaconf_merge": True} + if settings.get("DATABASES") and settings.DATABASES.get("default"): + if "sqlite3" not in settings.DATABASES.default.ENGINE: + data["DATABASES__default__OPTIONS__application_name"] = get_application_name(settings.CLUSTER_HOST_ID) + return data + + +DYNACONF = factory( + "AWX", + environments=("development", "production", "quiet", "kube"), + settings_files=["defaults.py"], +) +DYNACONF.validators.register(Validator("FOO", required=True)) + +# Store snapshot before loading any custom config file +if DYNACONF.current_env == "development": + DYNACONF.set("DEFAULTS_SNAPSHOT", DYNACONF.as_dict(internal=False)) + +# Load extra config +DYNACONF.load_file("/etc/tower/settings.py") +DYNACONF.load_file("/etc/tower/conf.d/*.py") +if DYNACONF.get_environ("AWX_KUBE_DEVEL"): + DYNACONF.load_file("kube_defaults.py") +else: + DYNACONF.load_file("local_*.py") + +# This must run after all custom settings are imported +DYNACONF.update(set_application_name(DYNACONF)) + +# Update django.conf.settings with DYNACONF keys. +export(DYNACONF) + +# Validate the settings according to the validators registered +DYNACONF.validators.validate() diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 1edcc11edbbb..5161125a4746 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -11,7 +11,7 @@ from split_settings.tools import include - +FOO = 0 DEBUG = True SQL_DEBUG = DEBUG @@ -1017,6 +1017,7 @@ ANSIBLE_BASE_RESOURCE_CONFIG_MODULE = 'awx.resource_api' ANSIBLE_BASE_PERMISSION_MODEL = 'main.Permission' +# TODO: Move this to the settings object from DAB from ansible_base.lib import dynamic_config # noqa: E402 include(os.path.join(os.path.dirname(dynamic_config.__file__), 'dynamic_settings.py')) diff --git a/awx/settings/development.py b/awx/settings/development.py index 68fa75ceb8c2..36e34ce1319d 100644 --- a/awx/settings/development.py +++ b/awx/settings/development.py @@ -1,121 +1,8 @@ -# Copyright (c) 2015 Ansible, Inc. -# All Rights Reserved. - -# Development settings for AWX project. - -# Python -import os -import socket -import copy -import sys -import traceback - -# Centos-7 doesn't include the svg mime type -# /usr/lib64/python/mimetypes.py -import mimetypes - -# Django Split Settings -from split_settings.tools import optional, include - -# Load default settings. -from .defaults import * # NOQA - -# awx-manage shell_plus --notebook -NOTEBOOK_ARGUMENTS = ['--NotebookApp.token=', '--ip', '0.0.0.0', '--port', '9888', '--allow-root', '--no-browser'] - -# print SQL queries in shell_plus -SHELL_PLUS_PRINT_SQL = False - -# show colored logs in the dev environment -# to disable this, set `COLOR_LOGS = False` in awx/settings/local_settings.py -COLOR_LOGS = True -LOGGING['handlers']['console']['()'] = 'awx.main.utils.handlers.ColorHandler' # noqa - -ALLOWED_HOSTS = ['*'] - -mimetypes.add_type("image/svg+xml", ".svg", True) -mimetypes.add_type("image/svg+xml", ".svgz", True) - -# Disallow sending session cookies over insecure connections -SESSION_COOKIE_SECURE = False - -# Disallow sending csrf cookies over insecure connections -CSRF_COOKIE_SECURE = False - -# Disable Pendo on the UI for development/test. -# Note: This setting may be overridden by database settings. -PENDO_TRACKING_STATE = "off" -INSIGHTS_TRACKING_STATE = False - -# debug toolbar and swagger assume that requirements/requirements_dev.txt are installed - -INSTALLED_APPS += ['drf_yasg', 'debug_toolbar'] # NOQA - -MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware'] + MIDDLEWARE # NOQA - -DEBUG_TOOLBAR_CONFIG = {'ENABLE_STACKTRACES': True} - -# Configure a default UUID for development only. -SYSTEM_UUID = '00000000-0000-0000-0000-000000000000' -INSTALL_UUID = '00000000-0000-0000-0000-000000000000' - -# Ansible base virtualenv paths and enablement -# only used for deprecated fields and management commands for them -BASE_VENV_PATH = os.path.realpath("/var/lib/awx/venv") - -CLUSTER_HOST_ID = socket.gethostname() - -AWX_CALLBACK_PROFILE = True - -# ======================!!!!!!! FOR DEVELOPMENT ONLY !!!!!!!================================= -# Disable normal scheduled/triggered task managers (DependencyManager, TaskManager, WorkflowManager). -# Allows user to trigger task managers directly for debugging and profiling purposes. -# Only works in combination with settings.SETTINGS_MODULE == 'awx.settings.development' -AWX_DISABLE_TASK_MANAGERS = False - -# Needed for launching runserver in debug mode -# ======================!!!!!!! FOR DEVELOPMENT ONLY !!!!!!!================================= - -# Store a snapshot of default settings at this point before loading any -# customizable config files. -this_module = sys.modules[__name__] -local_vars = dir(this_module) -DEFAULTS_SNAPSHOT = {} # define after we save local_vars so we do not snapshot the snapshot -for setting in local_vars: - if setting.isupper(): - DEFAULTS_SNAPSHOT[setting] = copy.deepcopy(getattr(this_module, setting)) - -del local_vars # avoid temporary variables from showing up in dir(settings) -del this_module -# -############################################################################################### -# -# Any settings defined after this point will be marked as as a read_only database setting -# -################################################################################################ - -# If there is an `/etc/tower/settings.py`, include it. -# If there is a `/etc/tower/conf.d/*.py`, include them. -include(optional('/etc/tower/settings.py'), scope=locals()) -include(optional('/etc/tower/conf.d/*.py'), scope=locals()) - -# If any local_*.py files are present in awx/settings/, use them to override -# default settings for development. If not present, we can still run using -# only the defaults. -# this needs to stay at the bottom of this file -try: - if os.getenv('AWX_KUBE_DEVEL', False): - include(optional('development_kube.py'), scope=locals()) - else: - include(optional('local_*.py'), scope=locals()) -except ImportError: - traceback.print_exc() - sys.exit(1) - -# The below runs AFTER all of the custom settings are imported -# because conf.d files will define DATABASES and this should modify that -from .application_name import set_application_name - -set_application_name(DATABASES, CLUSTER_HOST_ID) # NOQA - -del set_application_name +# This file exists for backwards compatibility only +# the current way of running AWX is to point settings to +# awx/settings/__init__.py as the entry point for the settings +# that is done by exporting: export DJANGO_SETTINGS_MODULE=awx.settings +from ansible_base.lib.dynamic_config import export +from . import DYNACONF # noqa + +export(DYNACONF) diff --git a/awx/settings/development_defaults.py b/awx/settings/development_defaults.py new file mode 100644 index 000000000000..f887d4055327 --- /dev/null +++ b/awx/settings/development_defaults.py @@ -0,0 +1,129 @@ +# Copyright (c) 2015 Ansible, Inc. +# All Rights Reserved. + +# Development settings for AWX project. + +# Python +import os +import socket +import copy +import sys +import traceback + +# Centos-7 doesn't include the svg mime type +# /usr/lib64/python/mimetypes.py +import mimetypes + +# Django Split Settings +# from split_settings.tools import optional, include + +# Load default settings. +# from .defaults import * # NOQA +# from awx.settings.main import settings + + +# awx-manage shell_plus --notebook +NOTEBOOK_ARGUMENTS = ['--NotebookApp.token=', '--ip', '0.0.0.0', '--port', '9888', '--allow-root', '--no-browser'] + +# print SQL queries in shell_plus +SHELL_PLUS_PRINT_SQL = False + +# show colored logs in the dev environment +# to disable this, set `COLOR_LOGS = False` in awx/settings/local_settings.py +COLOR_LOGS = True +# LOGGING['handlers']['console']['()'] = 'awx.main.utils.handlers.ColorHandler' # noqa + +ALLOWED_HOSTS = ['*'] + +mimetypes.add_type("image/svg+xml", ".svg", True) +mimetypes.add_type("image/svg+xml", ".svgz", True) + +# Disallow sending session cookies over insecure connections +SESSION_COOKIE_SECURE = False + +# Disallow sending csrf cookies over insecure connections +CSRF_COOKIE_SECURE = False + +# Disable Pendo on the UI for development/test. +# Note: This setting may be overridden by database settings. +PENDO_TRACKING_STATE = "off" +INSIGHTS_TRACKING_STATE = False + +# debug toolbar and swagger assume that requirements/requirements_dev.txt are installed + +# INSTALLED_APPS = settings.INSTALLED_APPS + ['drf_yasg', 'debug_toolbar'] # NOQA +INSTALLED_APPS = "@merge drf_yasg,debug_toolbar" + +# settings.MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware'] + settings.MIDDLEWARE # NOQA +# settings.MIDDLEWARE.insert(0, 'debug_toolbar.middleware.DebugToolbarMiddleware') +# MIDDLEWARE = "@insert debug_toolbar.middleware.DebugToolbarMiddleware" + +DEBUG_TOOLBAR_CONFIG = {'ENABLE_STACKTRACES': True} + +# Configure a default UUID for development only. +SYSTEM_UUID = '00000000-0000-0000-0000-000000000000' +INSTALL_UUID = '00000000-0000-0000-0000-000000000000' + +# Ansible base virtualenv paths and enablement +# only used for deprecated fields and management commands for them +BASE_VENV_PATH = os.path.realpath("/var/lib/awx/venv") + +CLUSTER_HOST_ID = socket.gethostname() + +AWX_CALLBACK_PROFILE = True + +# ======================!!!!!!! FOR DEVELOPMENT ONLY !!!!!!!================================= +# Disable normal scheduled/triggered task managers (DependencyManager, TaskManager, WorkflowManager). +# Allows user to trigger task managers directly for debugging and profiling purposes. +# Only works in combination with settings.SETTINGS_MODULE == 'awx.settings.development' +AWX_DISABLE_TASK_MANAGERS = False + +# Needed for launching runserver in debug mode +# ======================!!!!!!! FOR DEVELOPMENT ONLY !!!!!!!================================= + +# Store a snapshot of default settings at this point before loading any +# customizable config files. +# this_module = sys.modules[__name__] +# local_vars = dir(this_module) +# DEFAULTS_SNAPSHOT = {} # define after we save local_vars so we do not snapshot the snapshot +# for setting in local_vars: +# if setting.isupper(): +# DEFAULTS_SNAPSHOT[setting] = copy.deepcopy(getattr(this_module, setting)) + +# del local_vars # avoid temporary variables from showing up in dir(settings) +# del this_module +# +############################################################################################### +# +# Any settings defined after this point will be marked as as a read_only database setting +# +################################################################################################ + +# If there is an `/etc/tower/settings.py`, include it. +# If there is a `/etc/tower/conf.d/*.py`, include them. +# include(optional('/etc/tower/settings.py'), scope=locals()) +# include(optional('/etc/tower/conf.d/*.py'), scope=locals()) + +# If any local_*.py files are present in awx/settings/, use them to override +# default settings for development. If not present, we can still run using +# only the defaults. +# this needs to stay at the bottom of this file +# try: +# if os.getenv('AWX_KUBE_DEVEL', False): +# include(optional('development_kube.py'), scope=locals()) +# else: +# include(optional('local_*.py'), scope=locals()) +# except ImportError: +# traceback.print_exc() +# sys.exit(1) + + +# The below runs AFTER all of the custom settings are imported +# because conf.d files will define DATABASES and this should modify that +# from .application_name import set_application_name + +# set_application_name(settings.DATABASES, CLUSTER_HOST_ID) # NOQA + +# del set_application_name + +# settings.populate_obj(sys.modules[__name__]) diff --git a/awx/settings/development_kube.py b/awx/settings/kube_defaults.py similarity index 100% rename from awx/settings/development_kube.py rename to awx/settings/kube_defaults.py diff --git a/awx/settings/production.py b/awx/settings/production.py index fa74bc7fb78e..36e34ce1319d 100644 --- a/awx/settings/production.py +++ b/awx/settings/production.py @@ -1,106 +1,8 @@ -# Copyright (c) 2015 Ansible, Inc. -# All Rights Reserved. - -# Production settings for AWX project. - -# Python -import os -import copy -import errno -import sys -import traceback - -# Django Split Settings -from split_settings.tools import optional, include - -# Load default settings. -from .defaults import * # NOQA - -DEBUG = False -TEMPLATE_DEBUG = DEBUG -SQL_DEBUG = DEBUG - -# Clear database settings to force production environment to define them. -DATABASES = {} - -# Clear the secret key to force production environment to define it. -SECRET_KEY = None - -# Hosts/domain names that are valid for this site; required if DEBUG is False -# See https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = [] - -# Ansible base virtualenv paths and enablement -# only used for deprecated fields and management commands for them -BASE_VENV_PATH = os.path.realpath("/var/lib/awx/venv") - -# Very important that this is editable (not read_only) in the API -AWX_ISOLATION_SHOW_PATHS = [ - '/etc/pki/ca-trust:/etc/pki/ca-trust:O', - '/usr/share/pki:/usr/share/pki:O', -] - -# Store a snapshot of default settings at this point before loading any -# customizable config files. -this_module = sys.modules[__name__] -local_vars = dir(this_module) -DEFAULTS_SNAPSHOT = {} # define after we save local_vars so we do not snapshot the snapshot -for setting in local_vars: - if setting.isupper(): - DEFAULTS_SNAPSHOT[setting] = copy.deepcopy(getattr(this_module, setting)) - -del local_vars # avoid temporary variables from showing up in dir(settings) -del this_module -# -############################################################################################### -# -# Any settings defined after this point will be marked as as a read_only database setting -# -################################################################################################ - -# Load settings from any .py files in the global conf.d directory specified in -# the environment, defaulting to /etc/tower/conf.d/. -settings_dir = os.environ.get('AWX_SETTINGS_DIR', '/etc/tower/conf.d/') -settings_files = os.path.join(settings_dir, '*.py') - -# Load remaining settings from the global settings file specified in the -# environment, defaulting to /etc/tower/settings.py. -settings_file = os.environ.get('AWX_SETTINGS_FILE', '/etc/tower/settings.py') - -# Attempt to load settings from /etc/tower/settings.py first, followed by -# /etc/tower/conf.d/*.py. -try: - include(settings_file, optional(settings_files), scope=locals()) -except ImportError: - traceback.print_exc() - sys.exit(1) -except IOError: - from django.core.exceptions import ImproperlyConfigured - - included_file = locals().get('__included_file__', '') - if not included_file or included_file == settings_file: - # The import doesn't always give permission denied, so try to open the - # settings file directly. - try: - e = None - open(settings_file) - except IOError: - pass - if e and e.errno == errno.EACCES: - SECRET_KEY = 'permission-denied' - LOGGING = {} - else: - msg = 'No AWX configuration found at %s.' % settings_file - msg += '\nDefine the AWX_SETTINGS_FILE environment variable to ' - msg += 'specify an alternate path.' - raise ImproperlyConfigured(msg) - else: - raise - -# The below runs AFTER all of the custom settings are imported -# because conf.d files will define DATABASES and this should modify that -from .application_name import set_application_name - -set_application_name(DATABASES, CLUSTER_HOST_ID) # NOQA - -del set_application_name +# This file exists for backwards compatibility only +# the current way of running AWX is to point settings to +# awx/settings/__init__.py as the entry point for the settings +# that is done by exporting: export DJANGO_SETTINGS_MODULE=awx.settings +from ansible_base.lib.dynamic_config import export +from . import DYNACONF # noqa + +export(DYNACONF) diff --git a/awx/settings/production_defaults.py b/awx/settings/production_defaults.py new file mode 100644 index 000000000000..fa74bc7fb78e --- /dev/null +++ b/awx/settings/production_defaults.py @@ -0,0 +1,106 @@ +# Copyright (c) 2015 Ansible, Inc. +# All Rights Reserved. + +# Production settings for AWX project. + +# Python +import os +import copy +import errno +import sys +import traceback + +# Django Split Settings +from split_settings.tools import optional, include + +# Load default settings. +from .defaults import * # NOQA + +DEBUG = False +TEMPLATE_DEBUG = DEBUG +SQL_DEBUG = DEBUG + +# Clear database settings to force production environment to define them. +DATABASES = {} + +# Clear the secret key to force production environment to define it. +SECRET_KEY = None + +# Hosts/domain names that are valid for this site; required if DEBUG is False +# See https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts +ALLOWED_HOSTS = [] + +# Ansible base virtualenv paths and enablement +# only used for deprecated fields and management commands for them +BASE_VENV_PATH = os.path.realpath("/var/lib/awx/venv") + +# Very important that this is editable (not read_only) in the API +AWX_ISOLATION_SHOW_PATHS = [ + '/etc/pki/ca-trust:/etc/pki/ca-trust:O', + '/usr/share/pki:/usr/share/pki:O', +] + +# Store a snapshot of default settings at this point before loading any +# customizable config files. +this_module = sys.modules[__name__] +local_vars = dir(this_module) +DEFAULTS_SNAPSHOT = {} # define after we save local_vars so we do not snapshot the snapshot +for setting in local_vars: + if setting.isupper(): + DEFAULTS_SNAPSHOT[setting] = copy.deepcopy(getattr(this_module, setting)) + +del local_vars # avoid temporary variables from showing up in dir(settings) +del this_module +# +############################################################################################### +# +# Any settings defined after this point will be marked as as a read_only database setting +# +################################################################################################ + +# Load settings from any .py files in the global conf.d directory specified in +# the environment, defaulting to /etc/tower/conf.d/. +settings_dir = os.environ.get('AWX_SETTINGS_DIR', '/etc/tower/conf.d/') +settings_files = os.path.join(settings_dir, '*.py') + +# Load remaining settings from the global settings file specified in the +# environment, defaulting to /etc/tower/settings.py. +settings_file = os.environ.get('AWX_SETTINGS_FILE', '/etc/tower/settings.py') + +# Attempt to load settings from /etc/tower/settings.py first, followed by +# /etc/tower/conf.d/*.py. +try: + include(settings_file, optional(settings_files), scope=locals()) +except ImportError: + traceback.print_exc() + sys.exit(1) +except IOError: + from django.core.exceptions import ImproperlyConfigured + + included_file = locals().get('__included_file__', '') + if not included_file or included_file == settings_file: + # The import doesn't always give permission denied, so try to open the + # settings file directly. + try: + e = None + open(settings_file) + except IOError: + pass + if e and e.errno == errno.EACCES: + SECRET_KEY = 'permission-denied' + LOGGING = {} + else: + msg = 'No AWX configuration found at %s.' % settings_file + msg += '\nDefine the AWX_SETTINGS_FILE environment variable to ' + msg += 'specify an alternate path.' + raise ImproperlyConfigured(msg) + else: + raise + +# The below runs AFTER all of the custom settings are imported +# because conf.d files will define DATABASES and this should modify that +from .application_name import set_application_name + +set_application_name(DATABASES, CLUSTER_HOST_ID) # NOQA + +del set_application_name diff --git a/awx/settings/development_quiet.py b/awx/settings/quiet_defaults.py similarity index 61% rename from awx/settings/development_quiet.py rename to awx/settings/quiet_defaults.py index c47e78b69d86..1cb21720f7dd 100644 --- a/awx/settings/development_quiet.py +++ b/awx/settings/quiet_defaults.py @@ -1,14 +1,7 @@ # Copyright (c) 2015 Ansible, Inc. # All Rights Reserved. - # Development settings for AWX project, but with DEBUG disabled -# Load development settings. -from defaults import * # NOQA - -# Load development settings. -from development import * # NOQA - # Disable capturing DEBUG DEBUG = False TEMPLATE_DEBUG = DEBUG diff --git a/awx/urls.py b/awx/urls.py index daef360d5788..28eeb6960906 100644 --- a/awx/urls.py +++ b/awx/urls.py @@ -37,13 +37,14 @@ def get_urlpatterns(prefix=None): re_path(r'^(?!api/).*', include('awx.ui.urls', namespace='ui')), ] - if settings.SETTINGS_MODULE == 'awx.settings.development': - try: - import debug_toolbar - - urlpatterns += [re_path(r'^__debug__/', include(debug_toolbar.urls))] - except ImportError: - pass + # TODO: check current_env + # if settings.SETTINGS_MODULE == 'awx.settings.development': + # try: + # import debug_toolbar + + # urlpatterns += [re_path(r'^__debug__/', include(debug_toolbar.urls))] + # except ImportError: + # pass return urlpatterns diff --git a/requirements/requirements.in b/requirements/requirements.in index e003a1cd59e9..948964c18f0d 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -24,6 +24,7 @@ django-solo django-split-settings djangorestframework>=3.15.0 djangorestframework-yaml +dynaconf<4 filelock GitPython>=3.1.37 # CVE-2023-41040 grpcio<1.63.0 # 1.63.0+ requires cython>=3 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 69e323ffde1d..8c3b2c47acd9 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -167,6 +167,8 @@ djangorestframework-yaml==2.0.0 # via -r /awx_devel/requirements/requirements.in docutils==0.20.1 # via python-daemon +dynaconf==3.2.6 + # via -r /awx_devel/requirements/requirements.in enum-compat==0.0.3 # via asn1 filelock==3.13.1