|
1 | 1 | from django.conf import settings
|
| 2 | +from django.shortcuts import get_object_or_404 |
2 | 3 | from django.utils.translation import gettext_lazy as _
|
| 4 | +from flags.state import flag_enabled, flag_state, get_flags |
| 5 | +from rest_framework import status |
3 | 6 | from rest_framework.response import Response
|
| 7 | +from rest_framework.viewsets import ModelViewSet |
4 | 8 |
|
5 |
| -from ansible_base.feature_flags.serializers import FeatureFlagSerializer |
| 9 | +from ansible_base.feature_flags.models import AAPFlag |
| 10 | +from ansible_base.feature_flags.serializers import FeatureFlagSerializer, OldFeatureFlagSerializer |
6 | 11 | from ansible_base.lib.utils.views.ansible_base import AnsibleBaseView
|
| 12 | +from ansible_base.lib.utils.views.django_app_api import AnsibleBaseDjangoAppApiView |
| 13 | +from ansible_base.lib.utils.views.permissions import IsSuperuserOrAuditor |
| 14 | +from ansible_base.rest_pagination import DefaultPaginator |
7 | 15 |
|
8 |
| -from .utils import get_django_flags |
| 16 | +from .utils import get_django_flags, is_boolean_str |
9 | 17 |
|
10 | 18 |
|
11 |
| -class FeatureFlagsStateListView(AnsibleBaseView): |
| 19 | +class FeatureFlagsStatesView(AnsibleBaseDjangoAppApiView, ModelViewSet): |
| 20 | + """ |
| 21 | + A view class for displaying feature flags states |
| 22 | + """ |
| 23 | + |
| 24 | + queryset = AAPFlag.objects.order_by('id') |
| 25 | + permission_classes = [IsSuperuserOrAuditor] |
| 26 | + http_method_names = ['get', 'head', 'options'] |
| 27 | + |
| 28 | + def list(self, request): |
| 29 | + paginator = DefaultPaginator() |
| 30 | + flags = get_flags() |
| 31 | + ret = [] |
| 32 | + for flag in flags: |
| 33 | + ret.append({"flag_name": flag, "flag_state": flag_state(flag)}) |
| 34 | + result_page = paginator.paginate_queryset(ret, request) |
| 35 | + return paginator.get_paginated_response(result_page) |
| 36 | + |
| 37 | + |
| 38 | +class FeatureFlagsView(AnsibleBaseDjangoAppApiView, ModelViewSet): |
12 | 39 | """
|
13 | 40 | A view class for displaying feature flags
|
14 | 41 | """
|
15 | 42 |
|
| 43 | + queryset = AAPFlag.objects.order_by('id') |
16 | 44 | serializer_class = FeatureFlagSerializer
|
| 45 | + permission_classes = [IsSuperuserOrAuditor] |
| 46 | + http_method_names = ['get', 'put', 'head', 'options'] |
| 47 | + |
| 48 | + def update(self, request, **kwargs): |
| 49 | + _feature_flag = self.get_object() |
| 50 | + value = request.data.get('value') |
| 51 | + if not value: |
| 52 | + return Response(status=status.HTTP_400_BAD_REQUEST, data={"details": "Invalid request object."}) |
| 53 | + |
| 54 | + # Disable runtime toggle if the feature flag feature is not enabled |
| 55 | + if not flag_enabled('FEATURE_FEATURE_FLAGS_ENABLED'): |
| 56 | + return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED, data={"details": "Runtime feature flags toggle is not enabled."}) |
| 57 | + |
| 58 | + feature_flag = get_object_or_404(AAPFlag, pk=_feature_flag.id) |
| 59 | + if feature_flag.toggle_type == 'install-time': |
| 60 | + return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED, data={"details": "Install-time feature flags cannot be toggled at run-time."}) |
| 61 | + if feature_flag.condition == "boolean" and not is_boolean_str(value): |
| 62 | + return Response(status=status.HTTP_400_BAD_REQUEST, data={"details": "Feature flag boolean conditional requires using boolean value."}) |
| 63 | + feature_flag.value = value |
| 64 | + feature_flag.save() |
| 65 | + |
| 66 | + return Response(self.get_serializer().to_representation(feature_flag)) |
| 67 | + |
| 68 | + |
| 69 | +# TODO: This can be removed after functionality is migrated over to new class |
| 70 | +class OldFeatureFlagsStateListView(AnsibleBaseView): |
| 71 | + """ |
| 72 | + A view class for displaying feature flags |
| 73 | + """ |
| 74 | + |
| 75 | + serializer_class = OldFeatureFlagSerializer |
17 | 76 | filter_backends = []
|
18 | 77 | name = _('Feature Flags')
|
19 | 78 | http_method_names = ['get', 'head']
|
20 | 79 |
|
21 | 80 | def _get(self, request, format=None):
|
22 |
| - self.serializer = FeatureFlagSerializer() |
| 81 | + self.serializer = OldFeatureFlagSerializer() |
23 | 82 | return Response(self.serializer.to_representation())
|
24 | 83 |
|
25 | 84 | def get_queryset(self):
|
|
0 commit comments