From 541358978d1e66449b1577996fae6dc468181fdd Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 2 Dec 2022 11:45:05 +0800 Subject: [PATCH] fix: gateway (#9145) Co-authored-by: feng <1304903146@qq.com> --- apps/assets/api/domain.py | 5 +- apps/assets/serializers/domain.py | 108 ++---------------------------- 2 files changed, 9 insertions(+), 104 deletions(-) diff --git a/apps/assets/api/domain.py b/apps/assets/api/domain.py index 948bb6a7b..954f4842c 100644 --- a/apps/assets/api/domain.py +++ b/apps/assets/api/domain.py @@ -1,5 +1,4 @@ # ~*~ coding: utf-8 ~*~ -from django.db.models import F from django.views.generic.detail import SingleObjectMixin from django.utils.translation import ugettext as _ from rest_framework.views import APIView, Response @@ -7,7 +6,7 @@ from rest_framework.serializers import ValidationError from common.utils import get_logger from orgs.mixins.api import OrgBulkModelViewSet -from ..models import Domain, Host +from ..models import Domain, Gateway from .. import serializers logger = get_logger(__file__) @@ -29,7 +28,7 @@ class DomainViewSet(OrgBulkModelViewSet): class GatewayViewSet(OrgBulkModelViewSet): - perm_model = Host + perm_model = Gateway filterset_fields = ("domain__name", "name", "domain") search_fields = ("domain__name",) serializer_class = serializers.GatewaySerializer diff --git a/apps/assets/serializers/domain.py b/apps/assets/serializers/domain.py index f17aa19ee..8ee651e88 100644 --- a/apps/assets/serializers/domain.py +++ b/apps/assets/serializers/domain.py @@ -1,16 +1,13 @@ # -*- coding: utf-8 -*- # from rest_framework import serializers -from rest_framework.generics import get_object_or_404 from django.utils.translation import ugettext_lazy as _ from orgs.mixins.serializers import BulkOrgResourceModelSerializer -from common.drf.serializers import SecretReadableMixin, WritableNestedModelSerializer -from common.drf.fields import ObjectRelatedField, EncryptedField -from assets.const import SecretType, GATEWAY_NAME -from ..serializers import AssetProtocolsSerializer -from ..models import Platform, Domain, Node, Asset, Account, Host -from .utils import validate_password_for_ansible, validate_ssh_key +from common.drf.serializers import SecretReadableMixin +from common.drf.fields import ObjectRelatedField +from ..serializers import HostSerializer +from ..models import Domain, Gateway, Asset class DomainSerializer(BulkOrgResourceModelSerializer): @@ -41,100 +38,9 @@ class DomainSerializer(BulkOrgResourceModelSerializer): return obj.gateways.count() -class GatewaySerializer(BulkOrgResourceModelSerializer, WritableNestedModelSerializer): - password = EncryptedField( - label=_('Password'), required=False, allow_blank=True, allow_null=True, max_length=1024, - validators=[validate_password_for_ansible], write_only=True - ) - private_key = EncryptedField( - label=_('SSH private key'), required=False, allow_blank=True, allow_null=True, - max_length=16384, write_only=True - ) - passphrase = serializers.CharField( - label=_('Key password'), allow_blank=True, allow_null=True, required=False, write_only=True, - max_length=512, - ) - username = serializers.CharField( - label=_('Username'), allow_blank=True, max_length=128, required=True, write_only=True - ) - username_display = serializers.SerializerMethodField(label=_('Username')) - protocols = AssetProtocolsSerializer(many=True, required=False, label=_('Protocols')) - - class Meta: - model = Host - fields_mini = ['id', 'name', 'address'] - fields_small = fields_mini + ['is_active', 'comment'] - fields = fields_small + ['domain', 'protocols'] + [ - 'username', 'password', 'private_key', 'passphrase', 'username_display' - ] - extra_kwargs = { - 'name': {'label': _("Name")}, - 'address': {'label': _('Address')}, - } - - @staticmethod - def get_username_display(obj): - account = obj.accounts.order_by('-privileged').first() - return account.username if account else '' - - def validate_private_key(self, secret): - if not secret: - return - passphrase = self.initial_data.get('passphrase') - passphrase = passphrase if passphrase else None - validate_ssh_key(secret, passphrase) - return secret - - @staticmethod - def clean_auth_fields(validated_data): - username = validated_data.pop('username', None) - password = validated_data.pop('password', None) - private_key = validated_data.pop('private_key', None) - validated_data.pop('passphrase', None) - return username, password, private_key - - @staticmethod - def create_accounts(instance, username, password, private_key): - account_name = f'{instance.name}-{_("Gateway")}' - account_data = { - 'privileged': True, - 'name': account_name, - 'username': username, - 'asset_id': instance.id, - 'created_by': instance.created_by - } - if password: - Account.objects.create( - **account_data, secret=password, secret_type=SecretType.PASSWORD - ) - if private_key: - Account.objects.create( - **account_data, secret=private_key, secret_type=SecretType.SSH_KEY - ) - - @staticmethod - def update_accounts(instance, username, password, private_key): - accounts = instance.accounts.filter(username=username) - if password: - account = get_object_or_404(accounts, SecretType.PASSWORD) - account.secret = password - account.save() - if private_key: - account = get_object_or_404(accounts, SecretType.SSH_KEY) - account.secret = private_key - account.save() - - def create(self, validated_data): - auth_fields = self.clean_auth_fields(validated_data) - instance = super().create(validated_data) - self.create_accounts(instance, *auth_fields) - return instance - - def update(self, instance, validated_data): - auth_fields = self.clean_auth_fields(validated_data) - instance = super().update(instance, validated_data) - self.update_accounts(instance, *auth_fields) - return instance +class GatewaySerializer(HostSerializer): + class Meta(HostSerializer.Meta): + model = Gateway class GatewayWithAuthSerializer(SecretReadableMixin, GatewaySerializer):