Skip to content

Commit 2ef72a1

Browse files
committed
Adjust feature flag metadata
1 parent 740140d commit 2ef72a1

File tree

8 files changed

+66
-54
lines changed

8 files changed

+66
-54
lines changed
Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,52 @@
11
- name: FEATURE_INDIRECT_NODE_COUNTING_ENABLED
22
ui_name: Indirect Node Counting
3-
visibility: public
3+
visibility: True
44
condition: boolean
55
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
6+
support_level: TECHNICAL_PREVIEW
177
description: TBD
188
support_url: https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/
199
labels:
2010
- controller
2111
- name: FEATURE_EDA_ANALYTICS_ENABLED
2212
ui_name: Event-Driven Ansible Analytics
23-
visibility: public
13+
visibility: True
2414
condition: boolean
2515
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/
16+
support_level: TECHNICAL_PREVIEW
17+
description: Submit Event-Driven Ansible usage analytics to console.redhat.com
18+
support_url: https://access.redhat.com/solutions/7112810
2919
labels:
3020
- eda
3121
- name: FEATURE_GATEWAY_IPV6_USAGE_ENABLED
32-
ui_name: Gateway IPv6 Usage
33-
visibility: private
22+
ui_name: Gateway IPv6 Enablement
23+
visibility: False
3424
condition: boolean
3525
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/
26+
support_level: TECHNICAL_PREVIEW
27+
description: The feature flag represents enabling IPv6 only traffic to be allowed through the gateway component and does not include all components of the platform.
28+
support_url: https://access.redhat.com/articles/7116569
3929
labels:
4030
- gateway
4131
- name: FEATURE_GATEWAY_CREATE_CRC_SERVICE_TYPE_ENABLED
42-
ui_name: Gateway Create CRC Service Type
43-
visibility: private
32+
ui_name: Dynamic Service Type Feature
33+
visibility: False
4434
condition: boolean
4535
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/
36+
support_level: DEVELOPER_PREVIEW
37+
description: The Dynamic Service Type feature allows for the introduction of new platform services without requiring registration to the existing database. The new service can be enabled through the use of configuration.
38+
support_url: https://access.redhat.com/articles/7122668
39+
toggle_type: install-time
4940
labels:
5041
- gateway
5142
- name: FEATURE_DISPATCHERD_ENABLED
5243
ui_name: AAP Dispatcherd
53-
visibility: private
44+
visibility: True
5445
condition: boolean
5546
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/
47+
support_level: DEVELOPER_PREVIEW
48+
description: A service to run python tasks in subprocesses, designed specifically to work well with pg_notify, but intended to be extensible to other message delivery means.
49+
support_url: ''
5950
labels:
6051
- eda
6152
- controller

ansible_base/feature_flags/definitions/schema.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
},
1919
"visibility": {
2020
"description": "Controls whether the feature is visible in the UI.",
21-
"type": "string",
22-
"enum": ["public", "private"]
21+
"type": "boolean"
2322
},
2423
"condition": {
2524
"description": "The type of condition for the feature flag's value. Currently only boolean is supported.",
@@ -35,9 +34,8 @@
3534
"description": "The level of support provided for this feature.",
3635
"type": "string",
3736
"enum": [
38-
"NOT_FOR_USE",
39-
"NOT_FOR_PRODUCTION",
40-
"READY_FOR_PRODUCTION"
37+
"TECHNICAL_PREVIEW",
38+
"DEVELOPER_PREVIEW"
4139
]
4240
},
4341
"description": {

ansible_base/feature_flags/flag_source.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,19 @@
22
from flags.sources import Condition
33

44

5+
class DatabaseCondition(Condition):
6+
"""Condition that includes the AAPFlags database object
7+
This is required to ensure that enable_flag/disable_flag calls
8+
can work as expected, with the custom flag objects
9+
"""
10+
11+
def __init__(self, condition, value, required=False, obj=None):
12+
super().__init__(condition, value, required=required)
13+
self.obj = obj
14+
15+
516
class AAPFlagSource(object):
17+
"""The customer AAP flag source, retrieves a list of all flags in the database"""
618

719
def get_queryset(self):
820
aap_flags = apps.get_model('dab_feature_flags', 'AAPFlag')
@@ -13,5 +25,5 @@ def get_flags(self):
1325
for o in self.get_queryset():
1426
if o.name not in flags:
1527
flags[o.name] = []
16-
flags[o.name].append(Condition(o.condition, o.value, required=o.required))
28+
flags[o.name].append(DatabaseCondition(o.condition, o.value, required=o.required, obj=o))
1729
return flags

ansible_base/feature_flags/migrations/0001_initial.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Generated by Django 4.2.17 on 2025-06-06 16:22
1+
# Generated by Django 4.2.21 on 2025-06-17 20:08
22

33
import ansible_base.feature_flags.models.aap_flag
44
from django.conf import settings
@@ -26,8 +26,8 @@ class Migration(migrations.Migration):
2626
('condition', models.CharField(default='boolean', help_text='Used to specify a condition, which if met, will enable the feature flag.', max_length=64)),
2727
('value', models.CharField(default='False', help_text='The value used to evaluate the conditional specified.', max_length=127)),
2828
('required', models.BooleanField(default=False, help_text="If multiple conditions are required to be met to enable a feature flag, 'required' can be used to specify the necessary conditionals.")),
29-
('support_level', models.CharField(choices=[('NOT_FOR_USE', 'Not for use'), ('NOT_FOR_PRODUCTION', 'Not for production'), ('READY_FOR_PRODUCTION', 'Ready for production')], help_text='The support criteria for the feature flag. Must be one of (NOT_FOR_USE, NOT_FOR_PRODUCTION, READY_FOR_PRODUCTION).', max_length=25)),
30-
('visibility', models.CharField(choices=[('public', 'public'), ('private', 'private')], help_text='The visibility level of the feature flag. If private, flag is hidden.', max_length=20)),
29+
('support_level', models.CharField(choices=[('DEVELOPER_PREVIEW', 'Developer Preview'), ('TECHNICAL_PREVIEW', 'Technical Preview')], help_text='The support criteria for the feature flag. Must be one of (DEVELOPER_PREVIEW or TECHNICAL_PREVIEW).', max_length=25)),
30+
('visibility', models.BooleanField(default=False, help_text='The visibility of the feature flag. If false, flag is hidden.')),
3131
('toggle_type', models.CharField(choices=[('install-time', 'install-time'), ('run-time', 'run-time')], default='run-time', help_text="Details whether a flag is toggle-able at run-time or install-time. (Default: 'run-time').", max_length=20)),
3232
('description', models.CharField(default='', help_text='A detailed description giving an overview of the feature flag.', max_length=500)),
3333
('support_url', models.CharField(blank=True, default='', help_text='A link to the documentation support URL for the feature', max_length=250)),

ansible_base/feature_flags/models/aap_flag.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,13 @@ def __str__(self):
4747
support_level = models.CharField(
4848
max_length=25,
4949
null=False,
50-
help_text=_("The support criteria for the feature flag. Must be one of (NOT_FOR_USE, NOT_FOR_PRODUCTION, READY_FOR_PRODUCTION)."),
51-
choices=(('NOT_FOR_USE', 'Not for use'), ('NOT_FOR_PRODUCTION', 'Not for production'), ('READY_FOR_PRODUCTION', 'Ready for production')),
50+
help_text=_("The support criteria for the feature flag. Must be one of (DEVELOPER_PREVIEW or TECHNICAL_PREVIEW)."),
51+
choices=(('DEVELOPER_PREVIEW', 'Developer Preview'), ('TECHNICAL_PREVIEW', 'Technical Preview')),
5252
blank=False,
5353
)
54-
visibility = models.CharField(
55-
max_length=20,
56-
null=False,
57-
choices=[('public', 'public'), ('private', 'private')],
58-
help_text=_("The visibility level of the feature flag. If private, flag is hidden."),
59-
blank=False,
54+
visibility = models.BooleanField(
55+
default=False,
56+
help_text=_("The visibility of the feature flag. If false, flag is hidden."),
6057
)
6158
toggle_type = models.CharField(
6259
max_length=20,

docs/apps/feature_flags.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ An example flag could resemble -
5757
```yaml
5858
- name: FEATURE_FOO_ENABLED
5959
ui_name: Foo
60-
visibility: public
60+
visibility: True
6161
condition: boolean
6262
value: 'False'
6363
support_level: NOT_FOR_PRODUCTION

test_app/tests/feature_flags/models/test_aap_flag.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import pytest
22
from django.conf import settings
3+
from flags.state import disable_flag, enable_flag, flag_state
34

45
from ansible_base.feature_flags.models import AAPFlag
56
from ansible_base.feature_flags.utils import feature_flags_list
67

78

89
@pytest.mark.django_db
910
def test_total_platform_flags(aap_flags):
10-
assert AAPFlag.objects.count() == 6
11+
assert AAPFlag.objects.count() == len(feature_flags_list())
1112

1213

1314
@pytest.mark.django_db
@@ -35,8 +36,6 @@ def test_feature_flags_from_db(aap_flags, feature_flag):
3536
"feature_flag, value",
3637
[
3738
('FEATURE_INDIRECT_NODE_COUNTING_ENABLED', True),
38-
('FEATURE_POLICY_AS_CODE_ENABLED', True),
39-
('FEATURE_EDA_ANALYTICS_ENABLED', False),
4039
('FEATURE_GATEWAY_IPV6_USAGE_ENABLED', False),
4140
],
4241
)
@@ -48,3 +47,17 @@ def test_feature_flag_database_setting_override(feature_flag, value):
4847
create_initial_data()
4948
flag = AAPFlag.objects.get(name=feature_flag)
5049
assert flag.value == str(value)
50+
51+
52+
@pytest.mark.django_db
53+
def test_enable_and_disable_flag_functions(aap_flags):
54+
flag_name = "FEATURE_INDIRECT_NODE_COUNTING_ENABLED"
55+
# Assert Initial State
56+
assert flag_state(flag_name) is False
57+
58+
# Ensure flag can be enabled via django-flags enable_flag function
59+
enable_flag(flag_name)
60+
assert flag_state(flag_name) is True
61+
# Ensure flag can be disabled via django-flags enable_flag function
62+
disable_flag(flag_name)
63+
assert flag_state(flag_name) is False

test_app/tests/feature_flags/views/test_feature_flag.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from django.conf import settings
33

44
from ansible_base.feature_flags.models import AAPFlag
5+
from ansible_base.feature_flags.utils import feature_flags_list
56
from ansible_base.lib.utils.response import get_relative_url
67

78

@@ -10,7 +11,7 @@
1011
[
1112
[
1213
{'name': 'FEATURE_INDIRECT_NODE_COUNTING_ENABLED', 'value': True},
13-
{'name': 'FEATURE_POLICY_AS_CODE_ENABLED', 'value': True},
14+
{'name': 'FEATURE_EDA_ANALYTICS_ENABLED', 'value': True},
1415
],
1516
[
1617
{'name': 'FEATURE_GATEWAY_IPV6_USAGE_ENABLED', 'value': False},
@@ -33,7 +34,7 @@ def test_feature_flags_states_list(admin_api_client, flags_list):
3334
url = get_relative_url("aap_flags_states-list")
3435
response = admin_api_client.get(url)
3536
assert response.status_code == 200
36-
assert len(response.data['results']) == 6
37+
assert len(response.data['results']) == len(feature_flags_list())
3738

3839
found_and_verified_flags_count = 0
3940
for flag_from_api in response.data['results']:
@@ -55,4 +56,4 @@ def test_old_feature_flags_list(admin_api_client, aap_flags):
5556
url = get_relative_url("feature-flags-state-list")
5657
response = admin_api_client.get(url)
5758
assert response.status_code == 200
58-
assert len(response.data) == 6
59+
assert len(response.data) == len(feature_flags_list())

0 commit comments

Comments
 (0)