Merge branch 'v3' of github.com:jumpserver/jumpserver into v3

pull/9115/head
ibuler 2022-11-18 19:29:52 +08:00
commit 6d5be66b5e
28 changed files with 193 additions and 76 deletions

View File

@ -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),
),
]

View File

@ -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(

View File

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

View File

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

View File

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

View File

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

View File

@ -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 *

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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__ = [

View File

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

View File

@ -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 *

View File

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

View File

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

View File

@ -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 *

View File

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

View File

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

View File

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

View File

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