perf: 账号管理api

pull/8931/head
feng626 2022-09-19 17:00:03 +08:00
parent 389094f615
commit 108ccf5a8b
7 changed files with 62 additions and 61 deletions

View File

@ -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',
}

View File

@ -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']

View File

@ -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):
@ -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'
]

View File

@ -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):

View File

@ -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: <AuthBook>对象
:param account: <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: <AuthBook>对象
:param accounts: <Account>对象
"""
for account in accounts:
task_name = gettext_noop("Test account connectivity: ") + str(account)

View File

@ -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', '*', '*'),

View File

@ -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',