Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
5a929721
Commit
5a929721
authored
Dec 20, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Bugfix] 修复ops一些功能的bug
parent
3f89701b
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
482 additions
and
115 deletions
+482
-115
const.py
apps/assets/const.py
+10
-9
django.mo
apps/locale/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/locale/zh/LC_MESSAGES/django.po
+0
-0
api.py
apps/ops/api.py
+5
-0
models.py
apps/ops/models.py
+8
-0
adhoc_detail.html
apps/ops/templates/ops/adhoc_detail.html
+0
-0
adhoc_history.html
apps/ops/templates/ops/adhoc_history.html
+147
-0
adhoc_history_detail.html
apps/ops/templates/ops/adhoc_history_detail.html
+141
-0
task_adhoc.html
apps/ops/templates/ops/task_adhoc.html
+1
-1
task_detail.html
apps/ops/templates/ops/task_detail.html
+18
-14
task_history.html
apps/ops/templates/ops/task_history.html
+73
-54
task_list.html
apps/ops/templates/ops/task_list.html
+27
-28
view_urls.py
apps/ops/urls/view_urls.py
+4
-2
views.py
apps/ops/views.py
+42
-2
models.py
apps/perms/models.py
+1
-1
views.py
apps/perms/views.py
+5
-4
No files found.
apps/assets/const.py
View file @
5a929721
# -*- 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
=
[
...
...
apps/locale/zh/LC_MESSAGES/django.mo
View file @
5a929721
No preview for this file type
apps/locale/zh/LC_MESSAGES/django.po
View file @
5a929721
This diff is collapsed.
Click to expand it.
apps/ops/api.py
View file @
5a929721
...
...
@@ -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
apps/ops/models.py
View file @
5a929721
...
...
@@ -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
...
...
apps/ops/templates/ops/adhoc_detail.html
0 → 100644
View file @
5a929721
This diff is collapsed.
Click to expand it.
apps/ops/templates/ops/adhoc_history.html
0 → 100644
View file @
5a929721
{% 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 %}
apps/ops/templates/ops/adhoc_history_detail.html
0 → 100644
View file @
5a929721
{% 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 %}
apps/ops/templates/ops/task_adhoc.html
View file @
5a929721
...
...
@@ -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
);
}
...
...
apps/ops/templates/ops/task_detail.html
View file @
5a929721
...
...
@@ -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 asse
ts' %}
<i
class=
"fa fa-info-circle"
></i>
{% trans '
Last run failed hos
ts' %}
</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
asse
ts' %}
</td>
<td>
{% trans 'No
hos
ts' %}
</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 asse
ts' %}
<i
class=
"fa fa-info-circle"
></i>
{% trans '
Last run success hos
ts' %}
</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
asse
ts' %}
</td>
<td>
{% trans 'No
hos
ts' %}
</td>
</tr>
{% endfor %}
</tbody>
...
...
apps/ops/templates/ops/task_history.html
View file @
5a929721
...
...
@@ -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 %}
apps/ops/templates/ops/task_list.html
View file @
5a929721
...
...
@@ -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.
uu
id }}"
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 %}
apps/ops/urls/view_urls.py
View file @
5a929721
...
...
@@ -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'
),
]
\ No newline at end of file
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'
),
]
apps/ops/views.py
View file @
5a929721
# ~*~ 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
)
\ No newline at end of file
apps/perms/models.py
View file @
5a929721
...
...
@@ -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
apps/perms/views.py
View file @
5a929721
...
...
@@ -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
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment