diff --git a/apps/ops/api/serializers.py b/apps/ops/api/serializers.py index 1cafdf574..3981552e2 100644 --- a/apps/ops/api/serializers.py +++ b/apps/ops/api/serializers.py @@ -1,7 +1,7 @@ # ~*~ coding: utf-8 ~*~ from __future__ import unicode_literals -from ..models import HostAlia, UserAlia, CmdAlia, RunasAlia, Extra_conf, Privilege, Sudo, CronTable +from ops.models import * from rest_framework import serializers @@ -51,3 +51,9 @@ class CronTableSerializer(serializers.ModelSerializer): class Meta: model = CronTable + +class TaskSerializer(serializers.ModelSerializer): + + class Meta: + model = Task + read_only_fields = ('record',) diff --git a/apps/ops/api/views.py b/apps/ops/api/views.py index bc5e40617..4bde44b9f 100644 --- a/apps/ops/api/views.py +++ b/apps/ops/api/views.py @@ -13,6 +13,7 @@ __all__ = ["HostAliaViewSet", "PrivilegeViewSet", "SudoViewSet", "CronTableViewSet", + "TaskViewSet", ] @@ -63,5 +64,10 @@ class CronTableViewSet(viewsets.ModelViewSet): serializer_class = CronTableSerializer permission_classes = (AdminUserRequired,) +class TaskViewSet(viewsets.ModelViewSet): + queryset = Task.objects.all() + serializer_class = TaskSerializer + permission_classes = (AdminUserRequired,) + diff --git a/apps/ops/models/__init__.py b/apps/ops/models/__init__.py index ef134dd20..ef0a6b8af 100644 --- a/apps/ops/models/__init__.py +++ b/apps/ops/models/__init__.py @@ -2,3 +2,4 @@ from ansible import * from cron import * from sudo import * from utils import * + diff --git a/apps/ops/models/ansible.py b/apps/ops/models/ansible.py index 7ebf59476..cebc5251a 100644 --- a/apps/ops/models/ansible.py +++ b/apps/ops/models/ansible.py @@ -9,13 +9,13 @@ from assets.models import Asset from django.db import models from django.utils.translation import ugettext_lazy as _ -__all__ = ["Task", "Tasker", "AnsiblePlay", "AnsibleTask", "AnsibleHostResult"] +__all__ = ["Task", "TaskRecord", "AnsiblePlay", "AnsibleTask", "AnsibleHostResult"] logger = logging.getLogger(__name__) -class Tasker(models.Model): +class TaskRecord(models.Model): uuid = models.CharField(max_length=128, verbose_name=_('UUID'), primary_key=True) name = models.CharField(max_length=128, blank=True, verbose_name=_('Name')) start = models.DateTimeField(auto_now_add=True, verbose_name=_('Start Time')) @@ -51,7 +51,7 @@ class Tasker(models.Model): class AnsiblePlay(models.Model): - tasker = models.ForeignKey(Tasker, related_name='plays', blank=True, null=True) + tasker = models.ForeignKey(TaskRecord, related_name='plays', blank=True, null=True) uuid = models.CharField(max_length=128, verbose_name=_('UUID'), primary_key=True) name = models.CharField(max_length=128, verbose_name=_('Name')) @@ -73,7 +73,7 @@ class AnsiblePlay(models.Model): name=forgery_py.name.full_name(), ) try: - play.tasker = choice(Tasker.objects.all()) + play.tasker = choice(TaskRecord.objects.all()) play.save() logger.debug('Generate fake play: %s' % play.name) except Exception as e: @@ -293,8 +293,16 @@ class AnsibleHostResult(models.Model): continue class Task(models.Model): + record = models.OneToOneField(TaskRecord) name = models.CharField(max_length=128, blank=True, verbose_name=_('Name')) - asset = models.ForeignKey(Asset, null=True, blank=True, related_name='crontables') + module_name = models.CharField(max_length=128, verbose_name=_('Ansible Module Name')) + module_args = models.CharField(max_length=512, blank=True, verbose_name=_("Ansible Module Args")) + register = models.CharField(max_length=128, blank=True, verbose_name=_('Ansible Task Register')) + is_gather_facts = models.BooleanField(default=False,verbose_name=_('Is Gather Ansible Facts')) + asset = models.ManyToManyField(Asset, related_name='tasks') def __unicode__(self): - pass \ No newline at end of file + return "%s %s" % (self.module_name, self.module_args) + + def run(self): + pass diff --git a/apps/ops/models/sudo.py b/apps/ops/models/sudo.py index 5aaba44ab..0c1a582c8 100644 --- a/apps/ops/models/sudo.py +++ b/apps/ops/models/sudo.py @@ -5,7 +5,7 @@ import logging from jinja2 import Template from django.db import models -from django.utils import timezone +from django.utils.timezone import now from assets.models import Asset, AssetGroup from django.utils.translation import ugettext_lazy as _ @@ -174,7 +174,7 @@ class Sudo(models.Model): name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'), help_text=_('Name for this sudo')) - created_time = models.DateTimeField(verbose_name=_('Created Time'), default=timezone.now(), + created_time = models.DateTimeField(verbose_name=_('Created Time'), auto_created=True, help_text=_('The create time of this sudo')) modify_time = models.DateTimeField(auto_now=True, verbose_name=_('Modify Time'), help_text=_('The recent modify time of this sudo')) @@ -310,7 +310,7 @@ root ALL=(ALL:ALL) ALL seed() for i in range(count): sudo = cls(name=forgery_py.name.full_name(), - created_time=timezone.now() + created_time=now() ) try: sudo.save() diff --git a/apps/ops/models/utils.py b/apps/ops/models/utils.py index 1f93e619d..17c7cbab1 100644 --- a/apps/ops/models/utils.py +++ b/apps/ops/models/utils.py @@ -9,6 +9,6 @@ __all__ = ["generate_fake"] def generate_fake(): - for cls in (Tasker, AnsiblePlay, AnsibleTask, AnsibleHostResult, CronTable, + for cls in (TaskRecord, AnsiblePlay, AnsibleTask, AnsibleHostResult, CronTable, HostAlia, UserAlia, CmdAlia, RunasAlia, Privilege, Sudo): cls.generate_fake() \ No newline at end of file diff --git a/apps/ops/tasks/taskers.py b/apps/ops/tasks/taskers.py index 07815b993..3a724b049 100644 --- a/apps/ops/tasks/taskers.py +++ b/apps/ops/tasks/taskers.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals from ops.tasks import _celery_tasks -from ops.models import Tasker +from ops.models import TaskRecord from uuid import uuid1 from celery.result import AsyncResult @@ -23,7 +23,7 @@ def get_result(task_id): def __get_result_by_tasker_id(tasker_uuid, deal_method): - tasker = Tasker.objects.get(uuid=tasker_uuid) + tasker = TaskRecord.objects.get(uuid=tasker_uuid) total = tasker.total_hosts total_len = len(total) host_results = [] diff --git a/apps/ops/templates/task/list.html b/apps/ops/templates/task/list.html index 8da993251..7109e4fe8 100644 --- a/apps/ops/templates/task/list.html +++ b/apps/ops/templates/task/list.html @@ -3,7 +3,7 @@ {% block table_search %} {% endblock %} {% block table_container %} -
{% trans "Create sudo" %}
+
{% trans "Create task" %}
{#
{% trans "Import user" %}
#} @@ -12,8 +12,9 @@ - - + + + @@ -35,8 +36,6 @@ -{#{% include "users/_user_bulk_update_modal.html" %}#} -{#{% include "users/_user_import_modal.html" %}#} {% endblock %} {% block content_bottom_left %}{% endblock %} {% block custom_foot_js %} @@ -47,23 +46,23 @@ $(document).ready(function(){ ele: $('#sudo_list_table'), columnDefs: [ {targets: 1, createdCell: function (td, cellData, rowData) { - var detail_btn = '' + cellData + ''; + var detail_btn = '' + cellData + ''; $(td).html(detail_btn.replace('99991937', rowData.id)); }}, - {targets: 4, createdCell: function (td, cellData, rowData) { - var update_btn = '{% trans "Update" %}'.replace('99991937', cellData); - var preview_btn = '{% trans "Preview" %}'.replace('99991937', cellData); - var job_btn = '{% trans "Job" %}'.replace('99991937', cellData); - var del_btn = '{% trans "Delete" %}'.replace('99991937', cellData); + {targets: 3, createdCell: function (td, cellData) { + if (!cellData) { + $(td).html('') + } else { + $(td).html('') + } + }}, + {targets: 4, createdCell: function (td, cellData) { + var del_btn = '{% trans "Delete" %}'.replace('99991937', cellData) + $(td).html(del_btn) - if (rowData.id === 1 || rowData.username == "admin") { - $(td).html(update_btn) - } else { - $(td).html(preview_btn + job_btn + update_btn + del_btn) - } }}], - ajax_url: '{% url "api-ops:sudo-list" %}', - columns: [{data: "id"}, {data: "name" }, {data: "privilege_items" }, {data: "extra_lines" }, {data: "id" }], + ajax_url: '{% url "api-ops:task-list" %}', + columns: [{data: "name"}, {data: "uuid" }, {data: "start" }, {data: "completed" }, {data: "id" }], op_html: $('#actions').html() }; var table = jumpserver.initDataTable(options); diff --git a/apps/ops/urls/api_urls.py b/apps/ops/urls/api_urls.py index 81a550f66..144d6a53e 100644 --- a/apps/ops/urls/api_urls.py +++ b/apps/ops/urls/api_urls.py @@ -15,5 +15,6 @@ api_router.register(r'v1/extra_conf', v1_api.ExtraconfViewSet) api_router.register(r'v1/privilege', v1_api.PrivilegeViewSet) api_router.register(r'v1/sudo', v1_api.SudoViewSet) api_router.register(r'v1/cron', v1_api.CronTableViewSet) +api_router.register(r'v1/task', v1_api.TaskViewSet) urlpatterns = api_router.urls \ No newline at end of file diff --git a/apps/ops/urls/view_urls.py b/apps/ops/urls/view_urls.py index d43f1a95c..9e9c68253 100644 --- a/apps/ops/urls/view_urls.py +++ b/apps/ops/urls/view_urls.py @@ -19,4 +19,10 @@ urlpatterns = [ url(r'^cron/create$', page_view.CronCreateView.as_view(), name='page-cron-create'), url(r'^cron/(?P[0-9]+)/detail$', page_view.CronDetailView.as_view(), name='page-cron-detail'), url(r'^cron/(?P[0-9]+)/update$', page_view.CronUpdateView.as_view(), name='page-cron-update'), + + # TResource Task url + url(r'^task/list$', page_view.TaskListView.as_view(), name='page-task-list'), + url(r'^task/create$', page_view.TaskCreateView.as_view(), name='page-task-create'), + url(r'^task/(?P[0-9]+)/detail$', page_view.TaskDetailView.as_view(), name='page-task-detail'), + url(r'^task/(?P[0-9]+)/update$', page_view.TaskUpdateView.as_view(), name='page-task-update'), ] \ No newline at end of file diff --git a/apps/ops/utils/ansible_api.py b/apps/ops/utils/ansible_api.py index d3cc7edfe..25ddc91bd 100644 --- a/apps/ops/utils/ansible_api.py +++ b/apps/ops/utils/ansible_api.py @@ -18,7 +18,7 @@ from ansible.utils.display import Display from ansible.playbook.play import Play from ansible.plugins.callback import CallbackBase -from ops.models import Tasker, AnsiblePlay, AnsibleTask, AnsibleHostResult +from ops.models import TaskRecord, AnsiblePlay, AnsibleTask, AnsibleHostResult logger = logging.getLogger(__name__) @@ -196,7 +196,7 @@ class CallbackModule(CallbackBase): } try: - tasker = Tasker.objects.get(uuid=self.tasker_id) + tasker = TaskRecord.objects.get(uuid=self.tasker_id) play = AnsiblePlay(tasker, name=ret['name'], uuid=ret['uuid']) play.save() except Exception as e: @@ -429,7 +429,7 @@ class ADHocRunner(InventoryMixin): @staticmethod def update_db_tasker(tasker_id, ext_code): try: - tasker = Tasker.objects.get(uuid=tasker_id) + tasker = TaskRecord.objects.get(uuid=tasker_id) tasker.end = timezone.now() tasker.completed = True tasker.exit_code = ext_code @@ -440,7 +440,7 @@ class ADHocRunner(InventoryMixin): def create_db_tasker(self, name, uuid): try: hosts = [host.get('name') for host in self.hosts] - tasker = Tasker(name=name, uuid=uuid, hosts=','.join(hosts), start=timezone.now()) + tasker = TaskRecord(name=name, uuid=uuid, hosts=','.join(hosts), start=timezone.now()) tasker.save() except Exception as e: logger.error("Save Tasker to database error!, %s" % e.message) diff --git a/apps/ops/views.py b/apps/ops/views.py index 5678d1d88..cf07aee59 100644 --- a/apps/ops/views.py +++ b/apps/ops/views.py @@ -56,3 +56,32 @@ class CronDetailView(DetailView): context_object_name = 'cron' template_name = 'cron/detail.html' +class TaskListView(AdminUserRequiredMixin, ListView): + paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + model = Task + context_object_name = 'tasks' + template_name = 'task/list.html' + + def get_context_data(self, **kwargs): + context = { + 'task': 'Assets', + 'action': 'Create asset', + } + kwargs.update(context) + return super(TaskListView, self).get_context_data(**kwargs) + + +class TaskCreateView(AdminUserRequiredMixin, CreateView): + model = Task + template_name = 'task/create.html' + + +class TaskUpdateView(AdminUserRequiredMixin, UpdateView): + model = Task + template_name = 'task/update.html' + + +class TaskDetailView(DetailView): + model = Task + context_object_name = 'task' + template_name = 'task/detail.html' diff --git a/apps/templates/_nav.html b/apps/templates/_nav.html index 01e5427db..0ee86f8a4 100644 --- a/apps/templates/_nav.html +++ b/apps/templates/_nav.html @@ -46,6 +46,7 @@ {% trans 'Job Center' %}
{% trans 'Name' %}{% trans 'Privileges' %}{% trans 'Extra Lines' %}{% trans 'UUID' %}{% trans 'Start' %}{% trans 'Completed' %} {% trans 'Action' %}