Commit 150e1030 authored by yumaojun03's avatar yumaojun03

ansible Task接口更上层抽象的基本实现

parent 86c5f0d3
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals 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 from rest_framework import serializers
...@@ -51,3 +51,9 @@ class CronTableSerializer(serializers.ModelSerializer): ...@@ -51,3 +51,9 @@ class CronTableSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = CronTable model = CronTable
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
read_only_fields = ('record',)
...@@ -13,6 +13,7 @@ __all__ = ["HostAliaViewSet", ...@@ -13,6 +13,7 @@ __all__ = ["HostAliaViewSet",
"PrivilegeViewSet", "PrivilegeViewSet",
"SudoViewSet", "SudoViewSet",
"CronTableViewSet", "CronTableViewSet",
"TaskViewSet",
] ]
...@@ -63,5 +64,10 @@ class CronTableViewSet(viewsets.ModelViewSet): ...@@ -63,5 +64,10 @@ class CronTableViewSet(viewsets.ModelViewSet):
serializer_class = CronTableSerializer serializer_class = CronTableSerializer
permission_classes = (AdminUserRequired,) permission_classes = (AdminUserRequired,)
class TaskViewSet(viewsets.ModelViewSet):
queryset = Task.objects.all()
serializer_class = TaskSerializer
permission_classes = (AdminUserRequired,)
...@@ -2,3 +2,4 @@ from ansible import * ...@@ -2,3 +2,4 @@ from ansible import *
from cron import * from cron import *
from sudo import * from sudo import *
from utils import * from utils import *
...@@ -9,13 +9,13 @@ from assets.models import Asset ...@@ -9,13 +9,13 @@ from assets.models import Asset
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
__all__ = ["Task", "Tasker", "AnsiblePlay", "AnsibleTask", "AnsibleHostResult"] __all__ = ["Task", "TaskRecord", "AnsiblePlay", "AnsibleTask", "AnsibleHostResult"]
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Tasker(models.Model): class TaskRecord(models.Model):
uuid = models.CharField(max_length=128, verbose_name=_('UUID'), primary_key=True) uuid = models.CharField(max_length=128, verbose_name=_('UUID'), primary_key=True)
name = models.CharField(max_length=128, blank=True, verbose_name=_('Name')) name = models.CharField(max_length=128, blank=True, verbose_name=_('Name'))
start = models.DateTimeField(auto_now_add=True, verbose_name=_('Start Time')) start = models.DateTimeField(auto_now_add=True, verbose_name=_('Start Time'))
...@@ -51,7 +51,7 @@ class Tasker(models.Model): ...@@ -51,7 +51,7 @@ class Tasker(models.Model):
class AnsiblePlay(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) uuid = models.CharField(max_length=128, verbose_name=_('UUID'), primary_key=True)
name = models.CharField(max_length=128, verbose_name=_('Name')) name = models.CharField(max_length=128, verbose_name=_('Name'))
...@@ -73,7 +73,7 @@ class AnsiblePlay(models.Model): ...@@ -73,7 +73,7 @@ class AnsiblePlay(models.Model):
name=forgery_py.name.full_name(), name=forgery_py.name.full_name(),
) )
try: try:
play.tasker = choice(Tasker.objects.all()) play.tasker = choice(TaskRecord.objects.all())
play.save() play.save()
logger.debug('Generate fake play: %s' % play.name) logger.debug('Generate fake play: %s' % play.name)
except Exception as e: except Exception as e:
...@@ -293,8 +293,16 @@ class AnsibleHostResult(models.Model): ...@@ -293,8 +293,16 @@ class AnsibleHostResult(models.Model):
continue continue
class Task(models.Model): class Task(models.Model):
record = models.OneToOneField(TaskRecord)
name = models.CharField(max_length=128, blank=True, verbose_name=_('Name')) 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): def __unicode__(self):
return "%s %s" % (self.module_name, self.module_args)
def run(self):
pass pass
...@@ -5,7 +5,7 @@ import logging ...@@ -5,7 +5,7 @@ import logging
from jinja2 import Template from jinja2 import Template
from django.db import models from django.db import models
from django.utils import timezone from django.utils.timezone import now
from assets.models import Asset, AssetGroup from assets.models import Asset, AssetGroup
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
...@@ -174,7 +174,7 @@ class Sudo(models.Model): ...@@ -174,7 +174,7 @@ class Sudo(models.Model):
name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'), name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'),
help_text=_('Name for this sudo')) 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')) help_text=_('The create time of this sudo'))
modify_time = models.DateTimeField(auto_now=True, verbose_name=_('Modify Time'), modify_time = models.DateTimeField(auto_now=True, verbose_name=_('Modify Time'),
help_text=_('The recent modify time of this sudo')) help_text=_('The recent modify time of this sudo'))
...@@ -310,7 +310,7 @@ root ALL=(ALL:ALL) ALL ...@@ -310,7 +310,7 @@ root ALL=(ALL:ALL) ALL
seed() seed()
for i in range(count): for i in range(count):
sudo = cls(name=forgery_py.name.full_name(), sudo = cls(name=forgery_py.name.full_name(),
created_time=timezone.now() created_time=now()
) )
try: try:
sudo.save() sudo.save()
......
...@@ -9,6 +9,6 @@ __all__ = ["generate_fake"] ...@@ -9,6 +9,6 @@ __all__ = ["generate_fake"]
def 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): HostAlia, UserAlia, CmdAlia, RunasAlia, Privilege, Sudo):
cls.generate_fake() cls.generate_fake()
\ No newline at end of file
...@@ -3,7 +3,7 @@ from __future__ import unicode_literals ...@@ -3,7 +3,7 @@ from __future__ import unicode_literals
from ops.tasks import _celery_tasks from ops.tasks import _celery_tasks
from ops.models import Tasker from ops.models import TaskRecord
from uuid import uuid1 from uuid import uuid1
from celery.result import AsyncResult from celery.result import AsyncResult
...@@ -23,7 +23,7 @@ def get_result(task_id): ...@@ -23,7 +23,7 @@ def get_result(task_id):
def __get_result_by_tasker_id(tasker_uuid, deal_method): 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 = tasker.total_hosts
total_len = len(total) total_len = len(total)
host_results = [] host_results = []
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
{% block table_search %} {% block table_search %}
{% endblock %} {% endblock %}
{% block table_container %} {% 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>#} {#<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"> <table class="table table-striped table-bordered table-hover " id="sudo_list_table">
<thead> <thead>
...@@ -12,8 +12,9 @@ ...@@ -12,8 +12,9 @@
<input id="" type="checkbox" class="ipt_check_all"> <input id="" type="checkbox" class="ipt_check_all">
</th> </th>
<th class="text-center">{% trans 'Name' %}</th> <th class="text-center">{% trans 'Name' %}</th>
<th class="text-center">{% trans 'Privileges' %}</th> <th class="text-center">{% trans 'UUID' %}</th>
<th class="text-center">{% trans 'Extra Lines' %}</th> <th class="text-center">{% trans 'Start' %}</th>
<th class="text-center">{% trans 'Completed' %}</th>
<th class="text-center">{% trans 'Action' %}</th> <th class="text-center">{% trans 'Action' %}</th>
</tr> </tr>
...@@ -35,8 +36,6 @@ ...@@ -35,8 +36,6 @@
</div> </div>
</div> </div>
</div> </div>
{#{% include "users/_user_bulk_update_modal.html" %}#}
{#{% include "users/_user_import_modal.html" %}#}
{% endblock %} {% endblock %}
{% block content_bottom_left %}{% endblock %} {% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
...@@ -47,23 +46,23 @@ $(document).ready(function(){ ...@@ -47,23 +46,23 @@ $(document).ready(function(){
ele: $('#sudo_list_table'), ele: $('#sudo_list_table'),
columnDefs: [ columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) { {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)); $(td).html(detail_btn.replace('99991937', rowData.id));
}}, }},
{targets: 4, createdCell: function (td, cellData, rowData) { {targets: 3, createdCell: function (td, cellData) {
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); if (!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); $(td).html('<i class="fa fa-times text-danger"></i>')
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);
if (rowData.id === 1 || rowData.username == "admin") {
$(td).html(update_btn)
} else { } else {
$(td).html(preview_btn + job_btn + update_btn + del_btn) $(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)
}}], }}],
ajax_url: '{% url "api-ops:sudo-list" %}', ajax_url: '{% url "api-ops:task-list" %}',
columns: [{data: "id"}, {data: "name" }, {data: "privilege_items" }, {data: "extra_lines" }, {data: "id" }], columns: [{data: "name"}, {data: "uuid" }, {data: "start" }, {data: "completed" }, {data: "id" }],
op_html: $('#actions').html() op_html: $('#actions').html()
}; };
var table = jumpserver.initDataTable(options); var table = jumpserver.initDataTable(options);
......
...@@ -15,5 +15,6 @@ api_router.register(r'v1/extra_conf', v1_api.ExtraconfViewSet) ...@@ -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/privilege', v1_api.PrivilegeViewSet)
api_router.register(r'v1/sudo', v1_api.SudoViewSet) api_router.register(r'v1/sudo', v1_api.SudoViewSet)
api_router.register(r'v1/cron', v1_api.CronTableViewSet) api_router.register(r'v1/cron', v1_api.CronTableViewSet)
api_router.register(r'v1/task', v1_api.TaskViewSet)
urlpatterns = api_router.urls urlpatterns = api_router.urls
\ No newline at end of file
...@@ -19,4 +19,10 @@ urlpatterns = [ ...@@ -19,4 +19,10 @@ urlpatterns = [
url(r'^cron/create$', page_view.CronCreateView.as_view(), name='page-cron-create'), 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]+)/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'), 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'),
] ]
\ No newline at end of file
...@@ -18,7 +18,7 @@ from ansible.utils.display import Display ...@@ -18,7 +18,7 @@ from ansible.utils.display import Display
from ansible.playbook.play import Play from ansible.playbook.play import Play
from ansible.plugins.callback import CallbackBase 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__) logger = logging.getLogger(__name__)
...@@ -196,7 +196,7 @@ class CallbackModule(CallbackBase): ...@@ -196,7 +196,7 @@ class CallbackModule(CallbackBase):
} }
try: 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 = AnsiblePlay(tasker, name=ret['name'], uuid=ret['uuid'])
play.save() play.save()
except Exception as e: except Exception as e:
...@@ -429,7 +429,7 @@ class ADHocRunner(InventoryMixin): ...@@ -429,7 +429,7 @@ class ADHocRunner(InventoryMixin):
@staticmethod @staticmethod
def update_db_tasker(tasker_id, ext_code): def update_db_tasker(tasker_id, ext_code):
try: try:
tasker = Tasker.objects.get(uuid=tasker_id) tasker = TaskRecord.objects.get(uuid=tasker_id)
tasker.end = timezone.now() tasker.end = timezone.now()
tasker.completed = True tasker.completed = True
tasker.exit_code = ext_code tasker.exit_code = ext_code
...@@ -440,7 +440,7 @@ class ADHocRunner(InventoryMixin): ...@@ -440,7 +440,7 @@ class ADHocRunner(InventoryMixin):
def create_db_tasker(self, name, uuid): def create_db_tasker(self, name, uuid):
try: try:
hosts = [host.get('name') for host in self.hosts] 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() tasker.save()
except Exception as e: except Exception as e:
logger.error("Save Tasker to database error!, %s" % e.message) logger.error("Save Tasker to database error!, %s" % e.message)
......
...@@ -56,3 +56,32 @@ class CronDetailView(DetailView): ...@@ -56,3 +56,32 @@ class CronDetailView(DetailView):
context_object_name = 'cron' context_object_name = 'cron'
template_name = 'cron/detail.html' 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 @@ ...@@ -46,6 +46,7 @@
<i class="fa fa-coffee"></i> <span class="nav-label">{% trans 'Job Center' %}</span><span class="fa arrow"></span> <i class="fa fa-coffee"></i> <span class="nav-label">{% trans 'Job Center' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <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="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> <li id="cron"><a href="{% url 'ops:page-cron-list' %}">{% trans 'Cron' %}</a></li>
</ul> </ul>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment