Commit caec9709 authored by ibuler's avatar ibuler

[Fixture] 添加task list 搜索,重试

parent a4504dc0
...@@ -12,8 +12,8 @@ def update_assets_hardware_info(assets): ...@@ -12,8 +12,8 @@ def update_assets_hardware_info(assets):
task_tuple = ( task_tuple = (
('setup', ''), ('setup', ''),
) )
task = run_AdHoc.delay(task_tuple, assets, record=False) task_name = ','.join([asset.hostname for asset in assets])
summary, result = task.get(timeout=60*10) summary, result = run_AdHoc(task_tuple, assets, record=True, task_name=task_name)
for hostname, info in result['contacted'].items(): for hostname, info in result['contacted'].items():
if info: if info:
info = info[0]['ansible_facts'] info = info[0]['ansible_facts']
......
...@@ -46,12 +46,12 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView): ...@@ -46,12 +46,12 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView):
filter_kwargs = {} filter_kwargs = {}
if self.date_from_s: if self.date_from_s:
date_from = datetime.strptime(self.date_from_s, self.date_format) date_from = datetime.strptime(self.date_from_s, self.date_format)
date_from.replace(tzinfo=timezone.get_current_timezone()) date_from = date_from.replace(tzinfo=timezone.get_current_timezone())
filter_kwargs['date_start__gt'] = date_from filter_kwargs['date_start__gt'] = date_from
if self.date_to_s: if self.date_to_s:
date_to = timezone.datetime.strptime( date_to = timezone.datetime.strptime(
self.date_to_s + ' 23:59:59', '%m/%d/%Y %H:%M:%S') self.date_to_s + ' 23:59:59', '%m/%d/%Y %H:%M:%S')
date_to.replace(tzinfo=timezone.get_current_timezone()) date_to = date_to.replace(tzinfo=timezone.get_current_timezone())
filter_kwargs['date_start__lt'] = date_to filter_kwargs['date_start__lt'] = date_to
if self.user: if self.user:
filter_kwargs['user'] = self.user filter_kwargs['user'] = self.user
...@@ -64,6 +64,8 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView): ...@@ -64,6 +64,8 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView):
Q(user__icontains=self.keyword) | Q(user__icontains=self.keyword) |
Q(asset__icontains=self.keyword) | Q(asset__icontains=self.keyword) |
Q(system_user__icontains=self.keyword)).distinct() Q(system_user__icontains=self.keyword)).distinct()
if filter_kwargs:
self.queryset = self.queryset.filter(**filter_kwargs)
return self.queryset return self.queryset
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
......
...@@ -19,7 +19,7 @@ from .callback import AdHocResultCallback, PlaybookResultCallBack, \ ...@@ -19,7 +19,7 @@ from .callback import AdHocResultCallback, PlaybookResultCallBack, \
from common.utils import get_logger from common.utils import get_logger
__all__ = ["ADHocRunner", "Options"] __all__ = ["AdHocRunner", "PlayBookRunner"]
C.HOST_KEY_CHECKING = False C.HOST_KEY_CHECKING = False
......
...@@ -8,13 +8,13 @@ import json ...@@ -8,13 +8,13 @@ import json
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__ = ["TaskRecord"] __all__ = ["Task"]
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class TaskRecord(models.Model): class Task(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'))
date_start = models.DateTimeField(auto_now_add=True, verbose_name=_('Start time')) date_start = models.DateTimeField(auto_now_add=True, verbose_name=_('Start time'))
......
...@@ -2,108 +2,21 @@ ...@@ -2,108 +2,21 @@
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
import json
import time
from celery import shared_task from celery import shared_task
from django.utils import timezone
from assets.models import Asset from common.utils import get_logger
from common.utils import get_logger, encrypt_password from .utils import run_AdHoc
from .ansible.runner import AdHocRunner
logger = get_logger(__file__) logger = get_logger(__file__)
@shared_task(bind=True) @shared_task
def run_AdHoc(self, task_tuple, assets, def rerun_task(task_id):
task_name='Ansible AdHoc runner', from .models import Task
pattern='all', record=True): record = Task.objects.get(uuid=task_id)
if not assets:
logger.warning('Empty assets, runner cancel')
if isinstance(assets[0], Asset):
assets = [asset._to_secret_json() for asset in assets]
runner = AdHocRunner(assets)
if record:
from .models import TaskRecord
if not TaskRecord.objects.filter(uuid=self.request.id):
record = TaskRecord(uuid=self.request.id,
name=task_name,
assets=','.join(str(asset['id']) for asset in assets),
module_args=task_tuple,
pattern=pattern)
record.save()
else:
record = TaskRecord.objects.get(uuid=self.request.id)
record.date_start = timezone.now()
ts_start = time.time()
logger.warn('Start runner {}'.format(task_name))
result = runner.run(task_tuple, pattern=pattern, task_name=task_name)
timedelta = round(time.time() - ts_start, 2)
summary = runner.clean_result()
if record:
record.date_finished = timezone.now()
record.is_finished = True
record.result = json.dumps(result)
record.summary = json.dumps(summary)
record.timedelta = timedelta
if len(summary['failed']) == 0:
record.is_success = True
else:
record.is_success = False
record.save()
return summary, result
def rerun_AdHoc(uuid):
from .models import TaskRecord
record = TaskRecord.objects.get(uuid=uuid)
assets = record.assets_json assets = record.assets_json
task_tuple = record.module_args task_tuple = record.module_args
pattern = record.pattern pattern = record.pattern
task_name = record.name task_name = record.name
task = run_AdHoc.apply_async((task_tuple, assets), return run_AdHoc(task_tuple, assets, pattern=pattern,
{'pattern': pattern, 'task_name': task_name}, task_name=task_name, task_id=task_id)
task_id=uuid)
return task
def push_users(assets, users):
"""
user: {
name: 'web',
username: 'web',
shell: '/bin/bash',
password: '123123123',
public_key: 'string',
sudo: '/bin/whoami,/sbin/ifconfig'
}
"""
if isinstance(users, dict):
users = [users]
if isinstance(assets, dict):
assets = [assets]
task_tuple = []
for user in users:
# 添加用户, 设置公钥, 设置sudo
task_tuple.extend([
('user', 'name={} shell={} state=present password={}'.format(
user['username'], user.get('shell', '/bin/bash'),
encrypt_password(user.get('password', None)))),
('authorized_key', "user={} state=present key='{}'".format(
user['username'], user['public_key'])),
('lineinfile',
"name=/etc/sudoers state=present regexp='^{0} ALL=(ALL)' "
"line='{0} ALL=(ALL) NOPASSWD: {1}' "
"validate='visudo -cf %s'".format(
user['username'], user.get('sudo', '/bin/whoami')
))
])
task_name = 'Push user {}'.format(','.join([user['name'] for user in users]))
task = run_AdHoc.delay(task_tuple, assets, pattern='all', task_name=task_name)
return task
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
</tr> </tr>
<tr> <tr>
<td>{% trans 'Date start' %}:</td> <td>{% trans 'Date start' %}:</td>
<td><b>{{ object.date_start}}</b></td> <td><b>{{ object.date_start }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Date finished' %}:</td> <td>{% trans 'Date finished' %}:</td>
...@@ -64,11 +64,11 @@ ...@@ -64,11 +64,11 @@
</tr> </tr>
<tr> <tr>
<td>{% trans 'Is finished' %}:</td> <td>{% trans 'Is finished' %}:</td>
<td><b>{{ object.is_finished }}</b></td> <td><b>{{ object.is_finished|yesno:"Yes,No,Unkown" }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Is success ' %}:</td> <td>{% trans 'Is success ' %}:</td>
<td><b>{{ object.is_success }}</b></td> <td><b>{{ object.is_success|yesno:"Yes,No,Unkown" }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Assets ' %}:</td> <td>{% trans 'Assets ' %}:</td>
......
...@@ -46,10 +46,10 @@ ...@@ -46,10 +46,10 @@
{% endblock %} {% endblock %}
{% block table_body %} {% block table_body %}
{% for object in task_record_list %} {% for object in task_list %}
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center"><input type="checkbox" class="cbx-term"> </td> <td class="text-center"><input type="checkbox" class="cbx-term"> </td>
<td class="text-center"><a href="{% url 'ops:task-record-detail' pk=object.uuid %}">{{ object.name }}</a></td> <td class="text-center"><a href="{% url 'ops:task-detail' pk=object.uuid %}">{{ object.name }}</a></td>
<td class="text-center">{{ object.total_assets|length }}</td> <td class="text-center">{{ object.total_assets|length }}</td>
<td class="text-center"> <td class="text-center">
{% if object.is_success %} {% if object.is_success %}
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
<td class="text-center">{{ object.date_start }}</td> <td class="text-center">{{ object.date_start }}</td>
<td class="text-center">{{ object.timedelta }} s</td> <td class="text-center">{{ object.timedelta }} s</td>
<td class="text-center"> <td class="text-center">
<a href="" class="btn btn-xs btn-info">{% trans "Repush" %}</a> <a href="{% url 'ops:task-run' pk=object.uuid %}" class="btn btn-xs btn-info">{% trans "Run again" %}</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -9,6 +9,7 @@ __all__ = ["urlpatterns"] ...@@ -9,6 +9,7 @@ __all__ = ["urlpatterns"]
urlpatterns = [ urlpatterns = [
# TResource Task url # TResource Task url
url(r'^task-record/$', views.TaskRecordListView.as_view(), name='task-record-list'), url(r'^task/$', views.TaskListView.as_view(), name='task-list'),
url(r'^task-record/(?P<pk>[0-9a-zA-Z-]+)/$', views.TaskRecordDetailView.as_view(), name='task-record-detail'), url(r'^task/(?P<pk>[0-9a-zA-Z-]+)/$', views.TaskDetailView.as_view(), name='task-detail'),
url(r'^task/(?P<pk>[0-9a-zA-Z-]+)/run/$', views.TaskRunView.as_view(), name='task-run'),
] ]
\ No newline at end of file
...@@ -17,7 +17,8 @@ logger = get_logger(__file__) ...@@ -17,7 +17,8 @@ logger = get_logger(__file__)
def run_AdHoc(task_tuple, assets, def run_AdHoc(task_tuple, assets,
task_name='Ansible AdHoc runner', task_name='Ansible AdHoc runner',
task_id=None, pattern='all', record=True): task_id=None, pattern='all',
record=True, verbose=False):
if not assets: if not assets:
logger.warning('Empty assets, runner cancel') logger.warning('Empty assets, runner cancel')
...@@ -29,26 +30,28 @@ def run_AdHoc(task_tuple, assets, ...@@ -29,26 +30,28 @@ def run_AdHoc(task_tuple, assets,
runner = AdHocRunner(assets) runner = AdHocRunner(assets)
if record: if record:
from .models import TaskRecord from .models import Task
if not TaskRecord.objects.filter(uuid=task_id): if not Task.objects.filter(uuid=task_id):
record = TaskRecord(uuid=task_id, record = Task(uuid=task_id,
name=task_name, name=task_name,
assets=','.join(str(asset['id']) for asset in assets), assets=','.join(str(asset['id']) for asset in assets),
module_args=task_tuple, module_args=task_tuple,
pattern=pattern) pattern=pattern)
record.save() record.save()
else: else:
record = TaskRecord.objects.get(uuid=task_id) record = Task.objects.get(uuid=task_id)
record.date_start = timezone.now() record.date_start = timezone.now()
ts_start = time.time() ts_start = time.time()
logger.warn('Start runner {}'.format(task_name)) if verbose:
logger.debug('Start runner {}'.format(task_name))
result = runner.run(task_tuple, pattern=pattern, task_name=task_name) result = runner.run(task_tuple, pattern=pattern, task_name=task_name)
timedelta = round(time.time() - ts_start, 2) timedelta = round(time.time() - ts_start, 2)
summary = runner.clean_result() summary = runner.clean_result()
if record: if record:
record.date_finished = timezone.now() record.date_finished = timezone.now()
record.is_finished = True record.is_finished = True
record.result = json.dumps(result) if verbose:
record.result = json.dumps(result)
record.summary = json.dumps(summary) record.summary = json.dumps(summary)
record.timedelta = timedelta record.timedelta = timedelta
if len(summary['failed']) == 0: if len(summary['failed']) == 0:
...@@ -57,21 +60,3 @@ def run_AdHoc(task_tuple, assets, ...@@ -57,21 +60,3 @@ def run_AdHoc(task_tuple, assets,
record.is_success = False record.is_success = False
record.save() record.save()
return summary, result return summary, result
def rerun_AdHoc(task_id):
from .models import TaskRecord
record = TaskRecord.objects.get(uuid=task_id)
assets = record.assets_json
task_tuple = record.module_args
pattern = record.pattern
task_name = record.name
return run_AdHoc(task_tuple, assets, pattern=pattern,
task_name=task_name, task_id=task_id)
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals from __future__ import unicode_literals
import json import json
from datetime import datetime
from django.conf import settings from django.conf import settings
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView, View
from django.utils import timezone
from django.shortcuts import redirect, reverse
from .models import TaskRecord from .models import Task
from ops.tasks import rerun_task
class TaskRecordListView(ListView): class TaskListView(ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
model = TaskRecord model = Task
ordering = ('-date_start',) ordering = ('-date_start',)
context_object_name = 'task_record_list' context_object_name = 'task_list'
template_name = 'ops/task_record_list.html' template_name = 'ops/task_list.html'
date_format = '%m/%d/%Y'
keyword = date_from_s = date_to_s = ''
def get_queryset(self):
date_now = timezone.localtime(timezone.now())
date_to_default = date_now.strftime(self.date_format)
date_from_default = (date_now - timezone.timedelta(7)) \
.strftime(self.date_format)
self.queryset = super(TaskListView, self).get_queryset()
self.keyword = self.request.GET.get('keyword', '')
self.date_from_s = self.request.GET.get('date_from', date_from_default)
self.date_to_s = self.request.GET.get('date_to', date_to_default)
if self.date_from_s:
date_from = datetime.strptime(self.date_from_s, self.date_format)
date_from = date_from.replace(tzinfo=timezone.get_current_timezone())
self.queryset = self.queryset.filter(date_start__gt=date_from)
if self.date_to_s:
date_to = timezone.datetime.strptime(
self.date_to_s + ' 23:59:59', '%m/%d/%Y %H:%M:%S')
date_to = date_to.replace(tzinfo=timezone.get_current_timezone())
self.queryset = self.queryset.filter(date_finished__lt=date_to)
if self.keyword:
self.queryset = self.queryset.filter(
name__icontains=self.keyword,
)
return self.queryset
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': 'Ops', 'app': 'Ops',
'action': 'Task record list', 'action': 'Task record list',
'date_from': self.date_from_s,
'date_to': self.date_to_s,
'keyword': self.keyword,
} }
kwargs.update(context) kwargs.update(context)
return super(TaskRecordListView, self).get_context_data(**kwargs) return super(TaskListView, self).get_context_data(**kwargs)
class TaskRecordDetailView(DetailView): class TaskDetailView(DetailView):
model = TaskRecord model = Task
template_name = 'ops/task_record_detail.html' template_name = 'ops/task_detail.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
...@@ -36,4 +72,13 @@ class TaskRecordDetailView(DetailView): ...@@ -36,4 +72,13 @@ class TaskRecordDetailView(DetailView):
'results': json.loads(self.object.summary), 'results': json.loads(self.object.summary),
} }
kwargs.update(context) kwargs.update(context)
return super(TaskRecordDetailView, self).get_context_data(**kwargs) return super(TaskDetailView, self).get_context_data(**kwargs)
class TaskRunView(View):
pk_url_kwarg = 'pk'
def get(self, request, *args, **kwargs):
pk = kwargs.get(self.pk_url_kwarg)
rerun_task.delay(pk)
return redirect(reverse('ops:task-detail', kwargs={'pk': pk}))
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from common.utils import setattr_bulk, get_logger from common.utils import setattr_bulk, get_logger
from ops.tasks import push_users from .tasks import push_users
from .hands import User, UserGroup, Asset, AssetGroup, SystemUser from .hands import User, UserGroup, Asset, AssetGroup, SystemUser
logger = get_logger(__file__) logger = get_logger(__file__)
...@@ -231,7 +231,7 @@ def push_system_user(assets, system_user): ...@@ -231,7 +231,7 @@ def push_system_user(assets, system_user):
assets = [asset._to_secret_json() for asset in assets] assets = [asset._to_secret_json() for asset in assets]
system_user = system_user._to_secret_json() system_user = system_user._to_secret_json()
task = push_users(assets, system_user) task = push_users.delay(assets, system_user)
return task.id return task.id
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,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-record"><a href="{% url 'ops:task-record-list' %}">{% trans 'Task Record' %}</a></li> <li id="task"><a href="{% url 'ops:task-list' %}">{% trans 'Task' %}</a></li>
</ul> </ul>
</li> </li>
......
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