From 108ccf5a8b383eb190e5a4d86f3d9ab51f2b851f Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Mon, 19 Sep 2022 17:00:03 +0800 Subject: [PATCH 1/2] =?UTF-8?q?perf:=20=E8=B4=A6=E5=8F=B7=E7=AE=A1?= =?UTF-8?q?=E7=90=86api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/account/account.py | 36 +++------------------ apps/assets/api/account/history.py | 7 ++-- apps/assets/filters.py | 37 +++++++++++++++++++--- apps/assets/serializers/account/account.py | 29 +++++++++-------- apps/assets/tasks/account_connectivity.py | 4 +-- apps/rbac/const.py | 8 ++--- apps/rbac/tree.py | 2 +- 7 files changed, 62 insertions(+), 61 deletions(-) diff --git a/apps/assets/api/account/account.py b/apps/assets/api/account/account.py index 25a465e1d..5113d104b 100644 --- a/apps/assets/api/account/account.py +++ b/apps/assets/api/account/account.py @@ -1,45 +1,19 @@ -from django_filters import rest_framework as filters from rest_framework.decorators import action from rest_framework.response import Response from rest_framework.generics import CreateAPIView from orgs.mixins.api import OrgBulkModelViewSet from rbac.permissions import RBACPermission -from common.drf.filters import BaseFilterSet, UUIDInFilter + from common.mixins import RecordViewLogMixin from common.permissions import UserConfirmation from authentication.const import ConfirmType +from assets.models import Account +from assets.filters import AccountFilterSet from assets.tasks.account_connectivity import test_accounts_connectivity_manual -from assets.models import Account, Node from assets import serializers -__all__ = ['AccountFilterSet', 'AccountViewSet', 'AccountSecretsViewSet', 'AccountTaskCreateAPI'] - - -class AccountFilterSet(BaseFilterSet): - ip = filters.CharFilter(field_name='ip', lookup_expr='exact') - hostname = filters.CharFilter(field_name='name', lookup_expr='exact') - username = filters.CharFilter(field_name="username", lookup_expr='exact') - assets = UUIDInFilter(field_name='asset_id', lookup_expr='in') - nodes = UUIDInFilter(method='filter_nodes') - - def filter_nodes(self, queryset, name, value): - nodes = Node.objects.filter(id__in=value) - if not nodes: - return queryset - - node_qs = Node.objects.none() - for node in nodes: - node_qs |= node.get_all_children(with_self=True) - node_ids = list(node_qs.values_list('id', flat=True)) - queryset = queryset.filter(asset__nodes__in=node_ids) - return queryset - - class Meta: - model = Account - fields = [ - 'asset', 'id' - ] +__all__ = ['AccountViewSet', 'AccountSecretsViewSet', 'AccountTaskCreateAPI'] class AccountViewSet(OrgBulkModelViewSet): @@ -52,7 +26,7 @@ class AccountViewSet(OrgBulkModelViewSet): 'verify': serializers.AssetTaskSerializer } rbac_perms = { - 'verify': 'assets.test_authbook', + 'verify': 'assets.test_account', 'partial_update': 'assets.change_assetaccountsecret', } diff --git a/apps/assets/api/account/history.py b/apps/assets/api/account/history.py index 0db682177..0ddc659ad 100644 --- a/apps/assets/api/account/history.py +++ b/apps/assets/api/account/history.py @@ -1,9 +1,8 @@ -from .account import ( - AccountFilterSet, AccountViewSet, AccountSecretsViewSet -) -from common.mixins import RecordViewLogMixin from assets import serializers from assets.models import Account +from assets.filters import AccountFilterSet +from common.mixins import RecordViewLogMixin +from .account import AccountViewSet, AccountSecretsViewSet __all__ = ['AccountHistoryViewSet', 'AccountHistorySecretsViewSet'] diff --git a/apps/assets/filters.py b/apps/assets/filters.py index dd8bf80a4..fc75b16a8 100644 --- a/apps/assets/filters.py +++ b/apps/assets/filters.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- # - -from rest_framework.compat import coreapi, coreschema -from rest_framework import filters from django.db.models import Q +from rest_framework import filters +from rest_framework.compat import coreapi, coreschema -from .models import Label +from common.drf.filters import BaseFilterSet, UUIDInFilter from assets.utils import is_query_node_all_assets, get_node_from_request +from .models import Label, Node, Account class AssetByNodeFilterBackend(filters.BaseFilterBackend): @@ -109,7 +109,7 @@ class LabelFilterBackend(filters.BaseFilterBackend): q = Q(name=key, value=value) if not q: return [] - labels = Label.objects.filter(q, is_active=True)\ + labels = Label.objects.filter(q, is_active=True) \ .values_list('id', flat=True) return labels @@ -154,3 +154,30 @@ class IpInFilterBackend(filters.BaseFilterBackend): ) ) ] + + +class AccountFilterSet(BaseFilterSet): + from django_filters import rest_framework as filters + ip = filters.CharFilter(field_name='ip', lookup_expr='exact') + hostname = filters.CharFilter(field_name='name', lookup_expr='exact') + username = filters.CharFilter(field_name="username", lookup_expr='exact') + assets = UUIDInFilter(field_name='asset_id', lookup_expr='in') + nodes = UUIDInFilter(method='filter_nodes') + + def filter_nodes(self, queryset, name, value): + nodes = Node.objects.filter(id__in=value) + if not nodes: + return queryset + + node_qs = Node.objects.none() + for node in nodes: + node_qs |= node.get_all_children(with_self=True) + node_ids = list(node_qs.values_list('id', flat=True)) + queryset = queryset.filter(asset__nodes__in=node_ids) + return queryset + + class Meta: + model = Account + fields = [ + 'asset', 'id' + ] diff --git a/apps/assets/serializers/account/account.py b/apps/assets/serializers/account/account.py index 4ddcc1d49..8adca0a35 100644 --- a/apps/assets/serializers/account/account.py +++ b/apps/assets/serializers/account/account.py @@ -1,4 +1,3 @@ -from django.db.models import F from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers @@ -21,20 +20,20 @@ class AccountSerializerCreateMixin(serializers.ModelSerializer): @staticmethod def validate_template(value): - AccountTemplate.objects.get_or_create() - model = AccountTemplate try: - return model.objects.get(id=value) + return AccountTemplate.objects.get(id=value) except AccountTemplate.DoesNotExist: raise serializers.ValidationError(_('Account template not found')) @staticmethod def replace_attrs(account_template: AccountTemplate, attrs: dict): exclude_fields = [ - '_state', 'org_id', 'date_verified', 'id', - 'date_created', 'date_updated', 'created_by' + '_state', 'org_id', 'id', 'date_created', 'date_updated' ] - template_attrs = {k: v for k, v in account_template.__dict__.items() if k not in exclude_fields} + template_attrs = { + k: v for k, v in account_template.__dict__.items() + if k not in exclude_fields + } for k, v in template_attrs.items(): attrs.setdefault(k, v) @@ -48,17 +47,19 @@ class AccountSerializerCreateMixin(serializers.ModelSerializer): def create(self, validated_data): instance = super().create(validated_data) if self.push_now: - print("Start push account to asset") # Todo: push it - pass + print("Start push account to asset") return instance -class AccountSerializer(AuthValidateMixin, - AccountSerializerCreateMixin, - AccountFieldsSerializerMixin, - BulkOrgResourceModelSerializer): - asset = ObjectRelatedField(required=False, queryset=Asset.objects, label=_('Asset'), attrs=('id', 'name', 'ip')) +class AccountSerializer( + AuthValidateMixin, AccountSerializerCreateMixin, + AccountFieldsSerializerMixin, BulkOrgResourceModelSerializer +): + asset = ObjectRelatedField( + required=False, queryset=Asset.objects, + label=_('Asset'), attrs=('id', 'name', 'ip') + ) platform = serializers.ReadOnlyField(label=_("Platform")) class Meta(AccountFieldsSerializerMixin.Meta): diff --git a/apps/assets/tasks/account_connectivity.py b/apps/assets/tasks/account_connectivity.py index cec4ed3af..c28f93110 100644 --- a/apps/assets/tasks/account_connectivity.py +++ b/apps/assets/tasks/account_connectivity.py @@ -74,7 +74,7 @@ def test_user_connectivity(task_name, asset, username, password=None, private_ke @org_aware_func("account") def test_account_connectivity_util(account, task_name): """ - :param account: 对象 + :param account: 对象 :param task_name: :return: """ @@ -101,7 +101,7 @@ def test_account_connectivity_util(account, task_name): @shared_task(queue="ansible") def test_accounts_connectivity_manual(accounts): """ - :param accounts: 对象 + :param accounts: 对象 """ for account in accounts: task_name = gettext_noop("Test account connectivity: ") + str(account) diff --git a/apps/rbac/const.py b/apps/rbac/const.py index f8789a110..037358be0 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -35,14 +35,14 @@ exclude_permissions = ( ('assets', 'assetgroup', '*', '*'), ('assets', 'cluster', '*', '*'), ('assets', 'favoriteasset', '*', '*'), - ('assets', 'historicalauthbook', '*', '*'), + ('assets', 'historicalaccount', '*', '*'), ('assets', 'assetuser', '*', '*'), ('assets', 'gathereduser', 'add,delete,change', 'gathereduser'), ('assets', 'accountbackupplanexecution', 'delete,change', 'accountbackupplanexecution'), - ('assets', 'authbook', 'change', 'authbook'), + ('assets', 'account', 'change', 'account'), # TODO 暂时去掉历史账号的权限 - ('assets', 'authbook', '*', 'assethistoryaccount'), - ('assets', 'authbook', '*', 'assethistoryaccountsecret'), + ('assets', 'account', '*', 'assethistoryaccount'), + ('assets', 'account', '*', 'assethistoryaccountsecret'), ('perms', 'userassetgrantedtreenoderelation', '*', '*'), ('perms', 'usergrantedmappingnode', '*', '*'), diff --git a/apps/rbac/tree.py b/apps/rbac/tree.py index 0b08c565d..abce5759a 100644 --- a/apps/rbac/tree.py +++ b/apps/rbac/tree.py @@ -61,7 +61,7 @@ extra_nodes_data = [ # 将 model 放到其它节点下,而不是本来的 app 中 special_pid_mapper = { 'common.permission': 'view_other', - "assets.authbook": "accounts", + "assets.account": "accounts", "applications.account": "accounts", 'xpack.account': 'cloud_import', 'xpack.syncinstancedetail': 'cloud_import', From 7b4c2ce97eb0c0cb1fcad5787f6916a83e10f29b Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Mon, 19 Sep 2022 19:04:57 +0800 Subject: [PATCH 2/2] perf: xpack problem --- apps/common/utils/common.py | 1 - apps/jumpserver/settings/_xpack.py | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/common/utils/common.py b/apps/common/utils/common.py index ed45417b7..6f1e34b0a 100644 --- a/apps/common/utils/common.py +++ b/apps/common/utils/common.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- # import re -import socket from django.templatetags.static import static from collections import OrderedDict from itertools import chain diff --git a/apps/jumpserver/settings/_xpack.py b/apps/jumpserver/settings/_xpack.py index 2650e30b9..9f4319a35 100644 --- a/apps/jumpserver/settings/_xpack.py +++ b/apps/jumpserver/settings/_xpack.py @@ -6,8 +6,7 @@ from .. import const from .base import INSTALLED_APPS, TEMPLATES XPACK_DIR = os.path.join(const.BASE_DIR, 'xpack') -# XPACK_ENABLED = os.path.isdir(XPACK_DIR) -XPACK_ENABLED = False +XPACK_ENABLED = os.path.isdir(XPACK_DIR) XPACK_TEMPLATES_DIR = [] XPACK_CONTEXT_PROCESSOR = []