提交 b7021b5e 编写于 作者: baltery's avatar baltery

[Update] 支持收集资产上的用户

上级 5464c884
......@@ -36,6 +36,7 @@ class AssetViewSet(OrgBulkModelViewSet):
serializer_class = serializers.AssetSerializer
permission_classes = (IsOrgAdminOrAppUser,)
extra_filter_backends = [AssetByNodeFilterBackend, LabelFilterBackend]
custom_filter_fields = ['admin_user_id']
def set_assets_node(self, assets):
if not isinstance(assets, list):
......
......@@ -6,6 +6,7 @@ from assets.models import GatheredUser
from common.permissions import IsOrgAdmin
from ..serializers import GatheredUserSerializer
from ..filters import AssetRelatedByNodeFilterBackend
__all__ = ['GatheredUserViewSet']
......@@ -15,6 +16,7 @@ class GatheredUserViewSet(OrgModelViewSet):
queryset = GatheredUser.objects.all()
serializer_class = GatheredUserSerializer
permission_classes = [IsOrgAdmin]
extra_filter_backends = [AssetRelatedByNodeFilterBackend]
filter_fields = ['asset', 'username', 'present']
search_fields = ['username', 'asset__ip', 'asset__hostname']
......
......@@ -12,63 +12,54 @@ from .models import Node, Label
class AssetByNodeFilterBackend(filters.BaseFilterBackend):
fields = ['node', 'all']
# def filter_node(self, queryset):
# node_id = self.request.query_params.get("node_id")
# if not node_id:
# return queryset
#
# node = get_object_or_404(Node, id=node_id)
# show_current_asset = self.request.query_params.get("show_current_asset") in ('1', 'true')
#
# # 当前节点是顶层节点, 并且仅显示直接资产
# if node.is_org_root() and show_current_asset:
# queryset = queryset.filter(
# Q(nodes=node_id) | Q(nodes__isnull=True)
# ).distinct()
# # 当前节点是顶层节点,显示所有资产
# elif node.is_org_root() and not show_current_asset:
# return queryset
# # 当前节点不是鼎城节点,只显示直接资产
# elif not node.is_org_root() and show_current_asset:
# queryset = queryset.filter(nodes=node)
# else:
# children = node.get_all_children(with_self=True)
# queryset = queryset.filter(nodes__in=children).distinct()
# return queryset
def get_schema_fields(self, view):
return [
coreapi.Field(
name=field, location='query', required=False,
type='string', example='', description=''
type='string', example='', description='', schema=None,
)
for field in self.fields
]
def filter_queryset(self, request, queryset, view):
node_id = dict_get_any(request.query_params, ['node', 'node_id'])
if not node_id:
return queryset
@staticmethod
def is_query_all(request):
query_all_arg = request.query_params.get('all')
show_current_asset_arg = request.query_params.get('show_current_asset')
query_all = query_all_arg == '1'
if show_current_asset_arg is not None:
query_all = show_current_asset_arg != '1'
return query_all
@staticmethod
def get_query_node(request):
node_id = dict_get_any(request.query_params, ['node', 'node_id'])
if not node_id:
return None, False
if is_uuid(node_id):
node = get_object_or_none(Node, id=node_id)
else:
node = get_object_or_none(Node, key=node_id)
return node, True
if not node:
return queryset.none()
@staticmethod
def perform_query(pattern, queryset):
return queryset.filter(nodes__key__regex=pattern)
def filter_queryset(self, request, queryset, view):
node, has_query_arg = self.get_query_node(request)
if not has_query_arg:
return queryset
if node is None:
return queryset.none()
query_all = self.is_query_all(request)
if query_all:
pattern = node.get_all_children_pattern(with_self=True)
else:
pattern = node.get_children_key_pattern(with_self=True)
return queryset.filter(nodes__key__regex=pattern)
return self.perform_query(pattern, queryset)
class LabelFilterBackend(filters.BaseFilterBackend):
......@@ -117,3 +108,8 @@ class LabelFilterBackend(filters.BaseFilterBackend):
return queryset
class AssetRelatedByNodeFilterBackend(AssetByNodeFilterBackend):
@staticmethod
def perform_query(pattern, queryset):
return queryset.filter(asset__nodes__key__regex=pattern).distinct()
......@@ -18,10 +18,10 @@ class Migration(migrations.Migration):
('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('username', models.CharField(blank=True, db_index=True, max_length=32, verbose_name='Username')),
('present', models.BooleanField(default=True)),
('present', models.BooleanField(default=True, verbose_name='Present')),
('date_created', models.DateTimeField(auto_now_add=True, verbose_name='Date created')),
('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
('asset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='assets.Asset')),
('asset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='assets.Asset', verbose_name='Asset')),
],
options={'ordering': ['asset'], 'verbose_name': 'GatherUser'},
),
......
......@@ -11,10 +11,10 @@ __all__ = ['GatheredUser']
class GatheredUser(OrgModelMixin):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE)
asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_("Asset"))
username = models.CharField(max_length=32, blank=True, db_index=True,
verbose_name=_('Username'))
present = models.BooleanField(default=True)
present = models.BooleanField(default=True, verbose_name=_("Present"))
date_created = models.DateTimeField(auto_now_add=True,
verbose_name=_("Date created"))
date_updated = models.DateTimeField(auto_now=True,
......
# -*- coding: utf-8 -*-
#
from ..models import GatheredUser
from django.utils.translation import ugettext_lazy as _
from orgs.mixins.serializers import OrgResourceModelSerializerMixin
from ..models import GatheredUser
class GatheredUserSerializer(OrgResourceModelSerializerMixin):
......@@ -14,3 +15,7 @@ class GatheredUserSerializer(OrgResourceModelSerializerMixin):
'present', 'date_created', 'date_updated'
]
read_only_fields = fields
labels = {
'hostname': _("Hostname"),
'ip': "IP"
}
......@@ -116,8 +116,9 @@ def gather_asset_users(assets, task_name=None):
for k, value in hosts_category.items():
if not value['hosts']:
continue
_task_name = '{}: {}'.format(task_name, k)
task, created = update_or_create_ansible_task(
task_name=task_name, hosts=value['hosts'], tasks=value['tasks'],
task_name=_task_name, hosts=value['hosts'], tasks=value['tasks'],
pattern='all', options=const.TASK_OPTIONS,
run_as_admin=True, created_by=value['hosts'][0].org_id,
)
......
......@@ -70,7 +70,6 @@ class IDSpmFilter(filters.BaseFilterBackend):
class CustomFilter(filters.BaseFilterBackend):
custom_filter_fields = [] # ["node", "asset"]
def get_schema_fields(self, view):
fields = []
......@@ -79,7 +78,10 @@ class CustomFilter(filters.BaseFilterBackend):
type='string', example='',
description=''
)
for field in self.custom_filter_fields:
if not hasattr(view, 'custom_filter_fields'):
return []
for field in view.custom_filter_fields:
if isinstance(field, str):
defaults['name'] = field
elif isinstance(field, dict):
......
......@@ -218,28 +218,32 @@ class AdHoc(models.Model):
hid = str(uuid.uuid4())
history = AdHocRunHistory(id=hid, adhoc=self, task=self.task)
time_start = time.time()
date_start = timezone.now()
is_success = False
try:
date_start = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
history.date_start = timezone.now()
print(_("{} Start task: {}").format(date_start, self.task.name))
date_start_s = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(_("{} Start task: {}").format(date_start_s, self.task.name))
raw, summary = self._run_only()
date_end = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(_("{} Task finish").format(date_end))
history.is_finished = True
if summary.get('dark'):
history.is_success = False
else:
history.is_success = True
history.result = raw
history.summary = summary
is_success = summary.get('success', False)
return raw, summary
except Exception as e:
logger.error(e, exc_info=True)
return {}, {"dark": {"all": str(e)}, "contacted": []}
summary = {}
raw = {"dark": {"all": str(e)}, "contacted": []}
return raw, summary
finally:
history.date_finished = timezone.now()
history.timedelta = time.time() - time_start
history.save()
date_end = timezone.now()
date_end_s = date_end.strftime('%Y-%m-%d %H:%M:%S')
print(_("{} Task finish").format(date_end_s))
print('.\n\n.')
AdHocRunHistory.objects.filter(id=history.id).update(
date_start=date_start,
is_finished=True,
is_success=is_success,
date_finished=timezone.now(),
timedelta=time.time() - time_start
)
def _run_only(self):
runner = AdHocRunner(self.inventory, options=self.options)
......
......@@ -20,12 +20,7 @@ class RootOrgViewMixin:
return super().dispatch(request, *args, **kwargs)
class OrgModelViewSet(CommonApiMixin, ModelViewSet):
def get_queryset(self):
return super().get_queryset().all()
class OrgBulkModelViewSet(CommonApiMixin, BulkModelViewSet):
class OrgQuerySetMixin:
def get_queryset(self):
queryset = super().get_queryset().all()
if hasattr(self, 'swagger_fake_view'):
......@@ -36,6 +31,12 @@ class OrgBulkModelViewSet(CommonApiMixin, BulkModelViewSet):
queryset = self.serializer_class.setup_eager_loading(queryset)
return queryset
class OrgModelViewSet(CommonApiMixin, OrgQuerySetMixin, ModelViewSet):
pass
class OrgBulkModelViewSet(CommonApiMixin, OrgQuerySetMixin, BulkModelViewSet):
def allow_bulk_destroy(self, qs, filtered):
if qs.count() <= filtered.count():
return False
......
......@@ -7,7 +7,7 @@ from common.tree import TreeNodeSerializer
class UserAssetPermissionMixin(UserPermissionMixin):
util = AssetPermissionUtilV2(None)
util = None
tree = None
def initial(self, *args, **kwargs):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册