mirror of https://github.com/jumpserver/jumpserver
Merge branch 'v3' of github.com:jumpserver/jumpserver into v3
commit
6d5be66b5e
|
@ -0,0 +1,28 @@
|
||||||
|
# Generated by Django 3.2.14 on 2022-11-18 06:31
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('ops', '0032_auto_20221117_1848'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='job',
|
||||||
|
name='crontab',
|
||||||
|
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Regularly perform'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='job',
|
||||||
|
name='interval',
|
||||||
|
field=models.IntegerField(blank=True, default=24, null=True, verbose_name='Cycle perform'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='job',
|
||||||
|
name='is_periodic',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
|
@ -9,14 +9,16 @@ from django.utils.translation import gettext_lazy as _
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from celery import current_task
|
from celery import current_task
|
||||||
|
|
||||||
|
from common.const.choices import Trigger
|
||||||
from common.db.models import BaseCreateUpdateModel
|
from common.db.models import BaseCreateUpdateModel
|
||||||
|
|
||||||
__all__ = ["Job", "JobExecution"]
|
__all__ = ["Job", "JobExecution"]
|
||||||
|
|
||||||
from ops.ansible import JMSInventory, AdHocRunner, PlaybookRunner
|
from ops.ansible import JMSInventory, AdHocRunner, PlaybookRunner
|
||||||
|
from ops.mixin import PeriodTaskModelMixin
|
||||||
|
|
||||||
|
|
||||||
class Job(BaseCreateUpdateModel):
|
class Job(BaseCreateUpdateModel, PeriodTaskModelMixin):
|
||||||
class Types(models.TextChoices):
|
class Types(models.TextChoices):
|
||||||
adhoc = 'adhoc', _('Adhoc')
|
adhoc = 'adhoc', _('Adhoc')
|
||||||
playbook = 'playbook', _('Playbook')
|
playbook = 'playbook', _('Playbook')
|
||||||
|
@ -48,6 +50,42 @@ class Job(BaseCreateUpdateModel):
|
||||||
parameters_define = models.JSONField(default=dict, verbose_name=_('Parameters define'))
|
parameters_define = models.JSONField(default=dict, verbose_name=_('Parameters define'))
|
||||||
comment = models.CharField(max_length=1024, default='', verbose_name=_('Comment'), null=True, blank=True)
|
comment = models.CharField(max_length=1024, default='', verbose_name=_('Comment'), null=True, blank=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def last_execution(self):
|
||||||
|
return self.executions.last()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def date_last_run(self):
|
||||||
|
return self.last_execution.date_created if self.last_execution else None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def summary(self):
|
||||||
|
summary = {
|
||||||
|
"total": 0,
|
||||||
|
"success": 0,
|
||||||
|
}
|
||||||
|
for execution in self.executions.all():
|
||||||
|
summary["total"] += 1
|
||||||
|
if execution.is_success:
|
||||||
|
summary["success"] += 1
|
||||||
|
return summary
|
||||||
|
|
||||||
|
@property
|
||||||
|
def average_time_cost(self):
|
||||||
|
total_cost = 0
|
||||||
|
finished_count = self.executions.filter(status__in=['success', 'failed']).count()
|
||||||
|
for execution in self.executions.filter(status__in=['success', 'failed']).all():
|
||||||
|
total_cost += execution.time_cost
|
||||||
|
return total_cost / finished_count if finished_count else 0
|
||||||
|
|
||||||
|
def get_register_task(self):
|
||||||
|
from ..tasks import run_ops_job
|
||||||
|
name = "run_ops_job_period_{}".format(str(self.id)[:8])
|
||||||
|
task = run_ops_job.name
|
||||||
|
args = (str(self.id),)
|
||||||
|
kwargs = {}
|
||||||
|
return name, task, args, kwargs
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def inventory(self):
|
def inventory(self):
|
||||||
return JMSInventory(self.assets.all(), self.runas_policy, self.runas)
|
return JMSInventory(self.assets.all(), self.runas_policy, self.runas)
|
||||||
|
@ -72,7 +110,10 @@ class JobExecution(BaseCreateUpdateModel):
|
||||||
def get_runner(self):
|
def get_runner(self):
|
||||||
inv = self.job.inventory
|
inv = self.job.inventory
|
||||||
inv.write_to_file(self.inventory_path)
|
inv.write_to_file(self.inventory_path)
|
||||||
extra_vars = json.loads(self.parameters)
|
if isinstance(self.parameters, str):
|
||||||
|
extra_vars = json.loads(self.parameters)
|
||||||
|
else:
|
||||||
|
extra_vars = {}
|
||||||
|
|
||||||
if self.job.type == 'adhoc':
|
if self.job.type == 'adhoc':
|
||||||
runner = AdHocRunner(
|
runner = AdHocRunner(
|
||||||
|
|
|
@ -2,24 +2,26 @@ from django.db import transaction
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from common.drf.fields import ReadableHiddenField
|
from common.drf.fields import ReadableHiddenField
|
||||||
|
from ops.mixin import PeriodTaskSerializerMixin
|
||||||
from ops.models import Job, JobExecution
|
from ops.models import Job, JobExecution
|
||||||
|
|
||||||
_all_ = []
|
_all_ = []
|
||||||
|
|
||||||
|
|
||||||
class JobSerializer(serializers.ModelSerializer):
|
class JobSerializer(serializers.ModelSerializer, PeriodTaskSerializerMixin):
|
||||||
owner = ReadableHiddenField(default=serializers.CurrentUserDefault())
|
owner = ReadableHiddenField(default=serializers.CurrentUserDefault())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Job
|
model = Job
|
||||||
fields = [
|
read_only_fields = ["id", "date_last_run", "date_created", "date_updated", "average_time_cost"]
|
||||||
"id", "name", "instant", "type", "module", "args", "playbook", "assets", "runas_policy", "runas", "owner",
|
fields = read_only_fields + [
|
||||||
|
"name", "instant", "type", "module", "args", "playbook", "assets", "runas_policy", "runas", "owner",
|
||||||
"parameters_define",
|
"parameters_define",
|
||||||
"timeout",
|
"timeout",
|
||||||
"chdir",
|
"chdir",
|
||||||
"comment",
|
"comment",
|
||||||
"date_created",
|
"summary",
|
||||||
"date_updated"
|
"is_periodic", "interval", "crontab"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
@shared_task(soft_time_limit=60, queue="ansible", verbose_name=_("Run ansible task"))
|
@shared_task(soft_time_limit=60, queue="ansible", verbose_name=_("Run ansible task"))
|
||||||
def run_ops_job(job_id, **kwargs):
|
def run_ops_job(job_id):
|
||||||
job = get_object_or_none(Job, id=job_id)
|
job = get_object_or_none(Job, id=job_id)
|
||||||
execution = job.create_execution()
|
execution = job.create_execution()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.14 on 2022-11-18 02:55
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('perms', '0032_auto_20221111_1919'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='assetpermission',
|
||||||
|
name='actions',
|
||||||
|
field=models.IntegerField(default=1, verbose_name='Actions'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 3.2.14 on 2022-11-18 02:55
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('terminal', '0059_applethostdeployment_task'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='applethostdeployment',
|
||||||
|
options={'ordering': ('-date_start',)},
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
from .ticket import *
|
|
||||||
from .flow import *
|
from .flow import *
|
||||||
|
from .ticket import *
|
||||||
from .comment import *
|
from .comment import *
|
||||||
from .super_ticket import *
|
|
||||||
from .relation import *
|
from .relation import *
|
||||||
|
from .super_ticket import *
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
from rest_framework import viewsets, mixins
|
from rest_framework import viewsets, mixins
|
||||||
|
|
||||||
from common.exceptions import JMSException
|
from common.exceptions import JMSException
|
||||||
from common.utils import lazyproperty
|
from common.utils import lazyproperty
|
||||||
from rbac.permissions import RBACPermission
|
from rbac.permissions import RBACPermission
|
||||||
|
|
|
@ -9,7 +9,6 @@ __all__ = ['TicketFlowViewSet']
|
||||||
|
|
||||||
class TicketFlowViewSet(JMSBulkModelViewSet):
|
class TicketFlowViewSet(JMSBulkModelViewSet):
|
||||||
serializer_class = serializers.TicketFlowSerializer
|
serializer_class = serializers.TicketFlowSerializer
|
||||||
|
|
||||||
filterset_fields = ['id', 'type']
|
filterset_fields = ['id', 'type']
|
||||||
search_fields = ['id', 'type']
|
search_fields = ['id', 'type']
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
from rest_framework.mixins import CreateModelMixin
|
|
||||||
from rest_framework import views
|
from rest_framework import views
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.mixins import CreateModelMixin
|
||||||
|
|
||||||
|
from orgs.utils import tmp_to_root_org
|
||||||
from common.drf.api import JMSGenericViewSet
|
from common.drf.api import JMSGenericViewSet
|
||||||
|
from terminal.serializers import SessionSerializer
|
||||||
from tickets.models import TicketSession
|
from tickets.models import TicketSession
|
||||||
from tickets.serializers import TicketSessionRelationSerializer
|
from tickets.serializers import TicketSessionRelationSerializer
|
||||||
from terminal.serializers import SessionSerializer
|
|
||||||
from orgs.utils import tmp_to_root_org
|
|
||||||
|
|
||||||
|
|
||||||
class TicketSessionRelationViewSet(CreateModelMixin, JMSGenericViewSet):
|
class TicketSessionRelationViewSet(CreateModelMixin, JMSGenericViewSet):
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
from rest_framework.generics import RetrieveDestroyAPIView
|
from rest_framework.generics import RetrieveDestroyAPIView
|
||||||
|
|
||||||
from orgs.utils import tmp_to_root_org
|
from orgs.utils import tmp_to_root_org
|
||||||
from ..serializers import SuperTicketSerializer
|
|
||||||
from ..models import Ticket
|
from ..models import Ticket
|
||||||
|
from ..serializers import SuperTicketSerializer
|
||||||
|
|
||||||
__all__ = ['SuperTicketStatusAPI']
|
__all__ = ['SuperTicketStatusAPI']
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
#
|
#
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.exceptions import MethodNotAllowed
|
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.exceptions import MethodNotAllowed
|
||||||
|
|
||||||
from common.const.http import POST, PUT, PATCH
|
|
||||||
from common.mixins.api import CommonApiMixin
|
|
||||||
from orgs.utils import tmp_to_root_org
|
from orgs.utils import tmp_to_root_org
|
||||||
from rbac.permissions import RBACPermission
|
from rbac.permissions import RBACPermission
|
||||||
|
from common.mixins.api import CommonApiMixin
|
||||||
|
from common.const.http import POST, PUT, PATCH
|
||||||
from tickets import filters
|
from tickets import filters
|
||||||
from tickets import serializers
|
from tickets import serializers
|
||||||
from tickets.models import (
|
from tickets.models import (
|
||||||
|
@ -94,9 +94,9 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet):
|
||||||
|
|
||||||
|
|
||||||
class ApplyAssetTicketViewSet(TicketViewSet):
|
class ApplyAssetTicketViewSet(TicketViewSet):
|
||||||
serializer_class = serializers.ApplyAssetSerializer
|
|
||||||
model = ApplyAssetTicket
|
model = ApplyAssetTicket
|
||||||
filterset_class = filters.ApplyAssetTicketFilter
|
filterset_class = filters.ApplyAssetTicketFilter
|
||||||
|
serializer_class = serializers.ApplyAssetSerializer
|
||||||
serializer_classes = {
|
serializer_classes = {
|
||||||
'open': serializers.ApplyAssetSerializer,
|
'open': serializers.ApplyAssetSerializer,
|
||||||
'approve': serializers.ApproveAssetSerializer
|
'approve': serializers.ApproveAssetSerializer
|
||||||
|
@ -104,18 +104,18 @@ class ApplyAssetTicketViewSet(TicketViewSet):
|
||||||
|
|
||||||
|
|
||||||
class ApplyLoginTicketViewSet(TicketViewSet):
|
class ApplyLoginTicketViewSet(TicketViewSet):
|
||||||
serializer_class = serializers.LoginConfirmSerializer
|
|
||||||
model = ApplyLoginTicket
|
model = ApplyLoginTicket
|
||||||
filterset_class = filters.ApplyLoginTicketFilter
|
filterset_class = filters.ApplyLoginTicketFilter
|
||||||
|
serializer_class = serializers.LoginConfirmSerializer
|
||||||
|
|
||||||
|
|
||||||
class ApplyLoginAssetTicketViewSet(TicketViewSet):
|
class ApplyLoginAssetTicketViewSet(TicketViewSet):
|
||||||
serializer_class = serializers.LoginAssetConfirmSerializer
|
|
||||||
model = ApplyLoginAssetTicket
|
model = ApplyLoginAssetTicket
|
||||||
filterset_class = filters.ApplyLoginAssetTicketFilter
|
filterset_class = filters.ApplyLoginAssetTicketFilter
|
||||||
|
serializer_class = serializers.LoginAssetConfirmSerializer
|
||||||
|
|
||||||
|
|
||||||
class ApplyCommandTicketViewSet(TicketViewSet):
|
class ApplyCommandTicketViewSet(TicketViewSet):
|
||||||
serializer_class = serializers.ApplyCommandConfirmSerializer
|
|
||||||
model = ApplyCommandTicket
|
model = ApplyCommandTicket
|
||||||
filterset_class = filters.ApplyCommandTicketFilter
|
filterset_class = filters.ApplyCommandTicketFilter
|
||||||
|
serializer_class = serializers.ApplyCommandConfirmSerializer
|
||||||
|
|
|
@ -6,18 +6,18 @@ TICKET_DETAIL_URL = '/ui/#/tickets/tickets/{id}?type={type}'
|
||||||
|
|
||||||
class TicketType(TextChoices):
|
class TicketType(TextChoices):
|
||||||
general = 'general', _("General")
|
general = 'general', _("General")
|
||||||
login_confirm = 'login_confirm', _("Login confirm")
|
|
||||||
apply_asset = 'apply_asset', _('Apply for asset')
|
apply_asset = 'apply_asset', _('Apply for asset')
|
||||||
login_asset_confirm = 'login_asset_confirm', _('Login asset confirm')
|
login_confirm = 'login_confirm', _("Login confirm")
|
||||||
command_confirm = 'command_confirm', _('Command confirm')
|
command_confirm = 'command_confirm', _('Command confirm')
|
||||||
|
login_asset_confirm = 'login_asset_confirm', _('Login asset confirm')
|
||||||
|
|
||||||
|
|
||||||
class TicketState(TextChoices):
|
class TicketState(TextChoices):
|
||||||
pending = 'pending', _('Open')
|
pending = 'pending', _('Open')
|
||||||
approved = 'approved', _('Approved')
|
|
||||||
rejected = 'rejected', _('Rejected')
|
|
||||||
closed = 'closed', _("Cancel")
|
closed = 'closed', _("Cancel")
|
||||||
reopen = 'reopen', _("Reopen")
|
reopen = 'reopen', _("Reopen")
|
||||||
|
approved = 'approved', _('Approved')
|
||||||
|
rejected = 'rejected', _('Rejected')
|
||||||
|
|
||||||
|
|
||||||
class TicketStatus(TextChoices):
|
class TicketStatus(TextChoices):
|
||||||
|
@ -27,23 +27,23 @@ class TicketStatus(TextChoices):
|
||||||
|
|
||||||
class StepState(TextChoices):
|
class StepState(TextChoices):
|
||||||
pending = 'pending', _('Pending')
|
pending = 'pending', _('Pending')
|
||||||
approved = 'approved', _('Approved')
|
|
||||||
rejected = 'rejected', _('Rejected')
|
|
||||||
closed = 'closed', _("Closed")
|
closed = 'closed', _("Closed")
|
||||||
reopen = 'reopen', _("Reopen")
|
reopen = 'reopen', _("Reopen")
|
||||||
|
approved = 'approved', _('Approved')
|
||||||
|
rejected = 'rejected', _('Rejected')
|
||||||
|
|
||||||
|
|
||||||
class StepStatus(TextChoices):
|
class StepStatus(TextChoices):
|
||||||
pending = 'pending', _('Pending')
|
|
||||||
active = 'active', _('Active')
|
active = 'active', _('Active')
|
||||||
closed = 'closed', _("Closed")
|
closed = 'closed', _("Closed")
|
||||||
|
pending = 'pending', _('Pending')
|
||||||
|
|
||||||
|
|
||||||
class TicketAction(TextChoices):
|
class TicketAction(TextChoices):
|
||||||
open = 'open', _("Open")
|
open = 'open', _("Open")
|
||||||
close = 'close', _("Close")
|
close = 'close', _("Close")
|
||||||
approve = 'approve', _('Approve')
|
|
||||||
reject = 'reject', _('Reject')
|
reject = 'reject', _('Reject')
|
||||||
|
approve = 'approve', _('Approve')
|
||||||
|
|
||||||
|
|
||||||
class TicketLevel(IntegerChoices):
|
class TicketLevel(IntegerChoices):
|
||||||
|
@ -52,7 +52,7 @@ class TicketLevel(IntegerChoices):
|
||||||
|
|
||||||
|
|
||||||
class TicketApprovalStrategy(TextChoices):
|
class TicketApprovalStrategy(TextChoices):
|
||||||
super_admin = 'super_admin', _("Super admin")
|
|
||||||
org_admin = 'org_admin', _("Org admin")
|
org_admin = 'org_admin', _("Org admin")
|
||||||
super_org_admin = 'super_org_admin', _("Super admin and org admin")
|
|
||||||
custom_user = 'custom_user', _("Custom user")
|
custom_user = 'custom_user', _("Custom user")
|
||||||
|
super_admin = 'super_admin', _("Super admin")
|
||||||
|
super_org_admin = 'super_org_admin', _("Super admin and org admin")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from django_filters import rest_framework as filters
|
|
||||||
from django.db.models import Subquery, OuterRef
|
from django.db.models import Subquery, OuterRef
|
||||||
|
from django_filters import rest_framework as filters
|
||||||
|
|
||||||
from common.drf.filters import BaseFilterSet
|
from common.drf.filters import BaseFilterSet
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from perms.models import AssetPermission
|
|
||||||
from orgs.utils import tmp_to_org
|
from orgs.utils import tmp_to_org
|
||||||
|
from perms.models import AssetPermission
|
||||||
from tickets.models import ApplyAssetTicket
|
from tickets.models import ApplyAssetTicket
|
||||||
from .base import BaseHandler
|
from .base import BaseHandler
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.14 on 2022-11-18 03:00
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('tickets', '0022_alter_applyassetticket_apply_actions'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='applyassetticket',
|
||||||
|
name='apply_actions',
|
||||||
|
field=models.IntegerField(default=31, verbose_name='Actions'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,7 +1,6 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from perms.models import Action
|
|
||||||
from .general import Ticket
|
from .general import Ticket
|
||||||
|
|
||||||
__all__ = ['ApplyApplicationTicket']
|
__all__ = ['ApplyApplicationTicket']
|
||||||
|
@ -23,14 +22,10 @@ class ApplyApplicationTicket(Ticket):
|
||||||
'assets.SystemUser', verbose_name=_('Apply system users'),
|
'assets.SystemUser', verbose_name=_('Apply system users'),
|
||||||
)
|
)
|
||||||
apply_actions = models.IntegerField(
|
apply_actions = models.IntegerField(
|
||||||
choices=Action.DB_CHOICES, default=Action.ALL, verbose_name=_('Actions')
|
choices=[
|
||||||
|
(255, 'All'), (1, 'Connect'), (2, 'Upload file'), (4, 'Download file'), (6, 'Upload download'),
|
||||||
|
(8, 'Clipboard copy'), (16, 'Clipboard paste'), (24, 'Clipboard copy paste')
|
||||||
|
], default=255, verbose_name=_('Actions')
|
||||||
)
|
)
|
||||||
apply_date_start = models.DateTimeField(verbose_name=_('Date start'), null=True)
|
apply_date_start = models.DateTimeField(verbose_name=_('Date start'), null=True)
|
||||||
apply_date_expired = models.DateTimeField(verbose_name=_('Date expired'), null=True)
|
apply_date_expired = models.DateTimeField(verbose_name=_('Date expired'), null=True)
|
||||||
|
|
||||||
@property
|
|
||||||
def apply_actions_display(self):
|
|
||||||
return Action.value_to_choices_display(self.apply_actions)
|
|
||||||
|
|
||||||
def get_apply_actions_display(self):
|
|
||||||
return ', '.join(self.apply_actions_display)
|
|
||||||
|
|
|
@ -5,23 +5,23 @@ from typing import Callable
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.forms import model_to_dict
|
||||||
from django.db.utils import IntegrityError
|
from django.db.utils import IntegrityError
|
||||||
from django.db.models.fields import related
|
from django.db.models.fields import related
|
||||||
from django.forms import model_to_dict
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from orgs.utils import tmp_to_org
|
||||||
|
from orgs.models import Organization
|
||||||
from common.exceptions import JMSException
|
from common.exceptions import JMSException
|
||||||
from common.utils.timezone import as_current_tz
|
from common.utils.timezone import as_current_tz
|
||||||
from common.mixins.models import CommonModelMixin
|
from common.mixins.models import CommonModelMixin
|
||||||
from common.db.encoder import ModelJSONFieldEncoder
|
from common.db.encoder import ModelJSONFieldEncoder
|
||||||
from orgs.models import Organization
|
|
||||||
from orgs.utils import tmp_to_org
|
|
||||||
from tickets.const import (
|
from tickets.const import (
|
||||||
TicketType, TicketStatus, TicketState,
|
TicketType, TicketStatus, TicketState,
|
||||||
TicketLevel, StepState, StepStatus
|
TicketLevel, StepState, StepStatus
|
||||||
)
|
)
|
||||||
from tickets.handlers import get_ticket_handler
|
|
||||||
from tickets.errors import AlreadyClosed
|
from tickets.errors import AlreadyClosed
|
||||||
|
from tickets.handlers import get_ticket_handler
|
||||||
from ..flow import TicketFlow
|
from ..flow import TicketFlow
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
from urllib.parse import urljoin
|
|
||||||
import json
|
import json
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.shortcuts import reverse
|
from django.shortcuts import reverse
|
||||||
from django.template.loader import render_to_string
|
|
||||||
from django.forms import model_to_dict
|
from django.forms import model_to_dict
|
||||||
|
from django.template.loader import render_to_string
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from notifications.notifications import UserMessage
|
from notifications.notifications import UserMessage
|
||||||
|
@ -94,9 +94,9 @@ class BaseTicketMessage(UserMessage):
|
||||||
|
|
||||||
class TicketAppliedToAssigneeMessage(BaseTicketMessage):
|
class TicketAppliedToAssigneeMessage(BaseTicketMessage):
|
||||||
def __init__(self, user, ticket):
|
def __init__(self, user, ticket):
|
||||||
|
self._token = None
|
||||||
self.ticket = ticket
|
self.ticket = ticket
|
||||||
super().__init__(user)
|
super().__init__(user)
|
||||||
self._token = None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def token(self):
|
def token(self):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
from .ticket import *
|
|
||||||
from .flow import *
|
from .flow import *
|
||||||
|
from .ticket import *
|
||||||
from .comment import *
|
from .comment import *
|
||||||
from .relation import *
|
from .relation import *
|
||||||
from .super_ticket import *
|
from .super_ticket import *
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from ..models import Comment
|
|
||||||
from common.drf.fields import ReadableHiddenField
|
from common.drf.fields import ReadableHiddenField
|
||||||
|
from ..models import Comment
|
||||||
|
|
||||||
__all__ = ['CommentSerializer']
|
__all__ = ['CommentSerializer']
|
||||||
|
|
||||||
|
@ -23,8 +24,7 @@ class CommentSerializer(serializers.ModelSerializer):
|
||||||
model = Comment
|
model = Comment
|
||||||
fields_mini = ['id']
|
fields_mini = ['id']
|
||||||
fields_small = fields_mini + [
|
fields_small = fields_mini + [
|
||||||
'body', 'user_display',
|
'body', 'user_display', 'date_created', 'date_updated'
|
||||||
'date_created', 'date_updated'
|
|
||||||
]
|
]
|
||||||
fields_fk = ['ticket', 'user', ]
|
fields_fk = ['ticket', 'user', ]
|
||||||
fields = fields_small + fields_fk
|
fields = fields_small + fields_fk
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
from rest_framework import serializers
|
||||||
from django.db.transaction import atomic
|
from django.db.transaction import atomic
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
|
||||||
|
|
||||||
from orgs.models import Organization
|
from orgs.models import Organization
|
||||||
from orgs.utils import get_current_org_id
|
from orgs.utils import get_current_org_id
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
from .common import *
|
||||||
from .ticket import *
|
from .ticket import *
|
||||||
from .apply_asset import *
|
from .apply_asset import *
|
||||||
from .login_confirm import *
|
from .login_confirm import *
|
||||||
from .login_asset_confirm import *
|
|
||||||
from .command_confirm import *
|
from .command_confirm import *
|
||||||
from .common import *
|
from .login_asset_confirm import *
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from assets.models import Asset, Node
|
from assets.models import Asset, Node
|
||||||
from common.drf.fields import ObjectRelatedField
|
|
||||||
from perms.models import AssetPermission
|
from perms.models import AssetPermission
|
||||||
from perms.serializers.permission import ActionChoicesField
|
from perms.serializers.permission import ActionChoicesField
|
||||||
|
from common.drf.fields import ObjectRelatedField
|
||||||
from tickets.models import ApplyAssetTicket
|
from tickets.models import ApplyAssetTicket
|
||||||
from .common import BaseApplyAssetSerializer
|
from .common import BaseApplyAssetSerializer
|
||||||
from .ticket import TicketApplySerializer
|
from .ticket import TicketApplySerializer
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common.drf.fields import LabeledChoiceField
|
from common.drf.fields import LabeledChoiceField
|
||||||
from orgs.mixins.serializers import OrgResourceModelSerializerMixin
|
|
||||||
from orgs.models import Organization
|
from orgs.models import Organization
|
||||||
from tickets.const import TicketType, TicketStatus, TicketState
|
from orgs.mixins.serializers import OrgResourceModelSerializerMixin
|
||||||
from tickets.models import Ticket, TicketFlow
|
from tickets.models import Ticket, TicketFlow
|
||||||
|
from tickets.const import TicketType, TicketStatus, TicketState
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'TicketApplySerializer', 'TicketApproveSerializer', 'TicketSerializer',
|
'TicketApplySerializer', 'TicketApproveSerializer', 'TicketSerializer',
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from rest_framework_bulk.routes import BulkRouter
|
from rest_framework_bulk.routes import BulkRouter
|
||||||
|
|
||||||
from .. import api
|
from .. import api
|
||||||
|
@ -10,16 +9,16 @@ app_name = 'tickets'
|
||||||
router = BulkRouter()
|
router = BulkRouter()
|
||||||
|
|
||||||
router.register('tickets', api.TicketViewSet, 'ticket')
|
router.register('tickets', api.TicketViewSet, 'ticket')
|
||||||
router.register('apply-asset-tickets', api.ApplyAssetTicketViewSet, 'apply-asset-ticket')
|
|
||||||
router.register('apply-login-tickets', api.ApplyLoginTicketViewSet, 'apply-login-ticket')
|
|
||||||
router.register('apply-login-asset-tickets', api.ApplyLoginAssetTicketViewSet, 'apply-login-asset-ticket')
|
|
||||||
router.register('apply-command-tickets', api.ApplyCommandTicketViewSet, 'apply-command-ticket')
|
|
||||||
router.register('flows', api.TicketFlowViewSet, 'flows')
|
router.register('flows', api.TicketFlowViewSet, 'flows')
|
||||||
router.register('comments', api.CommentViewSet, 'comment')
|
router.register('comments', api.CommentViewSet, 'comment')
|
||||||
|
router.register('apply-asset-tickets', api.ApplyAssetTicketViewSet, 'apply-asset-ticket')
|
||||||
|
router.register('apply-login-tickets', api.ApplyLoginTicketViewSet, 'apply-login-ticket')
|
||||||
|
router.register('apply-command-tickets', api.ApplyCommandTicketViewSet, 'apply-command-ticket')
|
||||||
|
router.register('apply-login-asset-tickets', api.ApplyLoginAssetTicketViewSet, 'apply-login-asset-ticket')
|
||||||
router.register('ticket-session-relation', api.TicketSessionRelationViewSet, 'ticket-session-relation')
|
router.register('ticket-session-relation', api.TicketSessionRelationViewSet, 'ticket-session-relation')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('tickets/<uuid:ticket_id>/session/', api.TicketSessionApi.as_view(), name='ticket-sesion'),
|
path('tickets/<uuid:ticket_id>/session/', api.TicketSessionApi.as_view(), name='ticket-session'),
|
||||||
path('super-tickets/<uuid:pk>/status/', api.SuperTicketStatusAPI.as_view(), name='super-ticket-status'),
|
path('super-tickets/<uuid:pk>/status/', api.SuperTicketStatusAPI.as_view(), name='super-ticket-status'),
|
||||||
]
|
]
|
||||||
urlpatterns += router.urls
|
urlpatterns += router.urls
|
||||||
|
|
|
@ -2,18 +2,18 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.views.generic.base import TemplateView
|
|
||||||
from django.shortcuts import redirect, reverse
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
from django.shortcuts import redirect, reverse
|
||||||
|
from django.views.generic.base import TemplateView
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from orgs.utils import tmp_to_root_org
|
from orgs.utils import tmp_to_root_org
|
||||||
|
from tickets.const import TicketType
|
||||||
|
from tickets.errors import AlreadyClosed
|
||||||
from tickets.models import (
|
from tickets.models import (
|
||||||
Ticket, ApplyAssetTicket,
|
Ticket, ApplyAssetTicket,
|
||||||
ApplyLoginTicket, ApplyLoginAssetTicket, ApplyCommandTicket
|
ApplyLoginTicket, ApplyLoginAssetTicket, ApplyCommandTicket
|
||||||
)
|
)
|
||||||
from tickets.const import TicketType
|
|
||||||
from tickets.errors import AlreadyClosed
|
|
||||||
from common.utils import get_logger, FlashMessageUtil
|
from common.utils import get_logger, FlashMessageUtil
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
Loading…
Reference in New Issue