[Bugfix] 修复ops一些功能的bug

pull/828/merge
ibuler 7 years ago
parent 3f89701b84
commit 5a92972120

@ -1,15 +1,16 @@
# -*- coding: utf-8 -*-
#
from django.utils.translation import ugettext as _
PUSH_SYSTEM_USER_PERIOD_LOCK_KEY = "PUSH_SYSTEM_USER_PERIOD_KEY"
PUSH_SYSTEM_USER_PERIOD_TASK_NAME = "PUSH-SYSTEM-USER-PERIOD"
PUSH_SYSTEM_USER_TASK_NAME = "PUSH-SYSTEM-USER-TO-CLUSTER-{}"
PUSH_SYSTEM_USER_PERIOD_TASK_NAME = _("PUSH SYSTEM USER TO CLUSTER PERIOD TASK")
PUSH_SYSTEM_USER_TASK_NAME = _("PUSH SYSTEM USER TO CLUSTER: {}")
PUSH_SYSTEM_USER_LOCK_KEY = "PUSH_SYSTEM_USER_TO_CLUSTER_LOCK_{}"
UPDATE_ASSETS_HARDWARE_TASK_NAME = 'UPDATE-ASSETS-HARDWARE-INFO'
UPDATE_ASSETS_HARDWARE_TASK_NAME = _('UPDATE ASSETS HARDWARE INFO')
UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY = "UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY"
UPDATE_ASSETS_HARDWARE_PERIOD_TASK_NAME = 'UPDATE-ASSETS-HARDWARE-INFO-PERIOD'
UPDATE_ASSETS_HARDWARE_PERIOD_TASK_NAME = _('UPDATE ASSETS HARDWARE INFO PERIOD')
UPDATE_ASSETS_HARDWARE_TASKS = [
{
'name': UPDATE_ASSETS_HARDWARE_TASK_NAME,
@ -20,8 +21,8 @@ UPDATE_ASSETS_HARDWARE_TASKS = [
]
TEST_ADMIN_USER_CONN_PERIOD_LOCK_KEY = "TEST_ADMIN_USER_CONN_PERIOD_KEY"
TEST_ADMIN_USER_CONN_PERIOD_TASK_NAME = "TEST_ADMIN_USER_CONN_PERIOD_TASK"
TEST_ADMIN_USER_CONN_TASK_NAME = "TEST-ADMIN-USER-CONN-{}"
TEST_ADMIN_USER_CONN_PERIOD_TASK_NAME = _("TEST ADMIN USER CONN PERIOD TASK")
TEST_ADMIN_USER_CONN_TASK_NAME = _("TEST ADMIN USER CONN: {}")
TEST_ADMIN_USER_CONN_LOCK_KEY = TEST_ADMIN_USER_CONN_TASK_NAME
ADMIN_USER_CONN_CACHE_KEY = "ADMIN_USER_CONN_{}"
TEST_ADMIN_USER_CONN_TASKS = [
@ -34,12 +35,12 @@ TEST_ADMIN_USER_CONN_TASKS = [
]
ASSET_ADMIN_CONN_CACHE_KEY = "ASSET_ADMIN_USER_CONN_{}"
TEST_ASSET_CONN_TASK_NAME = "ASSET_CONN_TEST_MANUAL"
TEST_ASSET_CONN_TASK_NAME = _("ASSET CONN TEST MANUAL")
TEST_SYSTEM_USER_CONN_PERIOD_LOCK_KEY = "TEST_SYSTEM_USER_CONN_PERIOD_KEY"
TEST_SYSTEM_USER_CONN_PERIOD_TASK_NAME = "TEST-SYSTEM-USER-CONN-PERIOD-TASK"
TEST_SYSTEM_USER_CONN_PERIOD_TASK_NAME = _("TEST SYSTEM USER CONN PERIOD TASK")
TEST_SYSTEM_USER_CONN_CACHE_KEY_PREFIX = "SYSTEM_USER_CONN_"
TEST_SYSTEM_USER_CONN_TASK_NAME = "TEST-SYSTEM-USER-CONN-{}"
TEST_SYSTEM_USER_CONN_TASK_NAME = _("TEST SYSTEM USER CONN: {}")
TEST_SYSTEM_USER_CONN_LOCK_KEY = "TEST_SYSTEM_USER_CONN_{}"
SYSTEM_USER_CONN_CACHE_KEY = "SYSTEM_USER_CONN_{}"
TEST_SYSTEM_USER_CONN_TASKS = [

File diff suppressed because it is too large Load Diff

@ -35,8 +35,13 @@ class AdHocRunHistorySet(viewsets.ModelViewSet):
def get_queryset(self):
task_id = self.request.query_params.get('task')
adhoc_id = self.request.query_params.get('adhoc')
if task_id:
task = get_object_or_404(Task, id=task_id)
adhocs = task.adhoc.all()
self.queryset = self.queryset.filter(adhoc__in=adhocs)
if adhoc_id:
adhoc = get_object_or_404(AdHoc, id=adhoc_id)
self.queryset = self.queryset.filter(adhoc=adhoc)
return self.queryset

@ -222,6 +222,14 @@ class AdHocRunHistory(models.Model):
def summary(self, item):
self._summary = json.dumps(item)
@property
def success_hosts(self):
return self.summary.get('contacted', [])
@property
def failed_hosts(self):
return self.summary.get('dark', {})
def __str__(self):
return self.short_id

@ -0,0 +1,191 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active">
<a href="{% url 'ops:adhoc-detail' pk=object.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Version detail' %} </a>
</li>
<li>
<a href="{% url 'ops:adhoc-history' pk=object.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Version run history' %} </a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label"><b>{{ object.task.name }}: {{ object.short_id }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="20%">{% trans 'ID' %}:</td>
<td><b>{{ object.id }}</b></td>
</tr>
<tr>
<td width="20%">{% trans 'Hosts' %}:</td>
<td><b>{{ object.hosts | length }}</b></td>
</tr>
<tr>
<td width="20%">{% trans 'Pattern' %}:</td>
<td><b>{{ object.pattern }}</b></td>
</tr>
<tr>
<td>{% trans 'Options' %}</td>
<td>
<b>
{% for k, v in object.options.items %}
{{ k }} = {{ v }} <br/>
{% endfor %}
</b>
</td>
</tr>
{% if object.run_as_admin %}
<tr>
<td>{% trans 'Run as' %}</td>
<td><b> Admin </b></td>
</tr>
{% else %}
<tr>
<td>{% trans 'Run as' %}:</td>
<td><b>{{ object.get_latest_history.date_start }}</b></td>
</tr>
{% endif %}
<tr>
<td>{% trans 'Become' %}</td>
<td><b>{{ object.become.user }}</b></td>
</tr>
<tr>
<td>{% trans 'Created by' %}</td>
<td><b>{{ object.created_by }}</b></td>
</tr>
<tr>
<td>{% trans 'Date created' %}:</td>
<td><b>{{ object.date_created }}</b></td>
</tr>
<tr>
<td>{% trans 'Run times' %}:</td>
<td><b>{{ object.history.all | length }}</b></td>
</tr>
<tr>
<td>{% trans 'Last run' %}:</td>
<td><b>{{ object.latest_history.short_id }}</b></td>
</tr>
<tr>
<td>{% trans 'Time delta' %}:</td>
<td><b>{{ object.latest_history.timedelta|floatformat}} s</b></td>
</tr>
<tr>
<td>{% trans 'Is finished' %}:</td>
<td><b>{{ object.latest_history.is_finished|yesno:"Yes,No,Unkown" }}</b></td>
</tr>
<tr>
<td>{% trans 'Is success ' %}:</td>
<td><b>{{ object.latest_history.is_success|yesno:"Yes,No,Unkown" }}</b></td>
</tr>
<tr>
<td>{% trans 'Tasks' %}:</td>
<td>
<b>
{% for task in object.tasks %}
{{ forloop.counter }}. {{ task.name }} ::: {{ task.action.module }} <br/>
{% endfor %}
</b>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-danger">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Last run failed hosts' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
{% for host, task in object.latest_history.failed_hosts.items %}
{% if forloop.first %}
<tr class="no-borders-tr">
{% else %}
<tr>
{% endif %}
<td>{{ host }}: </td>
<td>
{% for name, result in task.items %}
<b>{{ name }}</b> => {{ result.msg }}
{% endfor %}
</td>
</tr>
{% empty %}
<tr class="no-borders-tr">
<td>{% trans 'No hosts' %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Last run success hosts' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
{% for host in object.latest_history.success_hosts %}
{% if forloop.first %}
<tr class="no-borders-tr">
{% else %}
<tr>
{% endif %}
<td>{{ host }}</td>
</tr>
{% empty %}
<tr class="no-borders-tr">
<td>{% trans 'No hosts' %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% include 'users/_user_update_pk_modal.html' %}
{% endblock %}

@ -0,0 +1,147 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li>
<a href="{% url 'ops:adhoc-detail' pk=object.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Version detail' %} </a>
</li>
<li class="active">
<a href="{% url 'ops:adhoc-history' pk=object.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Version run history' %} </a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-12" style="padding-left: 0">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left">{% trans 'History of ' %} <b>{{ object.task.name }}:{{ object.short_id }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover " id="task-history-list-table" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" class="ipt_check_all" >
</th>
<th>{% trans 'Date start' %}</th>
<th>{% trans 'F/S/T' %}</th>
<th>{% trans 'Ratio' %}</th>
<th>{% trans 'Is finished' %}</th>
<th>{% trans 'Is success' %}</th>
<th>{% trans 'Time' %}</th>
<th>{% trans 'Version' %}</th>
<th>{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
function initTable() {
var options = {
ele: $('#task-history-list-table'),
buttons: [],
order: [],
select: [],
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
$(td).html(cellData);
}},
{targets: 2, createdCell: function (td, cellData) {
var total = "<span>" + cellData.total + "</span>";
var success = "<span class='text-navy'>" + cellData.success + "</span>";
var failed = "<span class='text-danger'>" + cellData.failed + "</span>";
$(td).html(failed + '/' + success + '/' + total );
}},
{targets: 3, createdCell: function (td, cellData) {
var val = 0;
var innerHtml = "";
if (cellData.total !== 0) {
val = cellData.success/cellData.total * 100;
}
if (val === 100) {
innerHtml = "<span class='text-navy'>" + val + "% </span>";
} else {
innerHtml = "<span class='text-danger'>" + val + "% </span>";
}
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
}},
{targets: 4, 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: 5, 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: 6, createdCell: function (td, cellData) {
if (cellData) {
$(td).html(cellData.toFixed(2) + ' s')
} else {
$(td).html("0" + ' s')
}
}},
{targets: 8, createdCell: function (td, cellData) {
var run_btn = '<a class="btn btn-xs btn-primary m-l-xs btn-run" href="{% url 'ops:adhoc-history-detail' pk=DEFAULT_PK %}">{% trans "Detail" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
if (cellData) {
$(td).html(run_btn);
}
}}
],
ajax_url: '{% url "api-ops:history-list" %}?adhoc={{ object.pk }}',
columns: [{data: function(){return ""}}, {data: "date_start"}, {data: "stat"}, {data: "stat"}, {data: "is_finished"},
{data: "is_success"}, {data: "timedelta"}, {data: 'adhoc_short_id'}, {data: "id"}]
};
jumpserver.initDataTable(options);
}
$(document).ready(function () {
initTable();
})
</script>
{% endblock %}

@ -0,0 +1,141 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active">
<a href="{% url 'ops:adhoc-history-detail' pk=object.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Run history detail' %} </a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label"><b>{% trans 'History detail of' %} {{ object.task.name }}: {{ object.adhoc.short_id }} </b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="20%">{% trans 'ID' %}:</td>
<td><b>{{ object.id }}</b></td>
</tr>
<tr>
<td width="20%">{% trans 'Task name' %}:</td>
<td><b>{{ object.task.name }}</b></td>
</tr>
<tr>
<td>{% trans 'Version' %}:</td>
<td><b>{{ object.adhoc.short_id }}</b></td>
</tr>
<tr>
<td>{% trans 'Date start' %}:</td>
<td><b>{{ object.date_start }}</b></td>
</tr>
<tr>
<td>{% trans 'Time delta' %}:</td>
<td><b>{{ object.timedelta|floatformat}} s</b></td>
</tr>
<tr>
<td>{% trans 'Is finished' %}:</td>
<td><b>{{ object.is_finished|yesno:"Yes,No,Unkown" }}</b></td>
</tr>
<tr>
<td>{% trans 'Is success ' %}:</td>
<td><b>{{ object.is_success|yesno:"Yes,No,Unkown" }}</b></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-danger">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Failed assets' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
{% for host, task in object.failed_hosts.items %}
{% if forloop.first %}
<tr class="no-borders-tr">
{% else %}
<tr>
{% endif %}
<td>{{ host }}: </td>
<td>
{% for name, result in task.items %}
<b>{{ name }}</b> => {{ result.msg }}
{% endfor %}
</td>
</tr>
{% empty %}
<tr class="no-borders-tr">
<td>{% trans 'No assets' %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Success assets' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
{% for host in object.success_hosts %}
{% if forloop.first %}
<tr class="no-borders-tr">
{% else %}
<tr>
{% endif %}
<td>{{ host }}</td>
</tr>
{% empty %}
<tr class="no-borders-tr">
<td>{% trans 'No assets' %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% include 'users/_user_update_pk_modal.html' %}
{% endblock %}

@ -106,7 +106,7 @@
}
}},
{targets: 7, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a class="btn btn-xs btn-primary m-l-xs btn-run" data-uid="{{ DEFAULT_PK }}">{% trans "Detail" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var detail_btn = '<a class="btn btn-xs btn-primary m-l-xs btn-run" href="{% url 'ops:adhoc-detail' pk=DEFAULT_PK %}">{% trans "Detail" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
if (cellData) {
$(td).html(detail_btn);
}

@ -66,30 +66,30 @@
</tr>
<tr>
<td>{% trans 'Latest version' %}</td>
<td><b>{{ object.get_latest_adhoc.short_id }}</b></td>
<td><b><a href="{% url 'ops:adhoc-detail' pk=object.latest_adhoc.id %}">{{ object.latest_adhoc.short_id }}</a></b></td>
</tr>
<tr>
<td>{% trans 'Latest run' %}:</td>
<td><b>{{ object.get_latest_history.date_start }}</b></td>
<td><b>{{ object.latest_history.date_start }}</b></td>
</tr>
<tr>
<td>{% trans 'Time delta' %}:</td>
<td><b>{{ object.get_latest_history.timedelta|floatformat}} s</b></td>
<td><b>{{ object.latest_history.timedelta|floatformat}} s</b></td>
</tr>
<tr>
<td>{% trans 'Is finished' %}:</td>
<td><b>{{ object.get_latest_history.is_finished|yesno:"Yes,No,Unkown" }}</b></td>
<td><b>{{ object.latest_history.is_finished|yesno:"Yes,No,Unkown" }}</b></td>
</tr>
<tr>
<td>{% trans 'Is success ' %}:</td>
<td><b>{{ object.get_latest_history.is_success|yesno:"Yes,No,Unkown" }}</b></td>
<td><b>{{ object.latest_history.is_success|yesno:"Yes,No,Unkown" }}</b></td>
</tr>
<tr>
<td>{% trans 'Contents' %}:</td>
<td>
<b>
{% for task in object.get_latest_adhoc.tasks %}
{{ task.name }} : {{ task.action.module }} <br/>
{% for task in object.latest_adhoc.tasks %}
{{ forloop.counter }}. {{ task.name }} : {{ task.action.module }} <br/>
{% endfor %}
</b>
</td>
@ -102,23 +102,27 @@
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-danger">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Failed assets' %}
<i class="fa fa-info-circle"></i> {% trans 'Last run failed hosts' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
{% for host, msg in results.failed %}
{% for host, task in object.latest_history.failed_hosts.items %}
{% if forloop.first %}
<tr class="no-borders-tr">
{% else %}
<tr>
{% endif %}
<td>{{ host }}: </td>
<td>{{ msg }}</td>
<td>
{% for name, result in task.items %}
<b>{{ name }}</b> => {{ result.msg }}
{% endfor %}
</td>
</tr>
{% empty %}
<tr class="no-borders-tr">
<td>{% trans 'No assets' %}</td>
<td>{% trans 'No hosts' %}</td>
</tr>
{% endfor %}
</tbody>
@ -128,12 +132,12 @@
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Success assets' %}
<i class="fa fa-info-circle"></i> {% trans 'Last run success hosts' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
{% for host in object.get_latest_history.summary.contacted %}
{% for host in object.latest_history.success_hosts %}
{% if forloop.first %}
<tr class="no-borders-tr">
{% else %}
@ -143,7 +147,7 @@
</tr>
{% empty %}
<tr class="no-borders-tr">
<td>{% trans 'No assets' %}</td>
<td>{% trans 'No hosts' %}</td>
</tr>
{% endfor %}
</tbody>

@ -30,7 +30,7 @@
<div class="col-sm-12" style="padding-left: 0">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left">{% trans 'History of ' %} <b>{{ object.name }}</b></span>
<span style="float: left">{% trans 'History of ' %} <b>{{ object.task.name }}:{{ object.short_id }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
@ -54,6 +54,7 @@
</th>
<th>{% trans 'Date start' %}</th>
<th>{% trans 'F/S/T' %}</th>
<th>{% trans 'Ratio' %}</th>
<th>{% trans 'Is finished' %}</th>
<th>{% trans 'Is success' %}</th>
<th>{% trans 'Time' %}</th>
@ -75,57 +76,75 @@
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
var options = {
ele: $('#task-history-list-table'),
buttons: [],
order: [],
select: [],
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
{# var detail_btn = '<a href="' + cellData + '</a>';#}
$(td).html(cellData);
}},
{targets: 2, createdCell: function (td, cellData) {
var total = "<span>" + cellData.total + "</span>";
var success = "<span class='text-navy'>" + cellData.success + "</span>";
var failed = "<span class='text-danger'>" + cellData.failed + "</span>";
$(td).html(failed + '/' + success + '/' + total );
}},
{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) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 5, createdCell: function (td, cellData) {
if (cellData) {
$(td).html(cellData.toFixed(2) + ' s')
} else {
$(td).html("0" + ' s')
}
}},
{targets: 7, createdCell: function (td, cellData) {
var run_btn = '<a class="btn btn-xs btn-primary m-l-xs btn-run" data-uid="{{ DEFAULT_PK }}">{% trans "Detail" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
if (cellData) {
$(td).html(run_btn);
}
}}
],
ajax_url: '{% url "api-ops:history-list" %}?task={{ object.pk }}',
columns: [{data: function(){return ""}}, {data: "date_start"}, {data: "stat"}, {data: "adhoc_short_id"},
{data: "adhoc_short_id"}, {data: "timedelta"}, {data: 'adhoc_short_id'}, {data: "id"}]
};
jumpserver.initDataTable(options);
})
</script>
<script>
function initTable() {
var options = {
ele: $('#task-history-list-table'),
buttons: [],
order: [],
select: [],
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
$(td).html(cellData);
}},
{targets: 2, createdCell: function (td, cellData) {
var total = "<span>" + cellData.total + "</span>";
var success = "<span class='text-navy'>" + cellData.success + "</span>";
var failed = "<span class='text-danger'>" + cellData.failed + "</span>";
$(td).html(failed + '/' + success + '/' + total );
}},
{targets: 3, createdCell: function (td, cellData) {
var val = 0;
var innerHtml = "";
if (cellData.total !== 0) {
val = cellData.success/cellData.total * 100;
}
if (val === 100) {
innerHtml = "<span class='text-navy'>" + val + "% </span>";
} else {
innerHtml = "<span class='text-danger'>" + val + "% </span>";
}
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
}},
{targets: 4, 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: 5, 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: 6, createdCell: function (td, cellData) {
if (cellData) {
$(td).html(cellData.toFixed(2) + ' s')
} else {
$(td).html("0" + ' s')
}
}},
{targets: 8, createdCell: function (td, cellData) {
var run_btn = '<a class="btn btn-xs btn-primary m-l-xs btn-run" href="{% url 'ops:adhoc-history-detail' pk=DEFAULT_PK %}">{% trans "Detail" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
if (cellData) {
$(td).html(run_btn);
}
}}
],
ajax_url: '{% url "api-ops:history-list" %}?task={{ object.pk }}',
columns: [{data: function(){return ""}}, {data: "date_start"}, {data: "stat"}, {data: "stat"}, {data: "is_finished"},
{data: "is_success"}, {data: "timedelta"}, {data: 'adhoc_short_id'}, {data: "id"}]
};
jumpserver.initDataTable(options);
}
$(document).ready(function () {
initTable();
})
</script>
{% endblock %}

@ -22,7 +22,7 @@
</div>
</div>
<div class="input-group">
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
<input type="text" class="form-control input-sm" name="keyword" placeholder="{% trans "Search" %}" value="{{ keyword }}">
</div>
<div class="input-group">
<div class="input-group-btn">
@ -50,7 +50,7 @@
{% for object in task_list %}
<tr class="gradeX">
<td class="text-center"><input type="checkbox" class="cbx-term"> </td>
<td class="text-center"><a href="{% url 'ops:task-detail' pk=object.id %}">{{ object.name }}</a></td>
<td class="text-left"><a href="{% url 'ops:task-detail' pk=object.id %}">{{ object.name }}</a></td>
<td class="text-center">
<span class="text-danger">{{ object.history_summary.failed }}</span>/<span class="text-navy">{{ object.history_summary.success}}</span>/{{ object.history_summary.total}}
</td>
@ -67,38 +67,37 @@
<td class="text-center">{{ object.latest_history.timedelta|floatformat }} s</td>
<td class="text-center">
<a href="{% url 'ops:task-run' pk=object.id %}" class="btn btn-xs btn-info">{% trans "Run" %}</a>
<a data-uid="{{ object.uuid }}" class="btn btn-xs btn-danger btn-del">{% trans "Delete" %}</a>
<a data-uid="{{ object.id }}" class="btn btn-xs btn-danger btn-del">{% trans "Delete" %}</a>
</td>
</tr>
{% endfor %}
{% endblock %}
{# comment #}
{% block custom_foot_js %}
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script>
$(document).ready(function() {
$('table').DataTable({
"searching": false,
"paging": false,
"bInfo" : false,
"order": []
});
$('.select2').select2();
$('#date .input-daterange').datepicker({
dateFormat: 'mm/dd/yy',
keyboardNavigation: false,
forceParse: false,
autoclose: true
});
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script>
$(document).ready(function() {
$('table').DataTable({
"searching": false,
"paging": false,
"bInfo" : false,
"order": []
});
$('.select2').select2();
$('#date .input-daterange').datepicker({
dateFormat: 'mm/dd/yy',
keyboardNavigation: false,
forceParse: false,
autoclose: true
});
}).on('click', '.btn-del', function () {
var $this = $(this);
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-ops:task-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
objectDelete($this, name, the_url);
})
</script>
}).on('click', '.btn-del', function () {
var $this = $(this);
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-ops:task-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
objectDelete($this, name, the_url);
})
</script>
{% endblock %}

@ -16,4 +16,7 @@ urlpatterns = [
url(r'^task/(?P<pk>[0-9a-zA-Z\-]{36})/adhoc/$', views.TaskAdhocView.as_view(), name='task-adhoc'),
url(r'^task/(?P<pk>[0-9a-zA-Z\-]{36})/history/$', views.TaskHistoryView.as_view(), name='task-history'),
url(r'^task/(?P<pk>[0-9a-zA-Z\-]{36})/run/$', views.TaskRunView.as_view(), name='task-run'),
]
url(r'^adhoc/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.AdHocDetailView.as_view(), name='adhoc-detail'),
url(r'^adhoc/(?P<pk>[0-9a-zA-Z\-]{36})/history/$', views.AdHocHistoryView.as_view(), name='adhoc-history'),
url(r'^adhoc/history/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.AdHocHistoryDetailView.as_view(), name='adhoc-history-detail'),
]

@ -1,9 +1,9 @@
# ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals
import time
import json
from datetime import datetime
from django.utils.translation import ugettext as _
from django.conf import settings
from django.views.generic import ListView, DetailView, View
from django.utils import timezone
@ -53,7 +53,7 @@ class TaskListView(ListView):
def get_context_data(self, **kwargs):
context = {
'app': 'Ops',
'action': 'Playbook record list',
'action': _('Task list'),
'date_from': self.date_from_s,
'date_to': self.date_to_s,
'keyword': self.keyword,
@ -109,3 +109,42 @@ class TaskRunView(View):
rerun_task.delay(pk)
time.sleep(0.5)
return redirect(reverse('ops:task-detail', kwargs={'pk': pk}))
class AdHocDetailView(DetailView):
model = AdHoc
template_name = 'ops/adhoc_detail.html'
def get_context_data(self, **kwargs):
context = {
'app': 'Ops',
'action': 'Task version detail',
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class AdHocHistoryView(DetailView):
model = AdHoc
template_name = 'ops/adhoc_history.html'
def get_context_data(self, **kwargs):
context = {
'app': 'Ops',
'action': 'Version run history',
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class AdHocHistoryDetailView(DetailView):
model = AdHocRunHistory
template_name = 'ops/adhoc_history_detail.html'
def get_context_data(self, **kwargs):
context = {
'app': 'Ops',
'action': 'Run history detail',
}
kwargs.update(context)
return super().get_context_data(**kwargs)

@ -65,5 +65,5 @@ class AssetPermission(models.Model):
for system_user in self.system_users.all():
cluster_remain = clusters - set(system_user.cluster.all())
if cluster_remain:
errors[system_user.name] = cluster_remain
errors[system_user] = cluster_remain
return errors

@ -50,10 +50,11 @@ class MessageMixin:
@staticmethod
def get_warning_messages(errors):
message = "System user should in behind clusters, so that " \
"system user auto push to cluster assets <br>"
for system_user, clusters in errors:
message += "{}: {} ".format(system_user.name, ", ".join(list(clusters)))
message = "<b><i class='fa fa-warning'></i>WARNING: System user " \
"should in behind clusters, so that " \
"system user cat auto push to the cluster assets:</b> <br>"
for system_user, clusters in errors.items():
message += " >>> {}: {} ".format(system_user.name, ", ".join((cluster.name for cluster in clusters)))
return message
def get_success_message(self, cleaned_data):

Loading…
Cancel
Save