Skip to content

Commit 25381a6

Browse files
committed
Change flags list to yaml list
1 parent 48ad36a commit 25381a6

File tree

10 files changed

+99
-112
lines changed

10 files changed

+99
-112
lines changed

ansible_base/feature_flags/feature_flags.py

Lines changed: 0 additions & 85 deletions
This file was deleted.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
- name: FEATURE_INDIRECT_NODE_COUNTING_ENABLED
2+
ui_name: Indirect Node Counting
3+
visibility: public
4+
condition: boolean
5+
value: 'False'
6+
support_level: NOT_FOR_PRODUCTION
7+
description: TBD
8+
support_url: https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/
9+
labels:
10+
- controller
11+
- name: FEATURE_POLICY_AS_CODE_ENABLED
12+
ui_name: Policy as Code
13+
visibility: public
14+
condition: boolean
15+
value: 'False'
16+
support_level: NOT_FOR_PRODUCTION
17+
description: TBD
18+
support_url: https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/
19+
labels:
20+
- controller
21+
- name: FEATURE_EDA_ANALYTICS_ENABLED
22+
ui_name: Event-Driven Ansible Analytics
23+
visibility: public
24+
condition: boolean
25+
value: 'False'
26+
support_level: NOT_FOR_PRODUCTION
27+
description: TBD
28+
support_url: https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/
29+
labels:
30+
- eda
31+
- name: FEATURE_GATEWAY_IPV6_USAGE_ENABLED
32+
ui_name: Gateway IPv6 Usage
33+
visibility: private
34+
condition: boolean
35+
value: 'False'
36+
support_level: NOT_FOR_PRODUCTION
37+
description: TBD
38+
support_url: https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/
39+
labels:
40+
- gateway
41+
- name: FEATURE_GATEWAY_CREATE_CRC_SERVICE_TYPE_ENABLED
42+
ui_name: Gateway Create CRC Service Type
43+
visibility: private
44+
condition: boolean
45+
value: 'False'
46+
support_level: NOT_FOR_PRODUCTION
47+
description: TBD
48+
support_url: https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/
49+
labels:
50+
- gateway
51+
- name: FEATURE_DISPATCHERD_ENABLED
52+
ui_name: AAP Dispatcherd
53+
visibility: private
54+
condition: boolean
55+
value: 'False'
56+
support_level: NOT_FOR_PRODUCTION
57+
description: TBD
58+
support_url: https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/
59+
labels:
60+
- eda
61+
- controller

ansible_base/feature_flags/utils.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
import logging
2+
from pathlib import Path
23

4+
import yaml
35
from django.apps import apps
46
from django.conf import settings
57
from django.core.exceptions import ValidationError
68
from flags.sources import get_flags
79

8-
from ansible_base.feature_flags.feature_flags import AAP_FEATURE_FLAGS
9-
1010
logger = logging.getLogger('ansible_base.feature_flags.utils')
1111

1212

1313
def get_django_flags():
1414
return get_flags()
1515

1616

17+
def feature_flags_list():
18+
current_dir = Path(__file__).parent
19+
flags_list_file = current_dir / 'feature_flags.yaml'
20+
with open(flags_list_file, 'r') as file:
21+
try:
22+
return yaml.safe_load(file)
23+
except yaml.YAMLError as exc:
24+
print(exc)
25+
26+
1727
def create_initial_data(**kwargs): # NOSONAR
1828
"""
1929
Loads in platform feature flags when the server starts
@@ -45,7 +55,7 @@ def load_feature_flags():
4555
from ansible_base.resource_registry.signals.handlers import no_reverse_sync
4656

4757
feature_flags_model = apps.get_model('dab_feature_flags', 'AAPFlag')
48-
for flag in AAP_FEATURE_FLAGS:
58+
for flag in feature_flags_list():
4959
try:
5060
existing_flag = feature_flags_model.objects.filter(name=flag['name'], condition=flag['condition'])
5161
if existing_flag:
@@ -75,7 +85,7 @@ def delete_feature_flags():
7585
all_flags = apps.get_model('dab_feature_flags', 'AAPFlag').objects.all()
7686
for flag in all_flags:
7787
found = False
78-
for _flag in AAP_FEATURE_FLAGS:
88+
for _flag in feature_flags_list():
7989
if flag.name == _flag['name'] and flag.condition == _flag['condition']:
8090
found = True
8191
break

test_app/tests/authentication/management/test_authenticators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def test_authenticators_cli_initialize(
9797
err = StringIO()
9898

9999
# Sanity check:
100-
assert django_user_model.objects.count() == 0
100+
assert django_user_model.objects.count() == 1
101101

102102
# Optionally create admin user
103103
if admin_user_exists:

test_app/tests/feature_flags/management/test_feature_flags.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,10 @@ def test_handle_no_options():
203203

204204
@pytest.mark.django_db
205205
def test_management_command_existing_data(aap_flags, capsys):
206-
from ansible_base.feature_flags.feature_flags import AAP_FEATURE_FLAGS
206+
from ansible_base.feature_flags.utils import feature_flags_list
207207

208208
call_command('feature_flags', '--list')
209209

210210
captured = capsys.readouterr()
211211
output_lines = captured.out.strip().split('\n')
212-
assert len(output_lines) - 2 == len(AAP_FEATURE_FLAGS) # Subtract 2 to remove header and '---' line before data
212+
assert len(output_lines) - 2 == len(feature_flags_list()) # Subtract 2 to remove header and '---' line before data

test_app/tests/feature_flags/models/test_aap_flag.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import pytest
22
from django.conf import settings
33

4-
from ansible_base.feature_flags.feature_flags import AAP_FEATURE_FLAGS
54
from ansible_base.feature_flags.models import AAPFlag
5+
from ansible_base.feature_flags.utils import feature_flags_list
66

77

88
@pytest.mark.django_db
@@ -13,7 +13,7 @@ def test_total_platform_flags(aap_flags):
1313
@pytest.mark.django_db
1414
@pytest.mark.parametrize(
1515
"feature_flag",
16-
AAP_FEATURE_FLAGS,
16+
feature_flags_list(),
1717
)
1818
def test_feature_flags_from_db(aap_flags, feature_flag):
1919
flag = AAPFlag.objects.get(name=feature_flag['name'])

test_app/tests/feature_flags/test_old_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ def test_feature_flags_state_api_list(admin_api_client: APIClient):
77
"""
88
Test that we can list all feature flags
99
"""
10-
url = get_relative_url("featureflags-list")
10+
url = get_relative_url("feature-flags-state-list")
1111
response = admin_api_client.get(url)
1212
assert response.status_code == 200

test_app/tests/feature_flags/test_utils.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,9 @@ def mock_logger(mocker):
102102

103103

104104
@pytest.fixture
105-
def mock_aap_feature_flags_constant(mocker):
106-
return mocker.patch(f"{MODULE_PATH}.AAP_FEATURE_FLAGS", [])
105+
def mock_feature_flags_list(mocker):
106+
mock = mocker.patch(f"{MODULE_PATH}.feature_flags_list")
107+
return mock
107108

108109

109110
def test_get_django_flags(mocker):
@@ -122,7 +123,7 @@ class TestCreateInitialData:
122123

123124
@pytest.mark.django_db # May not be strictly necessary with all the mocking, but good practice
124125
def test_load_feature_flags_creates_new_flag_from_settings_value(
125-
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_aap_feature_flags_constant, mocker
126+
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_feature_flags_list, mocker
126127
):
127128
from ansible_base.feature_flags.utils import create_initial_data
128129

@@ -134,8 +135,7 @@ def test_load_feature_flags_creates_new_flag_from_settings_value(
134135
'visibility': 'public',
135136
# No 'value' here, expecting it from settings
136137
}
137-
mock_aap_feature_flags_constant.append(flag_def)
138-
138+
mock_feature_flags_list.return_value = [flag_def]
139139
# --- Mocks for database interaction (for load_feature_flags part) ---
140140
mock_filter_queryset = MagicMock()
141141
# Simulate flag does NOT exist:
@@ -182,7 +182,7 @@ def test_load_feature_flags_creates_new_flag_from_settings_value(
182182

183183
@pytest.mark.django_db
184184
def test_load_feature_flags_creates_new_flag_with_default_value_if_not_in_settings(
185-
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_aap_feature_flags_constant, mocker
185+
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_feature_flags_list, mocker
186186
):
187187
from ansible_base.feature_flags.utils import create_initial_data
188188

@@ -194,7 +194,7 @@ def test_load_feature_flags_creates_new_flag_with_default_value_if_not_in_settin
194194
'visibility': 'private',
195195
'value': False, # Default value in definition
196196
}
197-
mock_aap_feature_flags_constant.extend([flag_def])
197+
mock_feature_flags_list.return_value = [flag_def]
198198

199199
mock_empty_queryset = MagicMock()
200200
mock_empty_queryset.first.return_value = None
@@ -216,7 +216,7 @@ def test_load_feature_flags_creates_new_flag_with_default_value_if_not_in_settin
216216

217217
@pytest.mark.django_db
218218
def test_load_feature_flags_updates_existing_flag(
219-
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_aap_feature_flags_constant, mocker
219+
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_feature_flags_list, mocker
220220
):
221221
from ansible_base.feature_flags.utils import create_initial_data
222222

@@ -232,7 +232,7 @@ def test_load_feature_flags_updates_existing_flag(
232232
'labels': ['new'],
233233
'description': 'new desc',
234234
}
235-
mock_aap_feature_flags_constant.extend([flag_def_updated])
235+
mock_feature_flags_list.return_value = [flag_def_updated]
236236

237237
existing_db_flag = MockAAPFlagInstance(
238238
name='EXISTING_FLAG',
@@ -274,12 +274,12 @@ def test_load_feature_flags_updates_existing_flag(
274274

275275
@pytest.mark.django_db
276276
def test_load_feature_flags_handles_specific_validation_error(
277-
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_aap_feature_flags_constant, mocker
277+
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_feature_flags_list, mocker
278278
):
279279
from ansible_base.feature_flags.utils import create_initial_data
280280

281281
flag_def = {'name': 'ERROR_FLAG', 'condition': 'err_cond', 'ui_name': 'Error Flag'}
282-
mock_aap_feature_flags_constant.extend([flag_def])
282+
mock_feature_flags_list.return_value = [flag_def]
283283

284284
mock_empty_queryset = MagicMock()
285285
mock_empty_queryset.first.return_value = None
@@ -302,12 +302,12 @@ def test_load_feature_flags_handles_specific_validation_error(
302302

303303
@pytest.mark.django_db
304304
def test_load_feature_flags_logs_other_validation_errors(
305-
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_aap_feature_flags_constant, mocker
305+
self, mock_apps_get_model, mock_aap_flag_model_cls, mock_settings, mock_logger, mock_feature_flags_list, mocker
306306
):
307307
from ansible_base.feature_flags.utils import create_initial_data
308308

309309
flag_def = {'name': 'OTHER_ERROR_FLAG', 'condition': 'other_err_cond', 'ui_name': 'Other Error'}
310-
mock_aap_feature_flags_constant.extend([flag_def])
310+
mock_feature_flags_list.return_value = [flag_def]
311311

312312
mock_empty_queryset = MagicMock()
313313
mock_empty_queryset.first.return_value = None
@@ -329,7 +329,7 @@ def test_load_feature_flags_logs_other_validation_errors(
329329
mock_created_instance.save.assert_not_called()
330330

331331
@pytest.mark.django_db
332-
def test_delete_feature_flags_removes_obsolete_flag(self, mock_apps_get_model, mock_aap_flag_model_cls, mock_logger, mock_aap_feature_flags_constant):
332+
def test_delete_feature_flags_removes_obsolete_flag(self, mock_apps_get_model, mock_aap_flag_model_cls, mock_logger, mock_feature_flags_list):
333333
from ansible_base.feature_flags.utils import create_initial_data
334334

335335
obsolete_flag_in_db = MockAAPFlagInstance(name='OBSOLETE_FLAG', condition='obs_cond')
@@ -347,11 +347,11 @@ def test_delete_feature_flags_removes_obsolete_flag(self, mock_apps_get_model, m
347347
mock_logger.info.assert_any_call(f"Deleting feature flag: {obsolete_flag_in_db.name} as it is no longer available as a platform flag")
348348

349349
@pytest.mark.django_db
350-
def test_delete_feature_flags_keeps_current_flag(self, mock_apps_get_model, mock_aap_flag_model_cls, mock_logger, mock_aap_feature_flags_constant):
350+
def test_delete_feature_flags_keeps_current_flag(self, mock_apps_get_model, mock_aap_flag_model_cls, mock_logger, mock_feature_flags_list):
351351
from ansible_base.feature_flags.utils import create_initial_data
352352

353353
current_flag_def = {'name': 'CURRENT_FLAG', 'condition': 'curr_cond', 'ui_name': 'Current'}
354-
mock_aap_feature_flags_constant.extend([current_flag_def])
354+
mock_feature_flags_list.return_value = [current_flag_def]
355355

356356
current_flag_in_db = MockAAPFlagInstance(name='CURRENT_FLAG', condition='curr_cond')
357357

test_app/tests/feature_flags/views/test_feature_flag.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_old_feature_flags_list(admin_api_client, aap_flags):
5252
"""
5353
Test that we can list feature flags api, after preloading data
5454
"""
55-
url = get_relative_url("featureflags-list")
55+
url = get_relative_url("feature-flags-state-list")
5656
response = admin_api_client.get(url)
5757
assert response.status_code == 200
5858
assert len(response.data) == 6

test_app/tests/lib/utils/test_create_system_user.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def test_get_system_user_from_basic_model(self):
7373

7474
@pytest.mark.django_db
7575
def test_get_system_user_from_managed_model(self):
76+
User.all_objects.filter(username=get_system_username()[0]).delete()
7677
create_system_user(user_model=ManagedUser)
7778

7879
assert ManagedUser.objects.filter(username=get_system_username()[0]).count() == 0

0 commit comments

Comments
 (0)