Skip to content

Commit 1140ec4

Browse files
authored
[AAP-41917] fix: default EDA_MODE to production (#1236)
env EDA_MODE was not set. All settings from production/development/testing are imported. This fix sets EDA_MODE to production by default to avoid conflict settings from different modes. Different mode can still be set by the env var. Also directly call toggle_feature_flags function from DAB. [AAP-41917](https://issues.redhat.com/browse/AAP-41917) For testing pick a setting and set to different value in /etc/eda/settings.yaml under production/development/testing sections and prove the value is selected according to explicitly set EDA_MODE. When EDA_MODE is not set, the value under production is selected.
1 parent 4813f5f commit 1140ec4

File tree

5 files changed

+96
-36
lines changed

5 files changed

+96
-36
lines changed

src/aap_eda/settings/default.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,24 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
import os
15+
1416
from ansible_base.lib.dynamic_config import (
1517
export,
1618
factory,
1719
load_dab_settings,
1820
load_envvars,
1921
load_standard_settings_files,
22+
toggle_feature_flags,
2023
)
2124

2225
from .post_load import post_loading
2326

24-
EDA_SETTINGS_FILE = "/etc/eda/settings.yaml"
27+
EDA_SETTINGS_FILE = os.environ.get(
28+
"EDA_SETTINGS_FILE", "/etc/eda/settings.yaml"
29+
)
30+
31+
os.environ["EDA_MODE"] = os.environ.get("EDA_MODE", "production")
2532

2633
DYNACONF = factory(
2734
__name__,
@@ -31,12 +38,27 @@
3138
settings_files=["defaults.py"],
3239
)
3340

34-
DYNACONF.load_file(EDA_SETTINGS_FILE)
41+
# Insert the custom file in the list of standard settings so DAB loads it
42+
# without requiring mode based sections.
43+
DYNACONF.set(
44+
"ANSIBLE_STANDARD_SETTINGS_FILES", f"@insert 3 {EDA_SETTINGS_FILE}"
45+
)
46+
3547
load_standard_settings_files(
3648
DYNACONF
3749
) # /etc/ansible-automation-platform/*.yaml
3850
load_envvars(DYNACONF) # load envvars prefixed with EDA_
3951
DYNACONF.load_file("core.py") # load internal non-overwritable settings
4052
post_loading(DYNACONF)
4153
load_dab_settings(DYNACONF)
54+
55+
# toggle feature flags, considering flags coming from
56+
# /etc/ansible-automation-platform/*.yaml
57+
# and envvars like `EDA_FEATURE_FOO_ENABLED=true
58+
DYNACONF.update(
59+
toggle_feature_flags(DYNACONF),
60+
loader_identifier="settings:toggle_feature_flags",
61+
merge=True,
62+
)
63+
4264
export(__name__, DYNACONF) # export back to django.conf.settings

src/aap_eda/settings/post_load.py

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
from typing import Any, Optional, get_type_hints
14+
from typing import Optional, get_type_hints
1515

1616
from django.core.exceptions import ImproperlyConfigured
1717
from dynaconf import Dynaconf
18-
from dynaconf.utils.functional import empty
1918

2019
from aap_eda import utils
2120
from aap_eda.core.enums import RulebookProcessLogLevel
@@ -85,28 +84,6 @@ def _get_url_end_slash(settings: Dynaconf, name: str) -> str:
8584
return value
8685

8786

88-
def toggle_feature_flags(settings: Dynaconf) -> dict[str, Any]:
89-
"""Toggle FLAGS based on installer settings.
90-
91-
FLAGS is a django-flags formatted dictionary.
92-
FLAGS={
93-
"FEATURE_SOME_PLATFORM_FLAG_ENABLED": [
94-
{"condition": "boolean", "value": False, "required": True},
95-
{"condition": "before date", "value": "2022-06-01T12:00Z"},
96-
]
97-
}
98-
Installers will place `FEATURE_SOME_PLATFORM_FLAG_ENABLED=True/False` in
99-
the settings file. This function will update the value in the index 0 in
100-
FLAGS with the installer value.
101-
"""
102-
data = {}
103-
for feature_name, feature_content in settings.get("FLAGS", {}).items():
104-
if (installer_value := settings.get(feature_name, empty)) is not empty:
105-
feature_content[0]["value"] = installer_value
106-
data[f"FLAGS__{feature_name}"] = feature_content
107-
return data
108-
109-
11087
# Database
11188
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
11289

@@ -433,12 +410,3 @@ def post_loading(loaded_settings: Dynaconf):
433410
if key not in loaded_settings or settings[key] != loaded_settings[key]
434411
}
435412
loaded_settings.update(data, loader_identifier="settings:post_loading")
436-
437-
# toggle feature flags, considering flags coming from
438-
# /etc/ansible-automation-platform/*.yaml
439-
# and envvars like `EDA_FEATURE_FOO_ENABLED=true
440-
loaded_settings.update(
441-
toggle_feature_flags(settings),
442-
loader_identifier="settings:toggle_feature_flags",
443-
merge=True,
444-
)

tests/integration/api/test_feature_flags.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import pytest
2+
from ansible_base.lib.dynamic_config import toggle_feature_flags
23
from django.conf import settings
34
from django.test import override_settings
45
from flags.state import flag_state
56
from rest_framework import status
67

7-
from aap_eda.settings.post_load import toggle_feature_flags
88
from tests.integration.constants import api_url_v1
99

1010

tests/unit/data/demo_settings.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SECRET_KEY: "dev.key"

tests/unit/test_import_settings.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Copyright 2025 Red Hat, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import importlib
16+
import os
17+
18+
from django import conf
19+
20+
from aap_eda.settings import default
21+
22+
23+
def test_eda_mode():
24+
# pytest defaults
25+
assert conf.settings.MODE == "development"
26+
dev_sec_key = conf.settings.SECRET_KEY
27+
sec_env_var = os.getenv("EDA_SECRET_KEY")
28+
29+
# default to production mode (need to provide SECRET_KEY)
30+
os.environ.pop("EDA_MODE")
31+
os.environ["EDA_SECRET_KEY"] = "product"
32+
importlib.reload(default)
33+
importlib.reload(conf)
34+
assert conf.settings.MODE == "production"
35+
assert conf.settings.SECRET_KEY == "product"
36+
37+
# roll back to pytest defaults
38+
os.environ["EDA_MODE"] = "development"
39+
if sec_env_var:
40+
os.environ["EDA_SECRET_KEY"] = sec_env_var
41+
else:
42+
os.environ.pop("EDA_SECRET_KEY")
43+
importlib.reload(default)
44+
importlib.reload(conf)
45+
assert conf.settings.MODE == "development"
46+
assert conf.settings.SECRET_KEY == dev_sec_key
47+
48+
49+
def test_import_from_yaml():
50+
dev_sec_key = conf.settings.SECRET_KEY
51+
sec_env_var = os.getenv("EDA_SECRET_KEY")
52+
if sec_env_var:
53+
os.environ.pop("EDA_SECRET_KEY")
54+
55+
file_path = os.path.abspath(__file__)
56+
file_dir = os.path.dirname(file_path)
57+
user_settings_file = os.path.join(file_dir, "data/demo_settings.yaml")
58+
os.environ["EDA_SETTINGS_FILE"] = user_settings_file
59+
importlib.reload(default)
60+
importlib.reload(conf)
61+
assert conf.settings.SECRET_KEY == "dev.key"
62+
63+
# roll back
64+
os.environ.pop("EDA_SETTINGS_FILE", None)
65+
if sec_env_var:
66+
os.environ["EDA_SECRET_KEY"] = sec_env_var
67+
importlib.reload(default)
68+
importlib.reload(conf)
69+
assert conf.settings.SECRET_KEY == dev_sec_key

0 commit comments

Comments
 (0)