mirror of https://github.com/jumpserver/jumpserver
ansible Task接口更上层抽象的基本实现
parent
86c5f0d3d3
commit
150e1030c3
|
@ -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',)
|
||||
|
|
|
@ -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,)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@ from ansible import *
|
|||
from cron import *
|
||||
from sudo import *
|
||||
from utils import *
|
||||
|
||||
|
|
|
@ -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
|
||||
return "%s %s" % (self.module_name, self.module_args)
|
||||
|
||||
def run(self):
|
||||
pass
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
|
@ -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 = []
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{% block table_search %}
|
||||
{% endblock %}
|
||||
{% block table_container %}
|
||||
<div class="uc pull-left m-l-5 m-r-5"><a href="{% url "users:user-create" %}" class="btn btn-sm btn-primary"> {% trans "Create sudo" %} </a></div>
|
||||
<div class="uc pull-left m-l-5 m-r-5"><a href="{% url "ops:page-task-create" %}" class="btn btn-sm btn-primary"> {% trans "Create task" %} </a></div>
|
||||
{#<div class="uc pull-left"><a href="javascript:void(0);" class="btn btnbtn-sm btn-primary" data-toggle="modal" data-target="#user_import_modal"> {% trans "Import user" %} </a></div>#}
|
||||
<table class="table table-striped table-bordered table-hover " id="sudo_list_table">
|
||||
<thead>
|
||||
|
@ -12,8 +12,9 @@
|
|||
<input id="" type="checkbox" class="ipt_check_all">
|
||||
</th>
|
||||
<th class="text-center">{% trans 'Name' %}</th>
|
||||
<th class="text-center">{% trans 'Privileges' %}</th>
|
||||
<th class="text-center">{% trans 'Extra Lines' %}</th>
|
||||
<th class="text-center">{% trans 'UUID' %}</th>
|
||||
<th class="text-center">{% trans 'Start' %}</th>
|
||||
<th class="text-center">{% trans 'Completed' %}</th>
|
||||
<th class="text-center">{% trans 'Action' %}</th>
|
||||
|
||||
</tr>
|
||||
|
@ -35,8 +36,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#{% 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 = '<a href="{% url "ops:page-sudo-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||
var detail_btn = '<a href="{% url "ops:page-task-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||
}},
|
||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "users:user-update" pk=99991937 %}" class="btn btn-xs btn-info m-l-xs">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
||||
var preview_btn = '<a href="{% url "users:user-update" pk=99991937 %}" class="btn btn-xs btn-info m-l-xs">{% trans "Preview" %}</a>'.replace('99991937', cellData);
|
||||
var job_btn = '<a href="{% url "users:user-update" pk=99991937 %}" class="btn btn-xs btn-primary m-l-xs">{% trans "Job" %}</a>'.replace('99991937', cellData);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
||||
{targets: 3, createdCell: function (td, cellData) {
|
||||
if (!cellData) {
|
||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||
} else {
|
||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||
}
|
||||
}},
|
||||
{targets: 4, createdCell: function (td, cellData) {
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.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);
|
||||
|
|
|
@ -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
|
|
@ -19,4 +19,10 @@ urlpatterns = [
|
|||
url(r'^cron/create$', page_view.CronCreateView.as_view(), name='page-cron-create'),
|
||||
url(r'^cron/(?P<pk>[0-9]+)/detail$', page_view.CronDetailView.as_view(), name='page-cron-detail'),
|
||||
url(r'^cron/(?P<pk>[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<pk>[0-9]+)/detail$', page_view.TaskDetailView.as_view(), name='page-task-detail'),
|
||||
url(r'^task/(?P<pk>[0-9]+)/update$', page_view.TaskUpdateView.as_view(), name='page-task-update'),
|
||||
]
|
|
@ -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)
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
<i class="fa fa-coffee"></i> <span class="nav-label">{% trans 'Job Center' %}</span><span class="fa arrow"></span>
|
||||
</a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li id="task"><a href="{% url 'ops:page-task-list' %}">{% trans 'Task' %}</a></li>
|
||||
<li id="sudo"><a href="{% url 'ops:page-sudo-list' %}">{% trans 'Sudo' %}</a></li>
|
||||
<li id="cron"><a href="{% url 'ops:page-cron-list' %}">{% trans 'Cron' %}</a></li>
|
||||
</ul>
|
||||
|
|
Loading…
Reference in New Issue