diff --git a/apps/assets/api/platform.py b/apps/assets/api/platform.py index 030f90905..dfa63f8f6 100644 --- a/apps/assets/api/platform.py +++ b/apps/assets/api/platform.py @@ -1,17 +1,33 @@ -from rest_framework.viewsets import ModelViewSet +from rest_framework.decorators import action +from rest_framework.response import Response +from common.drf.api import JMSModelViewSet +from common.drf.serializers import GroupedChoiceSerailizer from assets.models import Platform from assets.serializers import PlatformSerializer +from assets.const import AllTypes, Category __all__ = ['AssetPlatformViewSet'] -class AssetPlatformViewSet(ModelViewSet): +class AssetPlatformViewSet(JMSModelViewSet): queryset = Platform.objects.all() - serializer_class = PlatformSerializer + serializer_classes = { + 'default': PlatformSerializer, + 'categories': GroupedChoiceSerailizer + } filterset_fields = ['name'] search_fields = ['name'] + rbac_perms = { + 'categories': 'assets.view_platform' + } + + @action(methods=['GET'], detail=False) + def categories(self, request, *args, **kwargs): + data = AllTypes.grouped_choices_to_objs() + serializer = self.get_serializer(data, many=True) + return Response(serializer.data) def check_object_permissions(self, request, obj): if request.method.lower() in ['delete', 'put', 'patch'] and obj.internal: diff --git a/apps/assets/const.py b/apps/assets/const.py index 0697c2112..218657d22 100644 --- a/apps/assets/const.py +++ b/apps/assets/const.py @@ -11,7 +11,7 @@ __all__ = [ class Category(models.TextChoices): HOST = 'host', _('Host') - NETWORK = 'network', _("Networking") + NETWORK = 'network', _("NetworkDevice") DATABASE = 'database', _("Database") REMOTE_APP = 'remote_app', _("Remote app") CLOUD = 'cloud', _("Clouding") @@ -62,6 +62,32 @@ class AllTypes(metaclass=IncludesTextChoicesMeta): RemoteAppTypes, CloudTypes ] + @classmethod + def grouped_choices(cls): + grouped_types= [ + (Category.HOST.value, HostTypes.choices), + (Category.NETWORK.value, NetworkTypes.choices), + (Category.DATABASE.value, DatabaseTypes.choices), + (Category.REMOTE_APP.value, RemoteAppTypes.choices), + (Category.CLOUD.value, CloudTypes.choices), + ] + return grouped_types + + @classmethod + def grouped_choices_to_objs(cls): + choices = cls.serialize_to_objs(Category.choices) + mapper = dict(cls.grouped_choices()) + for choice in choices: + children = cls.serialize_to_objs(mapper[choice['value']]) + choice['children'] = children + return choices + + @staticmethod + def serialize_to_objs(choices): + title = ['value', 'display_name'] + return [dict(zip(title, choice)) for choice in choices] + + class Protocol(models.TextChoices): ssh = 'ssh', 'SSH' diff --git a/apps/assets/migrations/0099_auto_20220426_1558.py b/apps/assets/migrations/0099_auto_20220426_1558.py index d073bfaa6..69ee76277 100644 --- a/apps/assets/migrations/0099_auto_20220426_1558.py +++ b/apps/assets/migrations/0099_auto_20220426_1558.py @@ -101,6 +101,7 @@ def migrate_remote_app_to_asset(apps, *args): print("Create remote app: {}".format(app.name)) remote_app = remote_app_model( id=app.id, hostname=app.name, ip='', + protocols='', category='remote_app', type=tp, platform=platforms_map[tp], org_id=app.org_id, @@ -130,6 +131,7 @@ def migrate_cloud_to_asset(apps, *args): cloud = cloud_model( id=app.id, hostname=app.name, ip='', category='remote_app', type='k8s', + protocols='', platform=platform, org_id=app.org_id, cluster=attrs.get('cluster', '') diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py index 0a8cfd265..b20348c14 100644 --- a/apps/assets/serializers/platform.py +++ b/apps/assets/serializers/platform.py @@ -3,6 +3,7 @@ from django.core.validators import RegexValidator from django.utils.translation import gettext_lazy as _ from assets.models import Platform +from assets.const import AllTypes __all__ = ['PlatformSerializer'] @@ -11,6 +12,7 @@ class PlatformSerializer(serializers.ModelSerializer): category_display = serializers.ReadOnlyField(source='get_category_display', label=_("Category display")) type_display = serializers.ReadOnlyField(source='get_type_display', label=_("Type display")) meta = serializers.DictField(required=False, allow_null=True, label=_('Meta')) + type = serializers.ChoiceField(choices=AllTypes.grouped_choices(), label=_("Type")) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/apps/common/drf/serializers.py b/apps/common/drf/serializers.py index 4beb59fe7..94ba9a238 100644 --- a/apps/common/drf/serializers.py +++ b/apps/common/drf/serializers.py @@ -3,10 +3,11 @@ from rest_framework import serializers from rest_framework.serializers import Serializer from rest_framework.serializers import ModelSerializer from rest_framework_bulk.serializers import BulkListSerializer - -from common.mixins import BulkListSerializerMixin +from django.utils.translation import gettext_lazy as _ from django.utils.functional import cached_property from rest_framework.utils.serializer_helpers import BindingDict + +from common.mixins import BulkListSerializerMixin from common.mixins.serializers import BulkSerializerMixin __all__ = [ @@ -83,3 +84,11 @@ class CeleryTaskSerializer(serializers.Serializer): task = serializers.CharField(read_only=True) +class ChoiceSerializer(serializers.Serializer): + display_name = serializers.CharField(label=_("Display name")) + value = serializers.CharField(label=_("Value")) + + +class GroupedChoiceSerailizer(ChoiceSerializer): + children = ChoiceSerializer(many=True, label=_("Children")) + diff --git a/apps/common/fields/model.py b/apps/common/fields/model.py index 4a4f3525d..3b9622411 100644 --- a/apps/common/fields/model.py +++ b/apps/common/fields/model.py @@ -143,7 +143,6 @@ class EncryptMixin: value = sp.get_prep_value(value) value = force_text(value) # 替换新的加密方式 - return crypto.encrypt(value) class EncryptTextField(EncryptMixin, models.TextField):