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
d247e49b
Commit
d247e49b
authored
Apr 02, 2018
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修改celery位置
parent
a4c843ff
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
252 additions
and
395 deletions
+252
-395
api.py
apps/common/api.py
+2
-31
models.py
apps/common/models.py
+0
-9
api_urls.py
apps/common/urls/api_urls.py
+0
-1
view_urls.py
apps/common/urls/view_urls.py
+0
-2
views.py
apps/common/views.py
+0
-15
django.mo
apps/i18n/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/i18n/zh/LC_MESSAGES/django.po
+136
-127
api.py
apps/ops/api.py
+12
-15
apps.py
apps/ops/apps.py
+4
-0
__init__.py
apps/ops/celery/__init__.py
+0
-1
signal_handler.py
apps/ops/celery/signal_handler.py
+34
-30
__init__.py
apps/ops/models/__init__.py
+6
-0
adhoc.py
apps/ops/models/adhoc.py
+5
-6
celery.py
apps/ops/models/celery.py
+36
-0
tasks.py
apps/ops/tasks.py
+0
-1
adhoc_history_detail.html
apps/ops/templates/ops/adhoc_history_detail.html
+1
-1
adhoc_history_output.html
apps/ops/templates/ops/adhoc_history_output.html
+0
-37
celery_task_log.html
apps/ops/templates/ops/celery_task_log.html
+1
-1
celery_task_output.html
apps/ops/templates/ops/celery_task_output.html
+0
-94
task_adhoc.html
apps/ops/templates/ops/task_adhoc.html
+3
-0
task_detail.html
apps/ops/templates/ops/task_detail.html
+1
-1
task_history.html
apps/ops/templates/ops/task_history.html
+3
-0
task_list.html
apps/ops/templates/ops/task_list.html
+2
-2
api_urls.py
apps/ops/urls/api_urls.py
+1
-1
view_urls.py
apps/ops/urls/view_urls.py
+1
-2
views.py
apps/ops/views.py
+4
-18
No files found.
apps/common/api.py
View file @
d247e49b
# -*- coding: utf-8 -*-
#
import
os
import
json
import
uuid
from
django.core.cache
import
cache
from
rest_framework.generics
import
RetrieveAPIView
from
rest_framework.views
import
Response
,
APIView
from
ldap3
import
Server
,
Connection
from
django.core.mail
import
get_connection
,
send_mail
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
.permissions
import
IsSuperUser
,
IsAppUser
from
.permissions
import
IsSuperUser
from
.serializers
import
MailTestSerializer
,
LDAPTestSerializer
from
.celery
import
FINISHED
from
.const
import
FILE_END_GUARD
,
celery_task_pre_key
class
MailTestingAPI
(
APIView
):
...
...
@@ -112,27 +106,4 @@ class DjangoSettingsAPI(APIView):
return
Response
(
configs
)
class
CeleryTaskLogApi
(
APIView
):
permission_classes
=
(
IsSuperUser
,)
buff_size
=
1024
*
10
end
=
False
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
task_id
=
kwargs
.
get
(
'pk'
)
info
=
cache
.
get
(
celery_task_pre_key
+
task_id
,
{})
log_path
=
info
.
get
(
"log_path"
)
mark
=
request
.
query_params
.
get
(
"mark"
)
or
str
(
uuid
.
uuid4
())
if
not
log_path
or
not
os
.
path
.
isfile
(
log_path
):
return
Response
({
"data"
:
_
(
"Waiting ..."
)},
status
=
203
)
with
open
(
log_path
,
'r'
)
as
f
:
offset
=
cache
.
get
(
mark
,
0
)
f
.
seek
(
offset
)
data
=
f
.
read
(
self
.
buff_size
)
.
replace
(
'
\n
'
,
'
\r\n
'
)
mark
=
str
(
uuid
.
uuid4
())
cache
.
set
(
mark
,
f
.
tell
(),
5
)
if
data
==
''
and
info
[
"status"
]
==
FINISHED
:
self
.
end
=
True
return
Response
({
"data"
:
data
,
'end'
:
self
.
end
,
'mark'
:
mark
})
apps/common/models.py
View file @
d247e49b
...
...
@@ -80,11 +80,3 @@ class Setting(models.Model):
class
Meta
:
db_table
=
"settings"
class
CeleryTask
(
models
.
Model
):
id
=
models
.
UUIDField
()
name
=
models
.
CharField
(
max_length
=
1024
)
status
=
models
.
CharField
(
max_length
=
128
)
date_published
=
models
.
DateTimeField
(
auto_now_add
=
True
)
date_start
=
models
.
DateTimeField
(
null
=
True
)
date_finished
=
models
.
DateTimeField
(
null
=
True
)
\ No newline at end of file
apps/common/urls/api_urls.py
View file @
d247e49b
...
...
@@ -10,5 +10,4 @@ urlpatterns = [
url
(
r'^v1/mail/testing/$'
,
api
.
MailTestingAPI
.
as_view
(),
name
=
'mail-testing'
),
url
(
r'^v1/ldap/testing/$'
,
api
.
LDAPTestingAPI
.
as_view
(),
name
=
'ldap-testing'
),
url
(
r'^v1/django-settings/$'
,
api
.
DjangoSettingsAPI
.
as_view
(),
name
=
'django-settings'
),
url
(
r'^v1/celery/task/(?P<pk>[0-9a-zA-Z\-]{36})/log/$'
,
api
.
CeleryTaskLogApi
.
as_view
(),
name
=
'celery-task-log'
),
]
apps/common/urls/view_urls.py
View file @
d247e49b
...
...
@@ -11,6 +11,4 @@ urlpatterns = [
url
(
r'^email/$'
,
views
.
EmailSettingView
.
as_view
(),
name
=
'email-setting'
),
url
(
r'^ldap/$'
,
views
.
LDAPSettingView
.
as_view
(),
name
=
'ldap-setting'
),
url
(
r'^terminal/$'
,
views
.
TerminalSettingView
.
as_view
(),
name
=
'terminal-setting'
),
url
(
r'^celery/task/(?P<pk>[0-9a-zA-Z\-]{36})/log/$'
,
views
.
CeleryTaskLogView
.
as_view
(),
name
=
'celery-task-log'
),
]
apps/common/views.py
View file @
d247e49b
...
...
@@ -122,18 +122,3 @@ class TerminalSettingView(AdminUserRequiredMixin, TemplateView):
return
render
(
request
,
self
.
template_name
,
context
)
class
CeleryTaskLogView
(
AdminUserRequiredMixin
,
TemplateView
):
template_name
=
'common/celery_task_log.html'
task_log_path
=
None
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
()
.
get_context_data
(
**
kwargs
)
task_id
=
self
.
kwargs
.
get
(
"pk"
)
if
cache
.
get
(
celery_task_pre_key
+
task_id
)
is
None
:
raise
Http404
()
context
.
update
({
"task_id"
:
self
.
kwargs
.
get
(
"pk"
)
})
return
context
apps/i18n/zh/LC_MESSAGES/django.mo
View file @
d247e49b
No preview for this file type
apps/i18n/zh/LC_MESSAGES/django.po
View file @
d247e49b
...
...
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-0
3-23 19:50
+0800\n"
"POT-Creation-Date: 2018-0
4-02 15:49
+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
...
...
@@ -51,7 +51,7 @@ msgid "Labels"
msgstr "标签管理"
#: assets/forms/asset.py:34 assets/forms/asset.py:70 assets/models/asset.py:52
#: assets/models/domain.py:
34
#: assets/models/domain.py:
46
msgid "Domain"
msgstr "网域"
...
...
@@ -74,12 +74,12 @@ msgstr ""
#: assets/forms/asset.py:90 assets/forms/asset.py:94 assets/forms/domain.py:16
#: assets/forms/label.py:15
#: perms/templates/perms/asset_permission_asset.html:88 users/forms.py:27
0
#: perms/templates/perms/asset_permission_asset.html:88 users/forms.py:27
2
msgid "Select assets"
msgstr "选择资产"
#: assets/forms/asset.py:99 assets/models/asset.py:51
#: assets/models/domain.py:
32
assets/templates/assets/admin_user_assets.html:53
#: assets/models/domain.py:
44
assets/templates/assets/admin_user_assets.html:53
#: assets/templates/assets/asset_detail.html:69
#: assets/templates/assets/domain_gateway_list.html:58
#: assets/templates/assets/system_user_asset.html:51
...
...
@@ -96,7 +96,7 @@ msgid "Select nodes"
msgstr "选择节点"
#: assets/forms/domain.py:14 assets/forms/label.py:13
#: assets/models/asset.py:1
56
assets/templates/assets/admin_user_list.html:25
#: assets/models/asset.py:1
65
assets/templates/assets/admin_user_list.html:25
#: assets/templates/assets/domain_detail.html:60
#: assets/templates/assets/domain_list.html:15
#: assets/templates/assets/label_list.html:16
...
...
@@ -111,7 +111,7 @@ msgstr "资产"
#: assets/forms/domain.py:54 assets/forms/user.py:79 assets/forms/user.py:120
#: assets/models/base.py:20 assets/models/cluster.py:18
#: assets/models/domain.py:1
5
assets/models/group.py:20
#: assets/models/domain.py:1
7
assets/models/group.py:20
#: assets/models/label.py:17 assets/templates/assets/admin_user_detail.html:56
#: assets/templates/assets/admin_user_list.html:23
#: assets/templates/assets/domain_detail.html:56
...
...
@@ -121,8 +121,8 @@ msgstr "资产"
#: assets/templates/assets/system_user_detail.html:58
#: assets/templates/assets/system_user_list.html:26 common/models.py:26
#: common/templates/common/terminal_setting.html:67
#: common/templates/common/terminal_setting.html:85 ops/models
.py:31
#: ops/templates/ops/task_detail.html:5
6
ops/templates/ops/task_list.html:34
#: common/templates/common/terminal_setting.html:85 ops/models
/adhoc.py:36
#: ops/templates/ops/task_detail.html:5
9
ops/templates/ops/task_list.html:34
#: perms/models.py:14 perms/templates/perms/asset_permission_detail.html:62
#: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:16
#: terminal/models.py:149 terminal/templates/terminal/terminal_detail.html:43
...
...
@@ -190,7 +190,7 @@ msgid ""
"than 2 system user"
msgstr "高优先级的系统用户将会作为默认登录用户"
#: assets/models/asset.py:49 assets/models/domain.py:
31
#: assets/models/asset.py:49 assets/models/domain.py:
43
#: assets/templates/assets/_asset_list_modal.html:21
#: assets/templates/assets/admin_user_assets.html:52
#: assets/templates/assets/asset_detail.html:61
...
...
@@ -217,7 +217,7 @@ msgstr "IP"
msgid "Hostname"
msgstr "主机名"
#: assets/models/asset.py:54 assets/models/domain.py:
36
#: assets/models/asset.py:54 assets/models/domain.py:
48
#: assets/models/label.py:20 assets/templates/assets/asset_detail.html:105
#: perms/templates/perms/asset_permission_list.html:70
msgid "Is active"
...
...
@@ -300,11 +300,11 @@ msgid "Created by"
msgstr "创建者"
#: assets/models/asset.py:83 assets/models/cluster.py:26
#: assets/models/domain.py:
18
assets/models/group.py:22
#: assets/models/domain.py:
20
assets/models/group.py:22
#: assets/models/label.py:23 assets/templates/assets/admin_user_detail.html:64
#: assets/templates/assets/domain_detail.html:68
#: assets/templates/assets/system_user_detail.html:92
#: ops/templates/ops/adhoc_detail.html:90 ops/templates/ops/task_detail.html:6
0
#: ops/templates/ops/adhoc_detail.html:90 ops/templates/ops/task_detail.html:6
3
#: perms/models.py:23 perms/models.py:80
#: perms/templates/perms/asset_permission_detail.html:90
#: terminal/templates/terminal/terminal_detail.html:59 users/models/group.py:17
...
...
@@ -313,8 +313,8 @@ msgid "Date created"
msgstr "创建日期"
#: assets/models/asset.py:84 assets/models/base.py:25
#: assets/models/cluster.py:29 assets/models/domain.py:1
6
#: assets/models/domain.py:
35
assets/models/group.py:23
#: assets/models/cluster.py:29 assets/models/domain.py:1
8
#: assets/models/domain.py:
47
assets/models/group.py:23
#: assets/models/label.py:21 assets/templates/assets/admin_user_detail.html:72
#: assets/templates/assets/admin_user_list.html:29
#: assets/templates/assets/asset_detail.html:125
...
...
@@ -323,7 +323,7 @@ msgstr "创建日期"
#: assets/templates/assets/domain_list.html:17
#: assets/templates/assets/system_user_detail.html:100
#: assets/templates/assets/system_user_list.html:33 common/models.py:30
#: ops/models
.py:37
perms/models.py:24 perms/models.py:81
#: ops/models
/adhoc.py:42
perms/models.py:24 perms/models.py:81
#: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:26
#: terminal/templates/terminal/terminal_detail.html:63 users/models/group.py:15
#: users/models/user.py:47 users/templates/users/user_detail.html:111
...
...
@@ -387,7 +387,7 @@ msgstr "默认Cluster"
msgid "Cluster"
msgstr "集群"
#: assets/models/domain.py:
33
assets/models/user.py:104
#: assets/models/domain.py:
45
assets/models/user.py:104
#: assets/templates/assets/domain_gateway_list.html:59
#: assets/templates/assets/system_user_detail.html:66
#: assets/templates/assets/system_user_list.html:28
...
...
@@ -407,7 +407,7 @@ msgstr "默认资产组"
#: terminal/templates/terminal/command_list.html:32
#: terminal/templates/terminal/command_list.html:72
#: terminal/templates/terminal/session_list.html:33
#: terminal/templates/terminal/session_list.html:71 users/forms.py:2
18
#: terminal/templates/terminal/session_list.html:71 users/forms.py:2
20
#: users/models/user.py:30 users/models/user.py:254
#: users/templates/users/user_group_detail.html:78
#: users/templates/users/user_group_list.html:13 users/views/user.py:334
...
...
@@ -493,7 +493,7 @@ msgstr ""
msgid "推送系统用户到节点资产: {} => {}"
msgstr ""
#: assets/tasks.py:43
1
#: assets/tasks.py:43
2
msgid "推送节点系统用户到新加入资产中: {}"
msgstr ""
...
...
@@ -509,9 +509,9 @@ msgstr "仅修改你需要更新的字段"
#: assets/templates/assets/system_user_asset.html:21
#: assets/views/admin_user.py:29 assets/views/admin_user.py:47
#: assets/views/admin_user.py:63 assets/views/admin_user.py:78
#: assets/views/admin_user.py:102 assets/views/asset.py:4
8
#: assets/views/asset.py:9
4 assets/views/asset.py:154 assets/views/asset.py:171
#: assets/views/asset.py:19
5
assets/views/domain.py:29
#: assets/views/admin_user.py:102 assets/views/asset.py:4
9
#: assets/views/asset.py:9
5 assets/views/asset.py:155 assets/views/asset.py:172
#: assets/views/asset.py:19
6
assets/views/domain.py:29
#: assets/views/domain.py:45 assets/views/domain.py:61
#: assets/views/domain.py:74 assets/views/domain.py:98
#: assets/views/domain.py:126 assets/views/domain.py:150
...
...
@@ -602,8 +602,8 @@ msgstr "可连接"
#: assets/templates/assets/domain_list.html:18
#: assets/templates/assets/label_list.html:17
#: assets/templates/assets/system_user_list.html:34
#: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:6
1
#: ops/templates/ops/task_history.html:6
2
ops/templates/ops/task_list.html:41
#: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:6
4
#: ops/templates/ops/task_history.html:6
5
ops/templates/ops/task_list.html:41
#: perms/templates/perms/asset_permission_list.html:72
#: terminal/templates/terminal/session_list.html:80
#: terminal/templates/terminal/terminal_list.html:36
...
...
@@ -774,9 +774,9 @@ msgstr "重置"
#: assets/templates/assets/domain_gateway_list.html:18
#: assets/templates/assets/system_user_asset.html:17
#: assets/templates/assets/system_user_detail.html:18
#: ops/templates/ops/adhoc_history.html:1
29
#: ops/templates/ops/task_adhoc.html:1
09
#: ops/templates/ops/task_history.html:13
2
#: ops/templates/ops/adhoc_history.html:1
30
#: ops/templates/ops/task_adhoc.html:1
16
#: ops/templates/ops/task_history.html:13
6
#: perms/templates/perms/asset_permission_asset.html:18
#: perms/templates/perms/asset_permission_detail.html:18
#: perms/templates/perms/asset_permission_user.html:18
...
...
@@ -822,7 +822,7 @@ msgstr "替换资产的管理员"
#: assets/templates/assets/admin_user_detail.html:100
#: assets/templates/assets/asset_detail.html:200
#: assets/templates/assets/asset_list.html:5
86
#: assets/templates/assets/asset_list.html:5
94
#: assets/templates/assets/system_user_detail.html:183
#: assets/templates/assets/system_user_list.html:138 templates/_modal.html:16
#: terminal/templates/terminal/session_detail.html:108
...
...
@@ -849,7 +849,7 @@ msgstr "不可达"
#: assets/templates/assets/admin_user_list.html:28
#: assets/templates/assets/system_user_list.html:32
#: ops/templates/ops/adhoc_history.html:54
#: ops/templates/ops/task_history.html:
57
#: ops/templates/ops/task_history.html:
60
msgid "Ratio"
msgstr "比例"
...
...
@@ -866,7 +866,7 @@ msgstr "节点"
msgid "Label"
msgstr "标签"
#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:19
6
#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:19
7
msgid "Asset detail"
msgstr "资产详情"
...
...
@@ -905,7 +905,7 @@ msgid "Update successfully!"
msgstr "更新成功"
#: assets/templates/assets/asset_list.html:63
#: assets/templates/assets/asset_list.html:120 assets/views/asset.py:9
5
#: assets/templates/assets/asset_list.html:120 assets/views/asset.py:9
6
msgid "Create asset"
msgstr "创建资产"
...
...
@@ -955,7 +955,7 @@ msgstr "创建节点失败"
msgid "Have child node, cancel"
msgstr "存在子节点,不能删除"
#: assets/templates/assets/asset_list.html:58
1
#: assets/templates/assets/asset_list.html:58
9
#: assets/templates/assets/system_user_list.html:133
#: users/templates/users/user_detail.html:334
#: users/templates/users/user_detail.html:359
...
...
@@ -964,20 +964,20 @@ msgstr "存在子节点,不能删除"
msgid "Are you sure?"
msgstr "你确认吗?"
#: assets/templates/assets/asset_list.html:5
82
#: assets/templates/assets/asset_list.html:5
90
msgid "This will delete the selected assets !!!"
msgstr "删除选择资产"
#: assets/templates/assets/asset_list.html:59
0
#: assets/templates/assets/asset_list.html:59
8
msgid "Asset Deleted."
msgstr "已被删除"
#: assets/templates/assets/asset_list.html:59
1
#: assets/templates/assets/asset_list.html:
596
#: assets/templates/assets/asset_list.html:59
9
#: assets/templates/assets/asset_list.html:
604
msgid "Asset Delete"
msgstr "删除"
#: assets/templates/assets/asset_list.html:
595
#: assets/templates/assets/asset_list.html:
603
msgid "Asset Deleting failed."
msgstr "删除失败"
...
...
@@ -1104,23 +1104,23 @@ msgstr "更新管理用户"
msgid "Admin user detail"
msgstr "管理用户详情"
#: assets/views/asset.py:
49
templates/_nav.html:23
#: assets/views/asset.py:
50
templates/_nav.html:23
msgid "Asset list"
msgstr "资产列表"
#: assets/views/asset.py:6
1
templates/_nav_user.html:4
#: assets/views/asset.py:6
2
templates/_nav_user.html:4
msgid "My assets"
msgstr "我的资产"
#: assets/views/asset.py:15
5
#: assets/views/asset.py:15
6
msgid "Bulk update asset"
msgstr "批量更新资产"
#: assets/views/asset.py:17
2
#: assets/views/asset.py:17
3
msgid "Update asset"
msgstr "更新资产"
#: assets/views/asset.py:29
6
#: assets/views/asset.py:29
9
msgid "already exists"
msgstr "已经存在"
...
...
@@ -1172,15 +1172,15 @@ msgstr "资产管理"
msgid "System user asset"
msgstr "系统用户集群资产"
#: common/api.py:1
9
#: common/api.py:1
8
msgid "Test mail sent to {}, please check"
msgstr "邮件已经发送{}, 请检查"
#: common/api.py:5
3
#: common/api.py:5
2
msgid "Test ldap success"
msgstr "连接LDAP成功"
#: common/api.py:9
1
#: common/api.py:9
0
msgid "Match {} s users"
msgstr "匹配 {} 个用户"
...
...
@@ -1299,7 +1299,7 @@ msgstr "资产列表排序"
msgid "Heartbeat interval"
msgstr "心跳间隔"
#: common/forms.py:150 ops/models
.py:32
#: common/forms.py:150 ops/models
/adhoc.py:37
msgid "Units: seconds"
msgstr "单位: 秒"
...
...
@@ -1349,28 +1349,28 @@ msgstr "启用"
#: common/templates/common/email_setting.html:15
#: common/templates/common/ldap_setting.html:15
#: common/templates/common/terminal_setting.html:16
#: common/templates/common/terminal_setting.html:42 common/views.py:2
1
#: common/templates/common/terminal_setting.html:42 common/views.py:2
2
msgid "Basic setting"
msgstr "基本设置"
#: common/templates/common/basic_setting.html:18
#: common/templates/common/email_setting.html:18
#: common/templates/common/ldap_setting.html:18
#: common/templates/common/terminal_setting.html:20 common/views.py:4
7
#: common/templates/common/terminal_setting.html:20 common/views.py:4
8
msgid "Email setting"
msgstr "邮件设置"
#: common/templates/common/basic_setting.html:21
#: common/templates/common/email_setting.html:21
#: common/templates/common/ldap_setting.html:21
#: common/templates/common/terminal_setting.html:24 common/views.py:7
3
#: common/templates/common/terminal_setting.html:24 common/views.py:7
4
msgid "LDAP setting"
msgstr "LDAP设置"
#: common/templates/common/basic_setting.html:24
#: common/templates/common/email_setting.html:24
#: common/templates/common/ldap_setting.html:24
#: common/templates/common/terminal_setting.html:28 common/views.py:10
3
#: common/templates/common/terminal_setting.html:28 common/views.py:10
4
msgid "Terminal setting"
msgstr "终端设置"
...
...
@@ -1380,97 +1380,101 @@ msgstr "终端设置"
msgid "Type"
msgstr "类型"
#: common/views.py:2
0 common/views.py:46 common/views.py:72 common/views.py:102
#: common/views.py:2
1 common/views.py:47 common/views.py:73 common/views.py:103
#: templates/_nav.html:73
msgid "Settings"
msgstr "系统设置"
#: common/views.py:3
1 common/views.py:57 common/views.py:85 common/views.py:115
#: common/views.py:3
2 common/views.py:58 common/views.py:86 common/views.py:116
msgid "Update setting successfully, please restart program"
msgstr "更新设置成功, 请手动重启程序"
#: ops/models.py:32
#: ops/api.py:79
msgid "Waiting ..."
msgstr ""
#: ops/models/adhoc.py:37
msgid "Interval"
msgstr "间隔"
#: ops/models
.py:33
#: ops/models
/adhoc.py:38
msgid "Crontab"
msgstr "Crontab"
#: ops/models
.py:33
#: ops/models
/adhoc.py:38
msgid "5 * * * *"
msgstr ""
#: ops/models
.py:35
#: ops/models
/adhoc.py:40
msgid "Callback"
msgstr "回调"
#: ops/models
.py:149
ops/templates/ops/adhoc_detail.html:114
#: ops/models
/adhoc.py:154
ops/templates/ops/adhoc_detail.html:114
msgid "Tasks"
msgstr "任务"
#: ops/models
.py:150
ops/templates/ops/adhoc_detail.html:57
#: ops/templates/ops/task_adhoc.html:
57
#: ops/models
/adhoc.py:155
ops/templates/ops/adhoc_detail.html:57
#: ops/templates/ops/task_adhoc.html:
60
msgid "Pattern"
msgstr ""
#: ops/models
.py:151
ops/templates/ops/adhoc_detail.html:61
#: ops/models
/adhoc.py:156
ops/templates/ops/adhoc_detail.html:61
msgid "Options"
msgstr "选项"
#: ops/models
.py:152
ops/templates/ops/adhoc_detail.html:53
#: ops/templates/ops/task_adhoc.html:5
6
ops/templates/ops/task_list.html:37
#: ops/models
/adhoc.py:157
ops/templates/ops/adhoc_detail.html:53
#: ops/templates/ops/task_adhoc.html:5
9
ops/templates/ops/task_list.html:37
msgid "Hosts"
msgstr "主机"
#: ops/models
.py:153
#: ops/models
/adhoc.py:158
msgid "Run as admin"
msgstr "再次执行"
#: ops/models
.py:154
ops/templates/ops/adhoc_detail.html:72
#: ops/templates/ops/adhoc_detail.html:77 ops/templates/ops/task_adhoc.html:
58
#: ops/models
/adhoc.py:159
ops/templates/ops/adhoc_detail.html:72
#: ops/templates/ops/adhoc_detail.html:77 ops/templates/ops/task_adhoc.html:
61
msgid "Run as"
msgstr "用户"
#: ops/models
.py:155
ops/templates/ops/adhoc_detail.html:82
#: ops/templates/ops/task_adhoc.html:
59
#: ops/models
/adhoc.py:160
ops/templates/ops/adhoc_detail.html:82
#: ops/templates/ops/task_adhoc.html:
62
msgid "Become"
msgstr "Become"
#: ops/models
.py:156
users/templates/users/user_group_detail.html:59
#: ops/models
/adhoc.py:161
users/templates/users/user_group_detail.html:59
msgid "Create by"
msgstr "创建者"
#: ops/models
.py:307
#: ops/models
/adhoc.py:323
msgid "Start time"
msgstr "开始时间"
#: ops/models
.py:308
#: ops/models
/adhoc.py:324
msgid "End time"
msgstr "完成时间"
#: ops/models
.py:309
ops/templates/ops/adhoc_history.html:57
#: ops/templates/ops/task_history.html:6
0
ops/templates/ops/task_list.html:40
#: ops/models
/adhoc.py:325
ops/templates/ops/adhoc_history.html:57
#: ops/templates/ops/task_history.html:6
3
ops/templates/ops/task_list.html:40
msgid "Time"
msgstr "时间"
#: ops/models
.py:310
ops/templates/ops/adhoc_detail.html:106
#: ops/models
/adhoc.py:326
ops/templates/ops/adhoc_detail.html:106
#: ops/templates/ops/adhoc_history.html:55
#: ops/templates/ops/adhoc_history_detail.html:6
6
#: ops/templates/ops/task_detail.html:8
0 ops/templates/ops/task_history.html:58
#: ops/templates/ops/adhoc_history_detail.html:6
9
#: ops/templates/ops/task_detail.html:8
3 ops/templates/ops/task_history.html:61
msgid "Is finished"
msgstr "是否完成"
#: ops/models
.py:311
ops/templates/ops/adhoc_history.html:56
#: ops/templates/ops/task_history.html:
59
#: ops/models
/adhoc.py:327
ops/templates/ops/adhoc_history.html:56
#: ops/templates/ops/task_history.html:
62
msgid "Is success"
msgstr "是否成功"
#: ops/models
.py:312
#: ops/models
/adhoc.py:328
msgid "Adhoc raw result"
msgstr "结果"
#: ops/models
.py:313
#: ops/models
/adhoc.py:329
msgid "Adhoc result summary"
msgstr "汇总"
...
...
@@ -1485,8 +1489,8 @@ msgid "Version run history"
msgstr "执行历史"
#: ops/templates/ops/adhoc_detail.html:49
#: ops/templates/ops/adhoc_history_detail.html:4
6
#: ops/templates/ops/task_detail.html:5
2
#: ops/templates/ops/adhoc_history_detail.html:4
9
#: ops/templates/ops/task_detail.html:5
5
#: terminal/templates/terminal/session_list.html:70
#: users/templates/users/login_log_list.html:48
msgid "ID"
...
...
@@ -1496,59 +1500,59 @@ msgstr "ID"
msgid "Run times"
msgstr "执行次数"
#: ops/templates/ops/adhoc_detail.html:98 ops/templates/ops/task_detail.html:7
2
#: ops/templates/ops/adhoc_detail.html:98 ops/templates/ops/task_detail.html:7
5
msgid "Last run"
msgstr "最后运行"
#: ops/templates/ops/adhoc_detail.html:102
#: ops/templates/ops/adhoc_history_detail.html:6
2
#: ops/templates/ops/task_detail.html:7
6
#: ops/templates/ops/adhoc_history_detail.html:6
5
#: ops/templates/ops/task_detail.html:7
9
msgid "Time delta"
msgstr "运行时间"
#: ops/templates/ops/adhoc_detail.html:110
#: ops/templates/ops/adhoc_history_detail.html:7
0
#: ops/templates/ops/task_detail.html:8
4
#: ops/templates/ops/adhoc_history_detail.html:7
3
#: ops/templates/ops/task_detail.html:8
7
msgid "Is success "
msgstr "成功"
#: ops/templates/ops/adhoc_detail.html:131
#: ops/templates/ops/task_detail.html:10
5
#: ops/templates/ops/task_detail.html:10
8
msgid "Last run failed hosts"
msgstr "最后运行失败主机"
#: ops/templates/ops/adhoc_detail.html:151
#: ops/templates/ops/adhoc_detail.html:176
#: ops/templates/ops/task_detail.html:12
5
#: ops/templates/ops/task_detail.html:15
0
#: ops/templates/ops/task_detail.html:12
8
#: ops/templates/ops/task_detail.html:15
3
msgid "No hosts"
msgstr "没有主机"
#: ops/templates/ops/adhoc_detail.html:161
#: ops/templates/ops/task_detail.html:13
5
#: ops/templates/ops/task_detail.html:13
8
msgid "Last run success hosts"
msgstr "最后运行成功主机"
#: ops/templates/ops/adhoc_history.html:30
#: ops/templates/ops/task_history.html:3
3
#: ops/templates/ops/task_history.html:3
6
msgid "History of "
msgstr "执行历史"
#: ops/templates/ops/adhoc_history.html:52
#: ops/templates/ops/adhoc_history_detail.html:
58
#: ops/templates/ops/task_history.html:5
5
terminal/models.py:132
#: ops/templates/ops/adhoc_history_detail.html:
61
#: ops/templates/ops/task_history.html:5
8
terminal/models.py:132
#: terminal/templates/terminal/session_list.html:77
msgid "Date start"
msgstr "开始日期"
#: ops/templates/ops/adhoc_history.html:53
#: ops/templates/ops/task_history.html:5
6
#: ops/templates/ops/task_history.html:5
9
msgid "F/S/T"
msgstr "失败/成功/总"
#: ops/templates/ops/adhoc_history.html:58
#: ops/templates/ops/adhoc_history_detail.html:5
4
#: ops/templates/ops/task_adhoc.html:5
5 ops/templates/ops/task_history.html:61
#: ops/templates/ops/adhoc_history_detail.html:5
7
#: ops/templates/ops/task_adhoc.html:5
8 ops/templates/ops/task_history.html:64
msgid "Version"
msgstr "版本"
...
...
@@ -1556,24 +1560,29 @@ msgstr "版本"
msgid "Run history detail"
msgstr "执行历史详情"
#: ops/templates/ops/adhoc_history_detail.html:27
#: ops/templates/ops/adhoc_history_detail.html:22
#: terminal/backends/command/models.py:14
msgid "Output"
msgstr "输出"
#: ops/templates/ops/adhoc_history_detail.html:30
msgid "History detail of"
msgstr "执行历史详情"
#: ops/templates/ops/adhoc_history_detail.html:5
0
#: ops/templates/ops/adhoc_history_detail.html:5
3
msgid "Task name"
msgstr "任务名称"
#: ops/templates/ops/adhoc_history_detail.html:8
1
#: ops/templates/ops/adhoc_history_detail.html:8
4
msgid "Failed assets"
msgstr "失败资产"
#: ops/templates/ops/adhoc_history_detail.html:10
1
#: ops/templates/ops/adhoc_history_detail.html:12
6
#: ops/templates/ops/adhoc_history_detail.html:10
4
#: ops/templates/ops/adhoc_history_detail.html:12
9
msgid "No assets"
msgstr "没有资产"
#: ops/templates/ops/adhoc_history_detail.html:11
1
#: ops/templates/ops/adhoc_history_detail.html:11
4
msgid "Success assets"
msgstr "成功资产"
...
...
@@ -1592,25 +1601,30 @@ msgstr "任务各版本"
msgid "Run history"
msgstr "执行历史"
#: ops/templates/ops/task_adhoc.html:33
#: ops/templates/ops/task_adhoc.html:28 ops/templates/ops/task_detail.html:28
#: ops/templates/ops/task_history.html:28
msgid "Last run output"
msgstr "输出"
#: ops/templates/ops/task_adhoc.html:36
msgid "Versions of "
msgstr "版本"
#: ops/templates/ops/task_adhoc.html:6
0
#: ops/templates/ops/task_adhoc.html:6
3
#: terminal/templates/terminal/command_list.html:76
#: terminal/templates/terminal/session_detail.html:50
msgid "Datetime"
msgstr "日期"
#: ops/templates/ops/task_detail.html:6
4
#: ops/templates/ops/task_detail.html:6
7
msgid "Total versions"
msgstr "版本数量"
#: ops/templates/ops/task_detail.html:
68
#: ops/templates/ops/task_detail.html:
71
msgid "Latest version"
msgstr "最新版本"
#: ops/templates/ops/task_detail.html:
88
#: ops/templates/ops/task_detail.html:
91
msgid "Contents"
msgstr "内容"
...
...
@@ -1639,7 +1653,7 @@ msgstr "日期"
msgid "Run"
msgstr "执行"
#: ops/templates/ops/task_list.html:12
3
#: ops/templates/ops/task_list.html:12
4
msgid "Task start: "
msgstr "任务开始: "
...
...
@@ -1705,7 +1719,7 @@ msgstr "添加"
msgid "Add asset group to this permission"
msgstr "添加资产组"
#: perms/templates/perms/asset_permission_asset.html:116 users/forms.py:27
3
#: perms/templates/perms/asset_permission_asset.html:116 users/forms.py:27
5
msgid "Select asset groups"
msgstr "选择资产组"
...
...
@@ -1734,7 +1748,7 @@ msgstr "资产组数量"
msgid "System user count"
msgstr "系统用户数量"
#: perms/templates/perms/asset_permission_detail.html:144 users/forms.py:27
6
#: perms/templates/perms/asset_permission_detail.html:144 users/forms.py:27
8
msgid "Select system users"
msgstr "选择系统用户"
...
...
@@ -1787,7 +1801,7 @@ msgstr "商业支持"
msgid "Docs"
msgstr "文档"
#: templates/_header_bar.html:37 templates/_nav_user.html:9 users/forms.py:9
2
#: templates/_header_bar.html:37 templates/_nav_user.html:9 users/forms.py:9
4
#: users/templates/users/_user.html:36
#: users/templates/users/user_password_update.html:37
#: users/templates/users/user_profile.html:17
...
...
@@ -1912,10 +1926,6 @@ msgstr "过滤"
msgid "Input"
msgstr "输入"
#: terminal/backends/command/models.py:14
msgid "Output"
msgstr "输出"
#: terminal/backends/command/models.py:15
#: terminal/templates/terminal/command_list.html:75
#: terminal/templates/terminal/terminal_list.html:33
...
...
@@ -2179,11 +2189,11 @@ msgstr ""
msgid "Role"
msgstr "角色"
#: users/forms.py:30 users/forms.py:1
38
#: users/forms.py:30 users/forms.py:1
40
msgid "ssh public key"
msgstr "ssh公钥"
#: users/forms.py:31 users/forms.py:1
39
#: users/forms.py:31 users/forms.py:1
41
msgid "ssh-rsa AAAA..."
msgstr ""
...
...
@@ -2195,39 +2205,39 @@ msgstr "复制用户公钥到这里"
msgid "Join user groups"
msgstr "添加到用户组"
#: users/forms.py:
58 users/forms.py:153
#: users/forms.py:
60 users/forms.py:155
msgid "Public key should not be the same as your old one."
msgstr "不能和原来的密钥相同"
#: users/forms.py:6
2 users/forms.py:157
users/serializers.py:42
#: users/forms.py:6
4 users/forms.py:159
users/serializers.py:42
msgid "Not a valid ssh public key"
msgstr "ssh密钥不合法"
#: users/forms.py:
98
#: users/forms.py:
100
msgid "Old password"
msgstr "原来密码"
#: users/forms.py:10
3
#: users/forms.py:10
5
msgid "New password"
msgstr "新密码"
#: users/forms.py:1
08
#: users/forms.py:1
10
msgid "Confirm password"
msgstr "确认密码"
#: users/forms.py:1
18
#: users/forms.py:1
20
msgid "Old password error"
msgstr "原来密码错误"
#: users/forms.py:12
6
#: users/forms.py:12
8
msgid "Password does not match"
msgstr "密码不一致"
#: users/forms.py:14
0
#: users/forms.py:14
2
msgid "Paste your id_rsa.pub here."
msgstr "复制你的公钥到这里"
#: users/forms.py:1
68
users/models/user.py:46
#: users/forms.py:1
70
users/models/user.py:46
#: users/templates/users/user_password_update.html:43
#: users/templates/users/user_profile.html:71
#: users/templates/users/user_profile_update.html:43
...
...
@@ -2235,7 +2245,7 @@ msgstr "复制你的公钥到这里"
msgid "Public key"
msgstr "ssh公钥"
#: users/forms.py:17
5 users/forms.py:180 users/forms.py:192 users/forms.py:222
#: users/forms.py:17
7 users/forms.py:182 users/forms.py:194 users/forms.py:224
msgid "Select users"
msgstr "选择用户"
...
...
@@ -2777,4 +2787,3 @@ msgstr "密码更新"
#: users/views/user.py:375
msgid "Public key update"
msgstr "密钥更新"
apps/ops/api.py
View file @
d247e49b
...
...
@@ -6,18 +6,15 @@ from django.core.cache import cache
from
django.shortcuts
import
get_object_or_404
from
django.utils.translation
import
ugettext
as
_
from
rest_framework
import
viewsets
,
generics
from
rest_framework.views
import
APIView
from
rest_framework.views
import
Response
from
.hands
import
IsSuperUser
from
common.const
import
FILE_END_GUARD
from
.
models
import
Task
,
AdHoc
,
AdHocRunHistory
from
.serializers
import
TaskSerializer
,
AdHocSerializer
,
AdHocRunHistorySerializer
from
.models
import
Task
,
AdHoc
,
AdHocRunHistory
,
CeleryTask
from
.
serializers
import
TaskSerializer
,
AdHocSerializer
,
\
AdHocRunHistorySerializer
from
.tasks
import
run_ansible_task
class
TaskViewSet
(
viewsets
.
ModelViewSet
):
queryset
=
Task
.
objects
.
all
()
serializer_class
=
TaskSerializer
...
...
@@ -67,28 +64,28 @@ class AdHocRunHistorySet(viewsets.ModelViewSet):
return
self
.
queryset
class
LogFileViewApi
(
APIView
):
class
CeleryTaskLogApi
(
generics
.
Retrieve
APIView
):
permission_classes
=
(
IsSuperUser
,)
buff_size
=
1024
*
10
end
=
False
queryset
=
CeleryTask
.
objects
.
all
()
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
file_path
=
request
.
query_params
.
get
(
"file"
)
mark
=
request
.
query_params
.
get
(
"mark"
)
or
str
(
uuid
.
uuid4
())
task
=
super
()
.
get_object
()
log_path
=
task
.
full_log_path
if
not
os
.
path
.
isfile
(
file_path
):
print
(
file_path
)
return
Response
({
"error"
:
_
(
"Log file not found"
)},
status
=
204
)
if
not
log_path
or
not
os
.
path
.
isfile
(
log_path
):
return
Response
({
"data"
:
_
(
"Waiting ..."
)},
status
=
203
)
with
open
(
file
_path
,
'r'
)
as
f
:
with
open
(
log
_path
,
'r'
)
as
f
:
offset
=
cache
.
get
(
mark
,
0
)
f
.
seek
(
offset
)
data
=
f
.
read
(
self
.
buff_size
)
.
replace
(
'
\n
'
,
'
\r\n
'
)
mark
=
str
(
uuid
.
uuid4
())
cache
.
set
(
mark
,
f
.
tell
(),
5
)
if
FILE_END_GUARD
in
data
:
data
.
replace
(
FILE_END_GUARD
,
''
)
if
data
==
''
and
task
.
is_finished
():
self
.
end
=
True
return
Response
({
"data"
:
data
,
'end'
:
self
.
end
,
'mark'
:
mark
})
apps/ops/apps.py
View file @
d247e49b
...
...
@@ -5,3 +5,7 @@ from django.apps import AppConfig
class
OpsConfig
(
AppConfig
):
name
=
'ops'
def
ready
(
self
):
super
()
.
ready
()
from
.celery
import
signal_handler
apps/ops/celery/__init__.py
View file @
d247e49b
...
...
@@ -15,4 +15,3 @@ app = Celery('jumpserver')
# pickle the object when using Windows.
app
.
config_from_object
(
'django.conf:settings'
,
namespace
=
'CELERY'
)
app
.
autodiscover_tasks
(
lambda
:
[
app_config
.
split
(
'.'
)[
0
]
for
app_config
in
settings
.
INSTALLED_APPS
])
apps/ops/celery/signal_handler.py
View file @
d247e49b
...
...
@@ -5,27 +5,21 @@ import datetime
import
sys
from
django.conf
import
settings
from
django.utils
import
timezone
from
django.core.cache
import
cache
from
django.db
import
transaction
from
celery
import
subtask
from
celery.signals
import
worker_ready
,
worker_shutdown
,
task_prerun
,
\
task_postrun
,
after_task_publish
from
django_celery_beat.models
import
PeriodicTask
from
common.utils
import
get_logger
,
TeeObj
from
common.utils
import
get_logger
,
TeeObj
,
get_object_or_none
from
common.const
import
celery_task_pre_key
from
.utils
import
get_after_app_ready_tasks
,
get_after_app_shutdown_clean_tasks
from
..models
import
CeleryTask
logger
=
get_logger
(
__file__
)
WAITING
=
"waiting"
RUNNING
=
"running"
FINISHED
=
"finished"
EXPIRE_TIME
=
3600
@worker_ready.connect
def
on_app_ready
(
sender
=
None
,
headers
=
None
,
body
=
None
,
**
kwargs
):
...
...
@@ -54,18 +48,31 @@ def after_app_shutdown(sender=None, headers=None, body=None, **kwargs):
PeriodicTask
.
objects
.
filter
(
name__in
=
tasks
)
.
delete
()
@after_task_publish.connect
def
after_task_publish_signal_handler
(
sender
,
headers
=
None
,
**
kwargs
):
CeleryTask
.
objects
.
create
(
id
=
headers
[
"id"
],
status
=
CeleryTask
.
WAITING
,
name
=
headers
[
"task"
]
)
@task_prerun.connect
def
pre_run_task_signal_handler
(
sender
,
task_id
=
None
,
task
=
None
,
**
kwargs
):
task_key
=
celery_task_pre_key
+
task_id
info
=
cache
.
get
(
task_key
,
{})
t
=
get_object_or_none
(
CeleryTask
,
id
=
task_id
)
if
t
is
None
:
logger
.
warn
(
"Not get the task: {}"
.
format
(
task_id
))
return
now
=
datetime
.
datetime
.
now
()
.
strftime
(
"
%
Y-
%
m-
%
d"
)
log_dir
=
os
.
path
.
join
(
settings
.
PROJECT_DIR
,
"data"
,
"celery"
,
now
)
if
not
os
.
path
.
exists
(
log_dir
):
os
.
makedirs
(
log_dir
)
log_path
=
os
.
path
.
join
(
log_dir
,
task_id
+
'.log'
)
info
.
update
({
"status"
:
RUNNING
,
"log_path"
:
log_path
})
cache
.
set
(
task_key
,
info
,
EXPIRE_TIME
)
f
=
open
(
log_path
,
'w'
)
log_path
=
os
.
path
.
join
(
now
,
task_id
+
'.log'
)
full_path
=
os
.
path
.
join
(
CeleryTask
.
LOG_DIR
,
log_path
)
if
not
os
.
path
.
exists
(
os
.
path
.
dirname
(
full_path
)):
os
.
makedirs
(
os
.
path
.
dirname
(
full_path
))
with
transaction
.
atomic
():
t
.
date_start
=
timezone
.
now
()
t
.
status
=
CeleryTask
.
RUNNING
t
.
log_path
=
log_path
t
.
save
()
f
=
open
(
full_path
,
'w'
)
tee
=
TeeObj
(
f
)
sys
.
stdout
=
tee
task
.
log_f
=
tee
...
...
@@ -73,17 +80,15 @@ def pre_run_task_signal_handler(sender, task_id=None, task=None, **kwargs):
@task_postrun.connect
def
post_run_task_signal_handler
(
sender
,
task_id
=
None
,
task
=
None
,
**
kwargs
):
task_key
=
celery_task_pre_key
+
task_id
info
=
cache
.
get
(
task_key
,
{})
info
.
update
({
"status"
:
FINISHED
})
cache
.
set
(
task_key
,
info
,
EXPIRE_TIME
)
t
=
get_object_or_none
(
CeleryTask
,
id
=
task_id
)
if
t
is
None
:
logger
.
warn
(
"Not get the task: {}"
.
format
(
task_id
))
return
with
transaction
.
atomic
():
t
.
status
=
CeleryTask
.
FINISHED
t
.
date_finished
=
timezone
.
now
()
t
.
save
()
task
.
log_f
.
flush
()
sys
.
stdout
=
task
.
log_f
.
origin_stdout
task
.
log_f
.
close
()
@after_task_publish.connect
def
after_task_publish_signal_handler
(
sender
,
headers
=
None
,
**
kwargs
):
task_id
=
headers
[
"id"
]
key
=
celery_task_pre_key
+
task_id
cache
.
set
(
key
,
{
"status"
:
WAITING
},
EXPIRE_TIME
)
\ No newline at end of file
apps/ops/models/__init__.py
0 → 100644
View file @
d247e49b
# -*- coding: utf-8 -*-
#
from
.adhoc
import
*
from
.celery
import
*
\ No newline at end of file
apps/ops/models.py
→
apps/ops/models
/adhoc
.py
View file @
d247e49b
...
...
@@ -11,15 +11,14 @@ from django.db import models
from
django.conf
import
settings
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
django_celery_beat.models
import
CrontabSchedule
,
IntervalSchedule
,
\
PeriodicTask
from
django_celery_beat.models
import
PeriodicTask
from
common.utils
import
get_signer
,
get_logger
from
.celery.utils
import
delete_celery_periodic_task
,
\
from
.
.
celery.utils
import
delete_celery_periodic_task
,
\
create_or_update_celery_periodic_tasks
,
\
disable_celery_periodic_task
from
.ansible
import
AdHocRunner
,
AnsibleError
from
.inventory
import
JMSInventory
from
.
.
ansible
import
AdHocRunner
,
AnsibleError
from
.
.
inventory
import
JMSInventory
__all__
=
[
"Task"
,
"AdHoc"
,
"AdHocRunHistory"
]
...
...
@@ -91,7 +90,7 @@ class Task(models.Model):
def
save
(
self
,
force_insert
=
False
,
force_update
=
False
,
using
=
None
,
update_fields
=
None
):
from
.tasks
import
run_ansible_task
from
.
.
tasks
import
run_ansible_task
super
()
.
save
(
force_insert
=
force_insert
,
force_update
=
force_update
,
using
=
using
,
update_fields
=
update_fields
,
...
...
apps/ops/models/celery.py
0 → 100644
View file @
d247e49b
# -*- coding: utf-8 -*-
#
import
uuid
import
os
from
django.conf
import
settings
from
django.db
import
models
class
CeleryTask
(
models
.
Model
):
WAITING
=
"waiting"
RUNNING
=
"running"
FINISHED
=
"finished"
LOG_DIR
=
os
.
path
.
join
(
settings
.
PROJECT_DIR
,
'data'
,
'celery'
)
STATUS_CHOICES
=
(
(
WAITING
,
WAITING
),
(
RUNNING
,
RUNNING
),
(
FINISHED
,
FINISHED
),
)
id
=
models
.
UUIDField
(
primary_key
=
True
,
default
=
uuid
.
uuid4
)
name
=
models
.
CharField
(
max_length
=
1024
)
status
=
models
.
CharField
(
max_length
=
128
,
choices
=
STATUS_CHOICES
)
log_path
=
models
.
CharField
(
max_length
=
256
,
blank
=
True
,
null
=
True
)
date_published
=
models
.
DateTimeField
(
auto_now_add
=
True
)
date_start
=
models
.
DateTimeField
(
null
=
True
)
date_finished
=
models
.
DateTimeField
(
null
=
True
)
def
__str__
(
self
):
return
"{}: {}"
.
format
(
self
.
name
,
self
.
id
)
def
is_finished
(
self
):
return
self
.
status
==
self
.
FINISHED
@property
def
full_log_path
(
self
):
return
os
.
path
.
join
(
self
.
LOG_DIR
,
self
.
log_path
)
apps/ops/tasks.py
View file @
d247e49b
# coding: utf-8
from
celery
import
shared_task
,
subtask
from
common.utils
import
get_logger
,
get_object_or_none
from
.models
import
Task
...
...
apps/ops/templates/ops/adhoc_history_detail.html
View file @
d247e49b
...
...
@@ -19,7 +19,7 @@
<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>
<li>
<a
href=
"{% url 'ops:adhoc-history-output' pk=object.pk %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'History o
utput' %}
</a>
<a
class=
"text-center celery-task-log"
onclick=
"window.open('{% url 'ops:celery-task-log' pk=object.pk %}','', 'width=800,height=600')"
><i
class=
"fa fa-laptop"
></i>
{% trans 'O
utput' %}
</a>
</li>
</ul>
</div>
...
...
apps/ops/templates/ops/adhoc_history_output.html
deleted
100644 → 0
View file @
a4c843ff
{% 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>
</head>
{% 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-history-detail' pk=object.pk %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Run history detail' %}
</a>
</li>
<li
class=
"active"
>
<a
href=
"{% url 'ops:adhoc-history-output' pk=object.pk %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'History output' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
style=
"height: 800px"
>
<iframe
src=
"{% url 'ops:adhoc-history-output-alone' pk=object.pk %}"
width=
"100%"
height=
"100%"
>
</iframe>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
apps/
common/templates/common
/celery_task_log.html
→
apps/
ops/templates/ops
/celery_task_log.html
View file @
d247e49b
...
...
@@ -35,7 +35,7 @@
var
rowHeight
=
1
;
var
colWidth
=
1
;
var
mark
=
''
;
var
url
=
"{% url 'api-
common:celery-task-log' pk=task_
id %}"
;
var
url
=
"{% url 'api-
ops:celery-task-log' pk=object.
id %}"
;
var
term
;
var
end
=
false
;
var
error
=
false
;
...
...
apps/ops/templates/ops/celery_task_output.html
deleted
100644 → 0
View file @
a4c843ff
{% load static %}
<head>
<title>
term.js
</title>
<script
src=
"{% static 'js/jquery-2.1.1.js' %}"
></script>
<style>
html
{
background
:
#000
;
}
h1
{
margin-bottom
:
20px
;
font
:
20px
/
1.5
sans-serif
;
}
.terminal
{
float
:
left
;
font-family
:
'Monaco'
,
'Consolas'
,
"DejaVu Sans Mono"
,
"Liberation Mono"
,
monospace
;
font-size
:
12px
;
color
:
#f0f0f0
;
background-color
:
#555
;
padding
:
20px
20px
20px
;
}
.terminal-cursor
{
color
:
#000
;
background
:
#f0f0f0
;
}
</style>
</head>
<div
class=
"container"
>
<div
id=
"term"
>
</div>
</div>
<script
src=
"{% static 'js/term.js' %}"
></script>
<script>
var
rowHeight
=
1
;
var
colWidth
=
1
;
var
mark
=
''
;
var
url
=
"{% url 'api-ops:history-output' pk=object.id %}"
;
var
term
;
var
end
=
false
;
var
has_error
=
false
;
function
calWinSize
()
{
var
t
=
$
(
'.terminal'
);
rowHeight
=
1.00
*
t
.
height
()
/
24
;
colWidth
=
1.00
*
t
.
width
()
/
80
;
}
function
resize
()
{
var
rows
=
Math
.
floor
(
window
.
innerHeight
/
rowHeight
)
-
2
;
var
cols
=
Math
.
floor
(
window
.
innerWidth
/
colWidth
)
-
5
;
term
.
resize
(
cols
,
rows
);
}
function
requestAndWrite
()
{
if
(
!
end
)
{
$
.
ajax
({
url
:
url
+
'?mark='
+
mark
,
method
:
"GET"
,
contentType
:
"application/json; charset=utf-8"
}).
done
(
function
(
data
,
textStatue
,
jqXHR
)
{
term
.
write
(
data
.
data
);
mark
=
data
.
mark
;
if
(
data
.
end
){
end
=
true
}
}).
fail
(
function
(
jqXHR
,
textStatus
,
errorThrown
)
{
if
(
!
has_error
)
{
var
error
=
jqXHR
.
responseJSON
.
error
;
term
.
write
(
'
\
x1b[31m'
+
error
+
'
\
x1b[m
\
r
\
n'
);
has_error
=
true
}
});
}
}
$
(
document
).
ready
(
function
()
{
term
=
new
Terminal
({
cols
:
80
,
rows
:
24
,
useStyle
:
true
,
screenKeys
:
false
,
convertEol
:
false
,
cursorBlink
:
false
});
term
.
open
();
term
.
on
(
'data'
,
function
(
data
)
{
term
.
write
(
data
.
replace
(
'
\
r'
,
'
\
r
\
n'
))
});
calWinSize
();
resize
();
$
(
'.terminal'
).
detach
().
appendTo
(
'#term'
);
setInterval
(
function
()
{
requestAndWrite
()
},
200
)
});
</script>
apps/ops/templates/ops/task_adhoc.html
View file @
d247e49b
...
...
@@ -24,6 +24,9 @@
<li>
<a
href=
"{% url 'ops:task-history' pk=object.pk %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Run history' %}
</a>
</li>
<li>
<a
class=
"text-center celery-task-log"
onclick=
"window.open('{% url 'ops:celery-task-log' pk=object.latest_history.pk %}','', 'width=800,height=600')"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Last run output' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
apps/ops/templates/ops/task_detail.html
View file @
d247e49b
...
...
@@ -25,7 +25,7 @@
<a
href=
"{% url 'ops:task-history' pk=object.pk %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Run history' %}
</a>
</li>
<li>
<a
href=
"{% url 'ops:adhoc-history-output' pk=object.latest_history.pk %}"
class=
"text-center
"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Last run output' %}
</a>
<a
class=
"text-center celery-task-log"
onclick=
"window.open('{% url 'ops:celery-task-log' pk=object.latest_history.pk %}','', 'width=800,height=600')
"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Last run output' %}
</a>
</li>
</ul>
</div>
...
...
apps/ops/templates/ops/task_history.html
View file @
d247e49b
...
...
@@ -24,6 +24,9 @@
<li
class=
"active"
>
<a
href=
"{% url 'ops:task-history' pk=object.pk %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Run history' %}
</a>
</li>
<li>
<a
class=
"text-center celery-task-log"
onclick=
"window.open('{% url 'ops:celery-task-log' pk=object.latest_history.pk %}','', 'width=800,height=600')"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Last run output' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
apps/ops/templates/ops/task_list.html
View file @
d247e49b
...
...
@@ -113,8 +113,8 @@ $(document).ready(function() {
};
var
success
=
function
(
data
)
{
var
task_id
=
data
.
task
;
var
url
=
'{% url "
common
:celery-task-log" pk=DEFAULT_PK %}'
.
replace
(
"{{ DEFAULT_PK }}"
,
task_id
);
window
.
open
(
url
,
''
,
'width=800,height=
8
00'
)
var
url
=
'{% url "
ops
:celery-task-log" pk=DEFAULT_PK %}'
.
replace
(
"{{ DEFAULT_PK }}"
,
task_id
);
window
.
open
(
url
,
''
,
'width=800,height=
6
00'
)
};
APIUpdateAttr
({
url
:
the_url
,
...
...
apps/ops/urls/api_urls.py
View file @
d247e49b
...
...
@@ -15,7 +15,7 @@ router.register(r'v1/history', api.AdHocRunHistorySet, 'history')
urlpatterns
=
[
url
(
r'^v1/tasks/(?P<pk>[0-9a-zA-Z\-]{36})/run/$'
,
api
.
TaskRun
.
as_view
(),
name
=
'task-run'
),
# url(r'^v1/history/(?P<pk>[0-9a-zA-Z\-]{36})/output/$', api.CeleryTaskOutputApi.as_view(), name='history-output
'),
url
(
r'^v1/celery/task/(?P<pk>[0-9a-zA-Z\-]{36})/log/$'
,
api
.
CeleryTaskLogApi
.
as_view
(),
name
=
'celery-task-log
'
),
]
urlpatterns
+=
router
.
urls
apps/ops/urls/view_urls.py
View file @
d247e49b
...
...
@@ -18,6 +18,5 @@ urlpatterns = [
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'
),
url
(
r'^adhoc/history/(?P<pk>[0-9a-zA-Z\-]{36})/_output/$'
,
views
.
CeleryTaskOutputView
.
as_view
(),
name
=
'adhoc-history-output-alone'
),
url
(
r'^adhoc/history/(?P<pk>[0-9a-zA-Z\-]{36})/output/$'
,
views
.
AdHocHistoryOutputView
.
as_view
(),
name
=
'adhoc-history-output'
),
url
(
r'^celery/task/(?P<pk>[0-9a-zA-Z\-]{36})/log/$'
,
views
.
CeleryTaskLogView
.
as_view
(),
name
=
'celery-task-log'
),
]
apps/ops/views.py
View file @
d247e49b
...
...
@@ -5,7 +5,7 @@ from django.conf import settings
from
django.views.generic
import
ListView
,
DetailView
,
TemplateView
from
common.mixins
import
DatetimeSearchMixin
from
.models
import
Task
,
AdHoc
,
AdHocRunHistory
from
.models
import
Task
,
AdHoc
,
AdHocRunHistory
,
CeleryTask
from
.hands
import
AdminUserRequiredMixin
...
...
@@ -121,19 +121,6 @@ class AdHocHistoryDetailView(AdminUserRequiredMixin, DetailView):
return
super
()
.
get_context_data
(
**
kwargs
)
class
CeleryTaskOutputView
(
AdminUserRequiredMixin
,
TemplateView
):
model
=
AdHocRunHistory
template_name
=
'ops/celery_task_output.html'
class
AdHocHistoryOutputView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
AdHocRunHistory
template_name
=
'ops/adhoc_history_output.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
class
CeleryTaskLogView
(
AdminUserRequiredMixin
,
DetailView
):
template_name
=
'ops/celery_task_log.html'
model
=
CeleryTask
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