diff --git a/apps/audits/api.py b/apps/audits/api.py index c83517afd..6932d07ea 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -7,12 +7,14 @@ from __future__ import absolute_import, unicode_literals from rest_framework import generics, viewsets from rest_framework_bulk import BulkModelViewSet -from audits.backends import command_store +from audits.backends import command_store, record_store from audits.backends.command.serializers import CommandLogSerializer +from audits.backends.record.serializers import RecordSerializer from . import models, serializers from .hands import IsSuperUserOrAppUser, IsAppUser +# Todo: 忘记当时为何不和ProxyLogViewSet复用了 class ProxyLogReceiveView(generics.CreateAPIView): queryset = models.ProxyLog.objects.all() serializer_class = serializers.ProxyLogSerializer @@ -38,9 +40,6 @@ class ProxyLogViewSet(viewsets.ModelViewSet): "date_start": "" } - some params we need generate: { - "log_file", "", # No use now, may be think more about monitor and record - } """ queryset = models.ProxyLog.objects.all() @@ -66,3 +65,34 @@ class CommandLogViewSet(BulkModelViewSet): serializer_class = CommandLogSerializer permission_classes = (IsSuperUserOrAppUser,) + +class RecordLogViewSet(BulkModelViewSet): + """接受app发送来的record log, 格式如下 + { + "proxy_log_id": 23, + "output": "d2hvbWFp", # base64.b64encode(s) + "timestamp": 1485238673.0 + } + """ + + serializer_class = RecordSerializer + permission_classes = (IsSuperUserOrAppUser,) + + def get_queryset(self): + filter_kwargs = {} + proxy_log_id = self.request.query_params.get('proxy_log_id') + data_from_ts = self.request.query_params.get('date_from_ts') + if proxy_log_id: + filter_kwargs['proxy_log_id'] = proxy_log_id + if data_from_ts: + filter_kwargs['date_from_ts'] = data_from_ts + if filter_kwargs: + return record_store.filter(**filter_kwargs) + else: + return record_store.all() + + + + + + diff --git a/apps/audits/backends/__init__.py b/apps/audits/backends/__init__.py index 432716414..5a2a38ec7 100644 --- a/apps/audits/backends/__init__.py +++ b/apps/audits/backends/__init__.py @@ -3,4 +3,8 @@ from django.conf import settings command_engine = import_module(settings.COMMAND_STORE_BACKEND) command_store = command_engine.CommandStore() +record_engine = import_module(settings.RECORD_STORE_BACKEND) +record_store = record_engine.RecordStore() from .command.serializers import CommandLogSerializer + + diff --git a/apps/audits/backends/command/base.py b/apps/audits/backends/command/base.py index e5bb696fa..54279f133 100644 --- a/apps/audits/backends/command/base.py +++ b/apps/audits/backends/command/base.py @@ -11,8 +11,8 @@ class CommandBase(object): pass @abc.abstractmethod - def filter(self, date_from=None, date_to=None, user='', - asset='', system_user='', command=''): + def filter(self, date_from_ts=None, date_to_ts=None, user='', + asset='', system_user='', command='', proxy_log_id=0): pass diff --git a/apps/audits/backends/command/db.py b/apps/audits/backends/command/db.py index 91d33c79d..26441e41f 100644 --- a/apps/audits/backends/command/db.py +++ b/apps/audits/backends/command/db.py @@ -17,7 +17,7 @@ class CommandStore(CommandBase): ) def filter(self, date_from_ts=None, date_to_ts=None, user='', - asset='', system_user='', command='', proxy_log_id=''): + asset='', system_user='', command='', proxy_log_id=0): filter_kwargs = {} if date_from_ts: diff --git a/apps/audits/backends/command/serializers.py b/apps/audits/backends/command/serializers.py index b7f5edc97..32da6bcea 100644 --- a/apps/audits/backends/command/serializers.py +++ b/apps/audits/backends/command/serializers.py @@ -12,10 +12,10 @@ class CommandLogSerializer(serializers.ModelSerializer): model = CommandLog fields = '__all__' - def save(self): + def create(self, validated_data): try: - output = self.validated_data['output'] - self.validated_data['output'] = base64.b64decode(output) + output = validated_data['output'] + validated_data['output'] = base64.b64decode(output) except IndexError: pass - return command_store.save(**dict(self.validated_data)) + return command_store.save(**dict(validated_data)) diff --git a/apps/audits/backends/record/__init__.py b/apps/audits/backends/record/__init__.py new file mode 100644 index 000000000..3e0d2fd0f --- /dev/null +++ b/apps/audits/backends/record/__init__.py @@ -0,0 +1,2 @@ +# ~*~ coding: utf-8 ~*~ + diff --git a/apps/audits/backends/record/base.py b/apps/audits/backends/record/base.py new file mode 100644 index 000000000..929937fc3 --- /dev/null +++ b/apps/audits/backends/record/base.py @@ -0,0 +1,17 @@ +# coding: utf-8 +import abc + + +class RecordBase(object): + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def save(self, proxy_log_id, output, timestamp): + pass + + @abc.abstractmethod + def filter(self, date_from_ts=None, proxy_log_id=None): + pass + + + diff --git a/apps/audits/backends/record/db.py b/apps/audits/backends/record/db.py new file mode 100644 index 000000000..e55211f65 --- /dev/null +++ b/apps/audits/backends/record/db.py @@ -0,0 +1,31 @@ +# ~*~ coding: utf-8 ~*~ + +from .base import RecordBase +from audits.models import RecordLog + + +class RecordStore(RecordBase): + model = RecordLog + queryset = [] + + def save(self, proxy_log_id, output, timestamp): + return self.model.objects.create( + proxy_log_id=proxy_log_id, output=output, timestamp=timestamp + ) + + def filter(self, date_from_ts=None, proxy_log_id=''): + filter_kwargs = {} + + if date_from_ts: + filter_kwargs['timestamp__gte'] = date_from_ts + if proxy_log_id: + filter_kwargs['proxy_log_id'] = proxy_log_id + + if filter_kwargs: + self.queryset = self.model.objects.filter(**filter_kwargs) + return self.queryset + + def all(self): + """返回所有数据""" + return self.model.objects.all() + diff --git a/apps/audits/backends/record/serializers.py b/apps/audits/backends/record/serializers.py new file mode 100644 index 000000000..30a5867e1 --- /dev/null +++ b/apps/audits/backends/record/serializers.py @@ -0,0 +1,20 @@ +# ~*~ coding: utf-8 ~*~ +import base64 +from rest_framework import serializers +from audits.models import RecordLog +from audits.backends import record_store + + +class RecordSerializer(serializers.ModelSerializer): + """使用这个类作为基础Command Log Serializer类, 用来序列化""" + class Meta: + model = RecordLog + fields = '__all__' + + def create(self, validated_data): + try: + output = validated_data['output'] + validated_data['output'] = base64.b64decode(output) + except IndexError: + pass + return record_store.save(**dict(validated_data)) diff --git a/apps/audits/models.py b/apps/audits/models.py index 92687d76b..255c1dad5 100644 --- a/apps/audits/models.py +++ b/apps/audits/models.py @@ -46,7 +46,6 @@ class ProxyLog(models.Model): null=True, verbose_name=_('Login type')) terminal = models.CharField( max_length=32, blank=True, null=True, verbose_name=_('Terminal')) - log_file = models.CharField(max_length=1000, blank=True, null=True) is_failed = models.BooleanField( default=False, verbose_name=_('Did connect failed')) is_finished = models.BooleanField( @@ -64,14 +63,14 @@ class ProxyLog(models.Model): class CommandLog(models.Model): - proxy_log_id = models.IntegerField() + proxy_log_id = models.IntegerField(db_index=True) user = models.CharField(max_length=48, db_index=True) asset = models.CharField(max_length=128, db_index=True) system_user = models.CharField(max_length=48, db_index=True) command_no = models.IntegerField() command = models.CharField(max_length=1000, blank=True, db_index=True) output = models.TextField(blank=True) - timestamp = models.FloatField(null=True, db_index=True) + timestamp = models.FloatField(db_index=True) def __unicode__(self): return '%s: %s' % (self.id, self.command) @@ -81,9 +80,12 @@ class CommandLog(models.Model): class RecordLog(models.Model): - proxy_log_id = models.IntegerField() + proxy_log_id = models.IntegerField(db_index=True) output = models.TextField(verbose_name=_('Output')) - timestamp = models.FloatField(null=True) + timestamp = models.FloatField(db_index=True) def __unicode__(self): return 'Record: %s' % self.proxy_log_id + + class Meta: + ordering = ['timestamp'] diff --git a/apps/audits/urls/api_urls.py b/apps/audits/urls/api_urls.py index ca8ed9c19..7f1f19952 100644 --- a/apps/audits/urls/api_urls.py +++ b/apps/audits/urls/api_urls.py @@ -8,6 +8,7 @@ app_name = 'audits' router = routers.DefaultRouter() router.register(r'v1/proxy-log', api.ProxyLogViewSet, 'proxy-log') router.register(r'v1/command-log', api.CommandLogViewSet, 'command-log') +router.register(r'v1/record-log', api.RecordLogViewSet, 'record-log') urlpatterns = [ url(r'^v1/proxy-log/receive/$', api.ProxyLogReceiveView.as_view(), diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 5f68ed231..c64bde50d 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -325,4 +325,4 @@ CAPTCHA_IMAGE_SIZE = (75, 33) CAPTCHA_FOREGROUND_COLOR = '#001100' COMMAND_STORE_BACKEND = 'audits.backends.command.db' - +RECORD_STORE_BACKEND = 'audits.backends.record.db'