mirror of https://github.com/jumpserver/jumpserver
parent
92a198c00b
commit
e82eb8f3d1
|
@ -2,34 +2,29 @@
|
|||
#
|
||||
from importlib import import_module
|
||||
|
||||
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin
|
||||
from django.db.models import F, Value
|
||||
from django.db.models.functions import Concat
|
||||
from django.conf import settings
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework import generics
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin
|
||||
|
||||
from common.drf.api import JMSReadOnlyModelViewSet
|
||||
from common.plugins.es import QuerySet as ESQuerySet
|
||||
from common.drf.filters import DatetimeRangeFilter
|
||||
from common.api import CommonGenericViewSet
|
||||
from ops.models.job import JobAuditLog
|
||||
from orgs.mixins.api import OrgGenericViewSet, OrgBulkModelViewSet
|
||||
from common.api import CommonGenericViewSet
|
||||
from common.drf.filters import DatetimeRangeFilter
|
||||
from common.plugins.es import QuerySet as ESQuerySet
|
||||
from orgs.utils import current_org
|
||||
from orgs.mixins.api import OrgGenericViewSet, OrgBulkModelViewSet
|
||||
from .backends import TYPE_ENGINE_MAPPING
|
||||
from .models import FTPLog, UserLoginLog, OperateLog, PasswordChangeLog
|
||||
from .serializers import FTPLogSerializer, UserLoginLogSerializer, JobAuditLogSerializer
|
||||
from .serializers import (
|
||||
OperateLogSerializer, OperateLogActionDetailSerializer,
|
||||
PasswordChangeLogSerializer
|
||||
OperateLogSerializer, OperateLogActionDetailSerializer, PasswordChangeLogSerializer
|
||||
)
|
||||
|
||||
|
||||
class JobAuditViewSet(OrgBulkModelViewSet):
|
||||
serializer_class = JobAuditLogSerializer
|
||||
http_method_names = ('get', 'head', 'options',)
|
||||
permission_classes = ()
|
||||
model = JobAuditLog
|
||||
serializer_class = JobAuditLogSerializer
|
||||
http_method_names = ('get', 'head', 'options')
|
||||
|
||||
|
||||
class FTPLogViewSet(CreateModelMixin, ListModelMixin, OrgGenericViewSet):
|
||||
|
|
|
@ -16,6 +16,8 @@ from assets.const import AllTypes
|
|||
from terminal.models import Session, Command
|
||||
from terminal.utils import ComponentsPrometheusMetricsUtil
|
||||
from orgs.utils import current_org
|
||||
from ops.const import JobStatus
|
||||
from ops.models import Job, JobExecution
|
||||
from common.utils import lazyproperty
|
||||
from audits.models import UserLoginLog, PasswordChangeLog, OperateLog
|
||||
from audits.const import LoginStatusChoices
|
||||
|
@ -118,12 +120,26 @@ class DateTimeMixin:
|
|||
queryset = Command.objects.filter(timestamp__gte=t)
|
||||
return queryset
|
||||
|
||||
@lazyproperty
|
||||
def jobs_queryset(self):
|
||||
t = self.days_to_datetime
|
||||
queryset = Job.objects.filter(date_created__gte=t)
|
||||
return queryset
|
||||
|
||||
@lazyproperty
|
||||
def jobs_executed_queryset(self):
|
||||
t = self.days_to_datetime
|
||||
queryset = JobExecution.objects.filter(date_created__gte=t)
|
||||
return queryset
|
||||
|
||||
|
||||
class DatesLoginMetricMixin:
|
||||
dates_list: list
|
||||
command_queryset: Command.objects
|
||||
sessions_queryset: Session.objects
|
||||
ftp_logs_queryset: OperateLog.objects
|
||||
jobs_queryset: Job.objects
|
||||
jobs_executed_queryset: JobExecution.objects
|
||||
login_logs_queryset: UserLoginLog.objects
|
||||
operate_logs_queryset: OperateLog.objects
|
||||
password_change_logs_queryset: PasswordChangeLog.objects
|
||||
|
@ -299,6 +315,21 @@ class DatesLoginMetricMixin:
|
|||
def commands_danger_amount(self):
|
||||
return self.command_queryset.filter(risk_level=Command.RISK_LEVEL_DANGEROUS).count()
|
||||
|
||||
@lazyproperty
|
||||
def jobs_amount(self):
|
||||
return self.jobs_queryset.count()
|
||||
|
||||
@lazyproperty
|
||||
def jobs_unexecuted_amount(self):
|
||||
executed_amount = self.jobs_executed_queryset.values(
|
||||
'job_id').order_by('job_id').distinct().count()
|
||||
return self.jobs_amount - executed_amount
|
||||
|
||||
@lazyproperty
|
||||
def jobs_executed_failed_amount(self):
|
||||
return self.jobs_executed_queryset.objects.filter(
|
||||
status=JobStatus.failed).count()
|
||||
|
||||
@lazyproperty
|
||||
def sessions_amount(self):
|
||||
return self.sessions_queryset.count()
|
||||
|
@ -408,6 +439,21 @@ class IndexApi(DateTimeMixin, DatesLoginMetricMixin, APIView):
|
|||
'total_count_ftp_logs': self.ftp_logs_amount,
|
||||
})
|
||||
|
||||
if _all or query_params.get('total_count') or query_params.get('total_count_jobs'):
|
||||
data.update({
|
||||
'total_count_jobs': self.jobs_amount,
|
||||
})
|
||||
|
||||
if _all or query_params.get('total_count') or query_params.get('total_count_jobs_unexecuted'):
|
||||
data.update({
|
||||
'total_count_jobs_unexecuted': self.jobs_unexecuted_amount,
|
||||
})
|
||||
|
||||
if _all or query_params.get('total_count') or query_params.get('total_count_jobs_executed_failed'):
|
||||
data.update({
|
||||
'total_count_jobs_executed_failed': self.jobs_executed_failed_amount,
|
||||
})
|
||||
|
||||
if _all or query_params.get('total_count') or query_params.get('total_count_type_to_assets_amount'):
|
||||
data.update({
|
||||
'total_count_type_to_assets_amount': self.get_type_to_assets,
|
||||
|
|
|
@ -27,3 +27,25 @@ DEFAULT_PASSWORD_RULES = {
|
|||
'length': DEFAULT_PASSWORD_LENGTH,
|
||||
'symbol_set': string_punctuation
|
||||
}
|
||||
|
||||
|
||||
class Types(models.TextChoices):
|
||||
adhoc = 'adhoc', _('Adhoc')
|
||||
playbook = 'playbook', _('Playbook')
|
||||
|
||||
|
||||
class RunasPolicies(models.TextChoices):
|
||||
privileged_only = 'privileged_only', _('Privileged Only')
|
||||
privileged_first = 'privileged_first', _('Privileged First')
|
||||
skip = 'skip', _('Skip')
|
||||
|
||||
|
||||
class Modules(models.TextChoices):
|
||||
shell = 'shell', _('Shell')
|
||||
winshell = 'win_shell', _('Powershell')
|
||||
|
||||
|
||||
class JobStatus(models.TextChoices):
|
||||
running = 'running', _('Running')
|
||||
success = 'success', _('Success')
|
||||
failed = 'failed', _('Failed')
|
||||
|
|
|
@ -14,23 +14,11 @@ __all__ = ["Job", "JobExecution", "JobAuditLog"]
|
|||
from ops.ansible import JMSInventory, AdHocRunner, PlaybookRunner
|
||||
from ops.mixin import PeriodTaskModelMixin
|
||||
from ops.variables import *
|
||||
from ops.const import Types, Modules, RunasPolicies, JobStatus
|
||||
from orgs.mixins.models import JMSOrgBaseModel
|
||||
|
||||
|
||||
class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
|
||||
class Types(models.TextChoices):
|
||||
adhoc = 'adhoc', _('Adhoc')
|
||||
playbook = 'playbook', _('Playbook')
|
||||
|
||||
class RunasPolicies(models.TextChoices):
|
||||
privileged_only = 'privileged_only', _('Privileged Only')
|
||||
privileged_first = 'privileged_first', _('Privileged First')
|
||||
skip = 'skip', _('Skip')
|
||||
|
||||
class Modules(models.TextChoices):
|
||||
shell = 'shell', _('Shell')
|
||||
winshell = 'win_shell', _('Powershell')
|
||||
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
name = models.CharField(max_length=128, null=True, verbose_name=_('Name'))
|
||||
instant = models.BooleanField(default=False)
|
||||
|
@ -100,7 +88,7 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
|
|||
class JobExecution(JMSOrgBaseModel):
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
task_id = models.UUIDField(null=True)
|
||||
status = models.CharField(max_length=16, verbose_name=_('Status'), default='running')
|
||||
status = models.CharField(max_length=16, verbose_name=_('Status'), default=JobStatus.running)
|
||||
job = models.ForeignKey(Job, on_delete=models.CASCADE, related_name='executions', null=True)
|
||||
parameters = models.JSONField(default=dict, verbose_name=_('Parameters'))
|
||||
result = models.JSONField(blank=True, null=True, verbose_name=_('Result'))
|
||||
|
@ -226,11 +214,11 @@ class JobExecution(JMSOrgBaseModel):
|
|||
|
||||
@property
|
||||
def is_finished(self):
|
||||
return self.status in ['success', 'failed']
|
||||
return self.status in [JobStatus.success, JobStatus.failed]
|
||||
|
||||
@property
|
||||
def is_success(self):
|
||||
return self.status == 'success'
|
||||
return self.status == JobStatus.success
|
||||
|
||||
@property
|
||||
def inventory_path(self):
|
||||
|
@ -244,13 +232,13 @@ class JobExecution(JMSOrgBaseModel):
|
|||
|
||||
def set_error(self, error):
|
||||
this = self.__class__.objects.get(id=self.id) # 重新获取一次,避免数据库超时连接超时
|
||||
this.status = 'failed'
|
||||
this.status = JobStatus.failed
|
||||
this.summary.update({'error': str(error)})
|
||||
this.finish_task()
|
||||
|
||||
def set_result(self, cb):
|
||||
status_mapper = {
|
||||
'successful': 'success',
|
||||
'successful': JobStatus.success,
|
||||
}
|
||||
this = self.__class__.objects.get(id=self.id)
|
||||
this.status = status_mapper.get(cb.status, cb.status)
|
||||
|
|
Loading…
Reference in New Issue