* [Update] 更新翻译 (#2541)

* [Update] 更新缓存机制

* [Update] 增加task最大允许事件,并设置命令最大运行时间为60s
pull/2548/head
老广 2019-03-27 11:21:21 +08:00 committed by GitHub
parent 8fede58c64
commit 69f6401e87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 296 additions and 172 deletions

View File

@ -46,7 +46,7 @@
<tr> <tr>
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th> <th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
<th class="text-center">{% trans 'Username' %}</th> <th class="text-center">{% trans 'Username' %}</th>
<th class="text-center">{% trans 'Version' %}</th> <th class="text-center">{% trans 'Password version' %}</th>
<th class="text-center">{% trans 'Reachable' %}</th> <th class="text-center">{% trans 'Reachable' %}</th>
<th class="text-center">{% trans 'Date updated' %}</th> <th class="text-center">{% trans 'Date updated' %}</th>
<th class="text-center">{% trans 'Action' %}</th> <th class="text-center">{% trans 'Action' %}</th>

View File

@ -70,6 +70,14 @@ class IsCurrentUserOrReadOnly(permissions.BasePermission):
return obj == request.user return obj == request.user
class LoginRequiredMixin(UserPassesTestMixin):
def test_func(self):
if self.request.user.is_authenticated:
return True
else:
return False
class AdminUserRequiredMixin(UserPassesTestMixin): class AdminUserRequiredMixin(UserPassesTestMixin):
def test_func(self): def test_func(self):
if not self.request.user.is_authenticated: if not self.request.user.is_authenticated:

View File

@ -475,6 +475,7 @@ CELERY_WORKER_REDIRECT_STDOUTS = True
CELERY_WORKER_REDIRECT_STDOUTS_LEVEL = "INFO" CELERY_WORKER_REDIRECT_STDOUTS_LEVEL = "INFO"
# CELERY_WORKER_HIJACK_ROOT_LOGGER = True # CELERY_WORKER_HIJACK_ROOT_LOGGER = True
CELERY_WORKER_MAX_TASKS_PER_CHILD = 40 CELERY_WORKER_MAX_TASKS_PER_CHILD = 40
CELERY_TASK_SOFT_TIME_LIMIT = 3600
# Cache use redis # Cache use redis
CACHES = { CACHES = {

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n" "Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-03-22 17:12+0800\n" "POT-Creation-Date: 2019-03-26 14:56+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n" "Language-Team: Jumpserver team<ibuler@qq.com>\n"
@ -73,7 +73,7 @@ msgstr "网域"
#: perms/templates/perms/asset_permission_list.html:57 #: perms/templates/perms/asset_permission_list.html:57
#: perms/templates/perms/asset_permission_list.html:78 #: perms/templates/perms/asset_permission_list.html:78
#: perms/templates/perms/asset_permission_list.html:128 #: perms/templates/perms/asset_permission_list.html:128
#: xpack/plugins/change_auth_plan/forms.py:101 #: xpack/plugins/change_auth_plan/forms.py:115
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:55 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:55
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:15 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:15
#: xpack/plugins/cloud/models.py:123 #: xpack/plugins/cloud/models.py:123
@ -102,7 +102,7 @@ msgstr "如果有多个的互相隔离的网络,设置资产属于的网域,
#: assets/forms/asset.py:92 assets/forms/asset.py:96 assets/forms/domain.py:17 #: assets/forms/asset.py:92 assets/forms/asset.py:96 assets/forms/domain.py:17
#: assets/forms/label.py:15 #: assets/forms/label.py:15
#: perms/templates/perms/asset_permission_asset.html:88 #: perms/templates/perms/asset_permission_asset.html:88
#: xpack/plugins/change_auth_plan/forms.py:92 #: xpack/plugins/change_auth_plan/forms.py:105
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:84 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:84
msgid "Select assets" msgid "Select assets"
msgstr "选择资产" msgstr "选择资产"
@ -125,9 +125,9 @@ msgstr "选择资产"
#: terminal/templates/terminal/command_list.html:73 #: terminal/templates/terminal/command_list.html:73
#: terminal/templates/terminal/session_list.html:41 #: terminal/templates/terminal/session_list.html:41
#: terminal/templates/terminal/session_list.html:72 #: terminal/templates/terminal/session_list.html:72
#: xpack/plugins/change_auth_plan/models.py:65 #: xpack/plugins/change_auth_plan/forms.py:114
#: xpack/plugins/change_auth_plan/models.py:401 #: xpack/plugins/change_auth_plan/models.py:408
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:40 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:46
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:54 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:54
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:13 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:13
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:14 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:14
@ -179,7 +179,7 @@ msgstr "SSH网关支持代理SSH,RDP和VNC"
#: users/templates/users/user_list.html:23 #: users/templates/users/user_list.html:23
#: users/templates/users/user_profile.html:51 #: users/templates/users/user_profile.html:51
#: users/templates/users/user_pubkey_update.html:53 #: users/templates/users/user_pubkey_update.html:53
#: xpack/plugins/change_auth_plan/forms.py:84 #: xpack/plugins/change_auth_plan/forms.py:97
#: xpack/plugins/change_auth_plan/models.py:58 #: xpack/plugins/change_auth_plan/models.py:58
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:61 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:61
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:12 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:12
@ -211,6 +211,13 @@ msgstr "名称"
#: users/templates/users/user_detail.html:67 #: users/templates/users/user_detail.html:67
#: users/templates/users/user_list.html:24 #: users/templates/users/user_list.html:24
#: users/templates/users/user_profile.html:47 #: users/templates/users/user_profile.html:47
#: xpack/plugins/change_auth_plan/forms.py:99
#: xpack/plugins/change_auth_plan/models.py:60
#: xpack/plugins/change_auth_plan/models.py:404
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:65
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:53
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:12
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:13
msgid "Username" msgid "Username"
msgstr "用户名" msgstr "用户名"
@ -232,7 +239,7 @@ msgstr "密码或密钥密码"
#: users/templates/users/user_pubkey_update.html:40 #: users/templates/users/user_pubkey_update.html:40
#: users/templates/users/user_update.html:20 #: users/templates/users/user_update.html:20
#: xpack/plugins/change_auth_plan/models.py:90 #: xpack/plugins/change_auth_plan/models.py:90
#: xpack/plugins/change_auth_plan/models.py:252 #: xpack/plugins/change_auth_plan/models.py:259
msgid "Password" msgid "Password"
msgstr "密码" msgstr "密码"
@ -517,9 +524,7 @@ msgstr "未知"
msgid "Latest version" msgid "Latest version"
msgstr "最新版本" msgstr "最新版本"
#: assets/models/authbook.py:29 #: assets/models/authbook.py:29 ops/templates/ops/adhoc_history.html:58
#: assets/templates/assets/asset_asset_user_list.html:49
#: ops/templates/ops/adhoc_history.html:58
#: ops/templates/ops/adhoc_history_detail.html:57 #: ops/templates/ops/adhoc_history_detail.html:57
#: ops/templates/ops/task_adhoc.html:58 ops/templates/ops/task_history.html:64 #: ops/templates/ops/task_adhoc.html:58 ops/templates/ops/task_history.html:64
msgid "Version" msgid "Version"
@ -530,12 +535,12 @@ msgid "AuthBook"
msgstr "" msgstr ""
#: assets/models/base.py:29 xpack/plugins/change_auth_plan/models.py:94 #: assets/models/base.py:29 xpack/plugins/change_auth_plan/models.py:94
#: xpack/plugins/change_auth_plan/models.py:259 #: xpack/plugins/change_auth_plan/models.py:266
msgid "SSH private key" msgid "SSH private key"
msgstr "ssh密钥" msgstr "ssh密钥"
#: assets/models/base.py:30 xpack/plugins/change_auth_plan/models.py:97 #: assets/models/base.py:30 xpack/plugins/change_auth_plan/models.py:97
#: xpack/plugins/change_auth_plan/models.py:255 #: xpack/plugins/change_auth_plan/models.py:262
msgid "SSH public key" msgid "SSH public key"
msgstr "ssh公钥" msgstr "ssh公钥"
@ -774,7 +779,7 @@ msgstr "手动登录"
#: assets/views/label.py:26 assets/views/label.py:43 assets/views/label.py:69 #: assets/views/label.py:26 assets/views/label.py:43 assets/views/label.py:69
#: assets/views/system_user.py:28 assets/views/system_user.py:44 #: assets/views/system_user.py:28 assets/views/system_user.py:44
#: assets/views/system_user.py:60 assets/views/system_user.py:74 #: assets/views/system_user.py:60 assets/views/system_user.py:74
#: templates/_nav.html:19 #: templates/_nav.html:19 xpack/plugins/change_auth_plan/models.py:65
msgid "Assets" msgid "Assets"
msgstr "资产管理" msgstr "资产管理"
@ -948,7 +953,7 @@ msgid "If set id, will use this id update asset existed"
msgstr "如果设置了id则会使用该行信息更新该id的资产" msgstr "如果设置了id则会使用该行信息更新该id的资产"
#: assets/templates/assets/_asset_list_modal.html:7 assets/views/asset.py:51 #: assets/templates/assets/_asset_list_modal.html:7 assets/views/asset.py:51
#: templates/_nav.html:22 #: templates/_nav.html:22 xpack/plugins/change_auth_plan/views.py:110
msgid "Asset list" msgid "Asset list"
msgstr "资产列表" msgstr "资产列表"
@ -957,7 +962,7 @@ msgid "Update asset user auth"
msgstr "更新资产用户认证信息" msgstr "更新资产用户认证信息"
#: assets/templates/assets/_asset_user_auth_modal.html:23 #: assets/templates/assets/_asset_user_auth_modal.html:23
#: xpack/plugins/change_auth_plan/forms.py:88 #: xpack/plugins/change_auth_plan/forms.py:101
msgid "Please input password" msgid "Please input password"
msgstr "请输入密码" msgstr "请输入密码"
@ -978,7 +983,7 @@ msgstr "如果使用了nat端口映射请设置为ssh真实监听的端口"
#: assets/templates/assets/asset_update.html:21 #: assets/templates/assets/asset_update.html:21
#: assets/templates/assets/gateway_create_update.html:37 #: assets/templates/assets/gateway_create_update.html:37
#: perms/templates/perms/asset_permission_create_update.html:38 #: perms/templates/perms/asset_permission_create_update.html:38
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:37 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:43
msgid "Basic" msgid "Basic"
msgstr "基本" msgstr "基本"
@ -1000,7 +1005,7 @@ msgstr "自动生成密钥"
#: assets/templates/assets/gateway_create_update.html:53 #: assets/templates/assets/gateway_create_update.html:53
#: perms/templates/perms/asset_permission_create_update.html:50 #: perms/templates/perms/asset_permission_create_update.html:50
#: terminal/templates/terminal/terminal_update.html:40 #: terminal/templates/terminal/terminal_update.html:40
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:61 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:67
msgid "Other" msgid "Other"
msgstr "其它" msgstr "其它"
@ -1031,7 +1036,7 @@ msgstr "其它"
#: users/templates/users/user_profile_update.html:63 #: users/templates/users/user_profile_update.html:63
#: users/templates/users/user_pubkey_update.html:70 #: users/templates/users/user_pubkey_update.html:70
#: users/templates/users/user_pubkey_update.html:76 #: users/templates/users/user_pubkey_update.html:76
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:65 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:71
#: xpack/plugins/cloud/templates/cloud/account_create_update.html:33 #: xpack/plugins/cloud/templates/cloud/account_create_update.html:33
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create.html:35 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create.html:35
#: xpack/plugins/interface/templates/interface/interface.html:88 #: xpack/plugins/interface/templates/interface/interface.html:88
@ -1068,7 +1073,7 @@ msgstr "重置"
#: users/templates/users/user_password_update.html:72 #: users/templates/users/user_password_update.html:72
#: users/templates/users/user_profile_update.html:64 #: users/templates/users/user_profile_update.html:64
#: users/templates/users/user_pubkey_update.html:77 #: users/templates/users/user_pubkey_update.html:77
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:66 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:72
#: xpack/plugins/interface/templates/interface/interface.html:89 #: xpack/plugins/interface/templates/interface/interface.html:89
msgid "Submit" msgid "Submit"
msgstr "提交" msgstr "提交"
@ -1098,7 +1103,11 @@ msgstr "关闭"
#: perms/templates/perms/asset_permission_asset.html:18 #: perms/templates/perms/asset_permission_asset.html:18
#: perms/templates/perms/asset_permission_detail.html:18 #: perms/templates/perms/asset_permission_detail.html:18
#: perms/templates/perms/asset_permission_user.html:18 #: perms/templates/perms/asset_permission_user.html:18
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:17
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:20
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:17
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:106 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:106
#: xpack/plugins/change_auth_plan/views.py:83
msgid "Detail" msgid "Detail"
msgstr "详情" msgstr "详情"
@ -1235,7 +1244,7 @@ msgstr "替换资产的管理员"
#: assets/templates/assets/admin_user_detail.html:91 #: assets/templates/assets/admin_user_detail.html:91
#: perms/templates/perms/asset_permission_asset.html:116 #: perms/templates/perms/asset_permission_asset.html:116
#: xpack/plugins/change_auth_plan/forms.py:96 #: xpack/plugins/change_auth_plan/forms.py:109
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:112 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:112
msgid "Select nodes" msgid "Select nodes"
msgstr "选择节点" msgstr "选择节点"
@ -1301,6 +1310,10 @@ msgstr "资产用户列表"
msgid "Asset users of" msgid "Asset users of"
msgstr "资产用户" msgstr "资产用户"
#: assets/templates/assets/asset_asset_user_list.html:49
msgid "Password version"
msgstr "密码版本"
#: assets/templates/assets/asset_asset_user_list.html:51 #: assets/templates/assets/asset_asset_user_list.html:51
#: assets/templates/assets/cmd_filter_detail.html:73 #: assets/templates/assets/cmd_filter_detail.html:73
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:109 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:109
@ -1927,7 +1940,7 @@ msgid "MFA"
msgstr "MFA" msgstr "MFA"
#: audits/models.py:100 audits/templates/audits/login_log_list.html:57 #: audits/models.py:100 audits/templates/audits/login_log_list.html:57
#: xpack/plugins/change_auth_plan/models.py:405 #: xpack/plugins/change_auth_plan/models.py:412
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:15 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:15
#: xpack/plugins/cloud/models.py:172 #: xpack/plugins/cloud/models.py:172
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:69 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:69
@ -1952,8 +1965,8 @@ msgstr "登录日期"
#: ops/templates/ops/task_history.html:58 perms/models.py:34 #: ops/templates/ops/task_history.html:58 perms/models.py:34
#: perms/templates/perms/asset_permission_detail.html:86 terminal/models.py:165 #: perms/templates/perms/asset_permission_detail.html:86 terminal/models.py:165
#: terminal/templates/terminal/session_list.html:78 #: terminal/templates/terminal/session_list.html:78
#: xpack/plugins/change_auth_plan/models.py:238 #: xpack/plugins/change_auth_plan/models.py:245
#: xpack/plugins/change_auth_plan/models.py:408 #: xpack/plugins/change_auth_plan/models.py:415
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:59 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:59
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:17 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:17
msgid "Date start" msgid "Date start"
@ -2283,8 +2296,8 @@ msgstr "完成时间"
#: ops/models/adhoc.py:326 ops/templates/ops/adhoc_history.html:57 #: ops/models/adhoc.py:326 ops/templates/ops/adhoc_history.html:57
#: ops/templates/ops/task_history.html:63 ops/templates/ops/task_list.html:33 #: ops/templates/ops/task_history.html:63 ops/templates/ops/task_list.html:33
#: xpack/plugins/change_auth_plan/models.py:241 #: xpack/plugins/change_auth_plan/models.py:248
#: xpack/plugins/change_auth_plan/models.py:411 #: xpack/plugins/change_auth_plan/models.py:418
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:58 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:58
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:16 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:16
msgid "Time" msgid "Time"
@ -2434,35 +2447,35 @@ msgstr "任务列表"
msgid "Go" msgid "Go"
msgstr "" msgstr ""
#: ops/templates/ops/command_execution_create.html:144 #: ops/templates/ops/command_execution_create.html:148
msgid "Selected assets" msgid "Selected assets"
msgstr "已选择资产" msgstr "已选择资产"
#: ops/templates/ops/command_execution_create.html:147 #: ops/templates/ops/command_execution_create.html:151
msgid "In total" msgid "In total"
msgstr "总共" msgstr "总共"
#: ops/templates/ops/command_execution_create.html:182 #: ops/templates/ops/command_execution_create.html:186
msgid "" msgid ""
"Select the left asset, select the running system user, execute command in " "Select the left asset, select the running system user, execute command in "
"batch" "batch"
msgstr "选择左侧资产, 选择运行的系统用户,批量执行命令" msgstr "选择左侧资产, 选择运行的系统用户,批量执行命令"
#: ops/templates/ops/command_execution_create.html:200 #: ops/templates/ops/command_execution_create.html:204
msgid "Unselected assets" msgid "Unselected assets"
msgstr "没有选中资产" msgstr "没有选中资产"
#: ops/templates/ops/command_execution_create.html:204 #: ops/templates/ops/command_execution_create.html:208
msgid "No input command" msgid "No input command"
msgstr "没有输入命令" msgstr "没有输入命令"
#: ops/templates/ops/command_execution_create.html:208 #: ops/templates/ops/command_execution_create.html:212
msgid "No system user was selected" msgid "No system user was selected"
msgstr "没有选择系统用户" msgstr "没有选择系统用户"
#: ops/templates/ops/command_execution_create.html:253 #: ops/templates/ops/command_execution_create.html:257
msgid "Pending" msgid "Pending"
msgstr "" msgstr "等待"
#: ops/templates/ops/command_execution_list.html:64 #: ops/templates/ops/command_execution_list.html:64
msgid "Finished" msgid "Finished"
@ -2521,7 +2534,7 @@ msgstr "更新任务内容: {}"
#: ops/views/adhoc.py:44 ops/views/adhoc.py:69 ops/views/adhoc.py:82 #: ops/views/adhoc.py:44 ops/views/adhoc.py:69 ops/views/adhoc.py:82
#: ops/views/adhoc.py:95 ops/views/adhoc.py:108 ops/views/adhoc.py:121 #: ops/views/adhoc.py:95 ops/views/adhoc.py:108 ops/views/adhoc.py:121
#: ops/views/adhoc.py:134 ops/views/command.py:43 ops/views/command.py:67 #: ops/views/adhoc.py:134 ops/views/command.py:44 ops/views/command.py:68
msgid "Ops" msgid "Ops"
msgstr "作业中心" msgstr "作业中心"
@ -2533,11 +2546,11 @@ msgstr "任务列表"
msgid "Task run history" msgid "Task run history"
msgstr "执行历史" msgstr "执行历史"
#: ops/views/command.py:44 #: ops/views/command.py:45
msgid "Command execution list" msgid "Command execution list"
msgstr "命令执行列表" msgstr "命令执行列表"
#: ops/views/command.py:68 templates/_nav_user.html:9 #: ops/views/command.py:69 templates/_nav_user.html:9
msgid "Command execution" msgid "Command execution"
msgstr "命令执行" msgstr "命令执行"
@ -4740,49 +4753,57 @@ msgstr "MFA 解绑成功,返回登录页面"
msgid "Password length" msgid "Password length"
msgstr "密码长度" msgstr "密码长度"
#: xpack/plugins/change_auth_plan/forms.py:40 #: xpack/plugins/change_auth_plan/forms.py:45
msgid "* For security, please do not change root user's password"
msgstr "* 为了安全请不要更改root用户的密码"
#: xpack/plugins/change_auth_plan/forms.py:54
msgid "* Please enter custom password" msgid "* Please enter custom password"
msgstr "* 请输入自定义密码" msgstr "* 请输入自定义密码"
#: xpack/plugins/change_auth_plan/forms.py:50 #: xpack/plugins/change_auth_plan/forms.py:63
msgid "* Please enter a valid crontab expression" msgid "* Please enter a valid crontab expression"
msgstr "* 请输入有效的 crontab 表达式" msgstr "* 请输入有效的 crontab 表达式"
#: xpack/plugins/change_auth_plan/forms.py:86 #: xpack/plugins/change_auth_plan/forms.py:116
#: xpack/plugins/change_auth_plan/models.py:60 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:60
#: xpack/plugins/change_auth_plan/models.py:397
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:65
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:53
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:12
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:13
msgid "Asset username"
msgstr "资产用户名"
#: xpack/plugins/change_auth_plan/forms.py:102
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:54
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:81 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:81
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:17 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:17
msgid "Periodic perform" msgid "Periodic perform"
msgstr "定时执行" msgstr "定时执行"
#: xpack/plugins/change_auth_plan/forms.py:106 #: xpack/plugins/change_auth_plan/forms.py:120
msgid ""
"Tips: Currently only unix-like assets are supported, while Windows assets "
"are not"
msgstr "提示目前仅支持类Unix资产暂不支持Windows资产"
#: xpack/plugins/change_auth_plan/forms.py:122
msgid ""
"Tips: The username of the user on the asset to be modified. if the user "
"exists, change the password; If the user does not exist, create the user."
msgstr ""
"提示:用户名为将要修改的资产上的用户的用户名。如果用户存在,则修改密码;如果"
"用户不存在,则创建用户。"
#: xpack/plugins/change_auth_plan/forms.py:126
msgid "Tips: (Units: hour)" msgid "Tips: (Units: hour)"
msgstr "提示:(单位: 时)" msgstr "提示:(单位: 时)"
#: xpack/plugins/change_auth_plan/forms.py:107 #: xpack/plugins/change_auth_plan/forms.py:127
msgid "" msgid ""
"eg: Every Sunday 03:05 run (5 3 * * 0) <br> Tips: Using 5 digits linux " "eg: Every Sunday 03:05 run <5 3 * * 0> <br> Tips: Using 5 digits linux "
"crontab expressions (<a href='https://tool.lu/crontab/' " "crontab expressions <min hour day month week> (<a href='https://tool.lu/"
"target='_blank'>Online tools</a>) <br>Note: If both Regularly perform and " "crontab/' target='_blank'>Online tools</a>) <br>Note: If both Regularly "
"Cycle perform are set, give priority to Regularly perform" "perform and Cycle perform are set, give priority to Regularly perform"
msgstr "" msgstr ""
"eg每周日 03:05 执行5 3 * * 0 <br> 提示: 使用5位 Linux crontab 表达式" "eg每周日 03:05 执行 <5 3 * * 0> <br> 提示: 使用5位 Linux crontab 表达式 <"
"<a href='https://tool.lu/crontab/' target='_blank'>在线工具</a> <br>注" "分 时 日 月 星期> <a href='https://tool.lu/crontab/' target='_blank'>在线工"
"意: 如果同时设置了定期执行和周期执行,优先使用定期执行" "具</a> <br>注意: 如果同时设置了定期执行和周期执行,优先使用定期执行"
#: xpack/plugins/change_auth_plan/meta.py:9 #: xpack/plugins/change_auth_plan/meta.py:9
#: xpack/plugins/change_auth_plan/models.py:110 #: xpack/plugins/change_auth_plan/models.py:110
#: xpack/plugins/change_auth_plan/models.py:245 #: xpack/plugins/change_auth_plan/models.py:252
#: xpack/plugins/change_auth_plan/views.py:31 #: xpack/plugins/change_auth_plan/views.py:31
#: xpack/plugins/change_auth_plan/views.py:47 #: xpack/plugins/change_auth_plan/views.py:47
#: xpack/plugins/change_auth_plan/views.py:68 #: xpack/plugins/change_auth_plan/views.py:68
@ -4818,7 +4839,7 @@ msgid "Regularly perform"
msgstr "定期执行" msgstr "定期执行"
#: xpack/plugins/change_auth_plan/models.py:83 #: xpack/plugins/change_auth_plan/models.py:83
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:45 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:51
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:69 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:69
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:57 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:57
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:16 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:16
@ -4830,34 +4851,35 @@ msgstr "密码策略"
msgid "Password rules" msgid "Password rules"
msgstr "密码规则" msgstr "密码规则"
#: xpack/plugins/change_auth_plan/models.py:249 #: xpack/plugins/change_auth_plan/models.py:209
msgid "For security, do not change root user's password"
msgstr "为了安全禁止更改root用户的密码"
#: xpack/plugins/change_auth_plan/models.py:212
msgid "Assets is empty, please add the asset"
msgstr "资产为空,请添加资产"
#: xpack/plugins/change_auth_plan/models.py:256
msgid "Change auth plan snapshot" msgid "Change auth plan snapshot"
msgstr "改密计划快照" msgstr "改密计划快照"
#: xpack/plugins/change_auth_plan/models.py:264 #: xpack/plugins/change_auth_plan/models.py:271
#: xpack/plugins/change_auth_plan/models.py:415 #: xpack/plugins/change_auth_plan/models.py:422
msgid "Change auth plan execution" msgid "Change auth plan execution"
msgstr "改密计划执行" msgstr "改密计划执行"
#: xpack/plugins/change_auth_plan/models.py:424 #: xpack/plugins/change_auth_plan/models.py:431
msgid "Change auth plan execution subtask" msgid "Change auth plan execution subtask"
msgstr "改密计划执行子任务" msgstr "改密计划执行子任务"
#: xpack/plugins/change_auth_plan/models.py:442 #: xpack/plugins/change_auth_plan/models.py:449
msgid "Authentication failed" msgid "Authentication failed"
msgstr "认证失败" msgstr "认证失败"
#: xpack/plugins/change_auth_plan/models.py:444 #: xpack/plugins/change_auth_plan/models.py:451
msgid "Connection timeout" msgid "Connection timeout"
msgstr "连接超时" msgstr "连接超时"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:17
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:20
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:17
#: xpack/plugins/change_auth_plan/views.py:83
msgid "Plan detail"
msgstr "计划详情"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:23 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:23
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:26 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:26
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:23 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:23
@ -4873,13 +4895,19 @@ msgstr "添加资产"
msgid "Add node to this plan" msgid "Add node to this plan"
msgstr "添加节点" msgstr "添加节点"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:12
msgid ""
"When the user password on the asset is changed, the action is performed "
"using the admin user associated with the asset"
msgstr "更改资产上的用户密码时,将会使用与该资产关联的管理用户进行操作"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:76 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:76
msgid "Length" msgid "Length"
msgstr "长度" msgstr "长度"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:134 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:134
msgid "Execute plan" msgid "Run plan manually"
msgstr "执行计划" msgstr "手动执行计划"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:179 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:179
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:101 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:101
@ -4915,10 +4943,6 @@ msgstr "计划列表"
msgid "Update plan" msgid "Update plan"
msgstr "更新计划" msgstr "更新计划"
#: xpack/plugins/change_auth_plan/views.py:110
msgid "plan asset list"
msgstr "计划资产列表"
#: xpack/plugins/change_auth_plan/views.py:140 #: xpack/plugins/change_auth_plan/views.py:140
msgid "Plan execution task list" msgid "Plan execution task list"
msgstr "执行任务列表" msgstr "执行任务列表"

View File

@ -4,6 +4,7 @@ import subprocess
from django.conf import settings from django.conf import settings
from celery import shared_task, subtask from celery import shared_task, subtask
from celery.exceptions import SoftTimeLimitExceeded
from django.utils import timezone from django.utils import timezone
from common.utils import get_logger, get_object_or_none from common.utils import get_logger, get_object_or_none
@ -38,11 +39,14 @@ def run_ansible_task(tid, callback=None, **kwargs):
logger.error("No task found") logger.error("No task found")
@shared_task @shared_task(soft_time_limit=60)
def run_command_execution(cid, **kwargs): def run_command_execution(cid, **kwargs):
execution = get_object_or_none(CommandExecution, id=cid) execution = get_object_or_none(CommandExecution, id=cid)
if execution: if execution:
try:
execution.run() execution.run()
except SoftTimeLimitExceeded:
print("HLLL")
else: else:
logger.error("Not found the execution id: {}".format(cid)) logger.error("Not found the execution id: {}".format(cid))

View File

@ -5,17 +5,17 @@
{% block custom_head_css_js %} {% block custom_head_css_js %}
<link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet"> <link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
<link rel="stylesheet" href="{% static 'js/plugins/xterm/xterm.css' %}" />
<link href="{% static 'css/plugins/codemirror/codemirror.css' %}" rel="stylesheet">
<link href="{% static 'css/plugins/codemirror/ambiance.css' %}" rel="stylesheet">
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script> <script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.exhide.min.js' %}"></script> <script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.exhide.min.js' %}"></script>
<script src="{% static 'js/jquery.form.min.js' %}"></script> <script src="{% static 'js/jquery.form.min.js' %}"></script>
<script src="{% static 'js/plugins/xterm/xterm.js' %}"></script> <script src="{% static 'js/plugins/xterm/xterm.js' %}"></script>
<link rel="stylesheet" href="{% static 'js/plugins/xterm/xterm.css' %}" />
<script src="{% static 'js/plugins/xterm/addons/fit/fit.js' %}"></script> <script src="{% static 'js/plugins/xterm/addons/fit/fit.js' %}"></script>
<script src="{% static 'js/plugins/codemirror/codemirror.js' %}"></script> <script src="{% static 'js/plugins/codemirror/codemirror.js' %}"></script>
<script src="{% static 'js/plugins/codemirror/mode/shell/shell.js' %}"></script> <script src="{% static 'js/plugins/codemirror/mode/shell/shell.js' %}"></script>
<link href="{% static 'css/plugins/codemirror/codemirror.css' %}" rel="stylesheet">
<link href="{% static 'css/plugins/codemirror/ambiance.css' %}" rel="stylesheet">
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script> <script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
<style type="text/css"> <style type="text/css">
.xterm .xterm-screen canvas { .xterm .xterm-screen canvas {
@ -82,6 +82,7 @@
<script> <script>
var zTree, show = 0; var zTree, show = 0;
var systemUserId = null; var systemUserId = null;
var treeUrl = "{% url 'api-perms:my-nodes-assets-as-tree' %}?cache_policy=1";
function initTree() { function initTree() {
var setting = { var setting = {
@ -110,14 +111,17 @@ function initTree() {
onCheck: onCheck onCheck: onCheck
} }
}; };
var url = "{% url 'api-perms:my-nodes-assets-as-tree' %}?cache_policy=1";
if (systemUserId) { if (systemUserId) {
url += '&system_user=' + systemUserId url = treeUrl + '&system_user=' + systemUserId
} }
$.get(url, function(data, status){ $.get(url, function(data, status){
$.fn.zTree.init($("#assetTree"), setting, data); $.fn.zTree.init($("#assetTree"), setting, data);
zTree = $.fn.zTree.getZTreeObj("assetTree"); zTree = $.fn.zTree.getZTreeObj("assetTree");
rootNodeAddDom(zTree, function () {
treeUrl = treeUrl.replace('cache_policy=1', 'cache_policy=2');
initTree();
});
}); });
} }
@ -250,7 +254,8 @@ function execute() {
method: 'POST', method: 'POST',
flash_message: false, flash_message: false,
success: function (resp) { success: function (resp) {
term.write("{% trans 'Pending' %}" + "...\r\n"); var msg = "{% trans 'Pending' %}";
term.write(msg + "...\r\n");
log_url = resp.log_url; log_url = resp.log_url;
int = setInterval(function () { int = setInterval(function () {
writeExecutionOutput() writeExecutionOutput()

View File

@ -5,6 +5,7 @@ from django.utils.translation import ugettext as _
from django.conf import settings from django.conf import settings
from django.views.generic import ListView, TemplateView from django.views.generic import ListView, TemplateView
from common.permissions import AdminUserRequiredMixin, LoginRequiredMixin
from common.mixins import DatetimeSearchMixin from common.mixins import DatetimeSearchMixin
from ..models import CommandExecution from ..models import CommandExecution
from ..forms import CommandExecutionForm from ..forms import CommandExecutionForm
@ -15,7 +16,7 @@ __all__ = [
] ]
class CommandExecutionListView(DatetimeSearchMixin, ListView): class CommandExecutionListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):
template_name = 'ops/command_execution_list.html' template_name = 'ops/command_execution_list.html'
model = CommandExecution model = CommandExecution
paginate_by = settings.DISPLAY_PER_PAGE paginate_by = settings.DISPLAY_PER_PAGE
@ -50,7 +51,7 @@ class CommandExecutionListView(DatetimeSearchMixin, ListView):
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
class CommandExecutionStartView(TemplateView): class CommandExecutionStartView(LoginRequiredMixin, TemplateView):
template_name = 'ops/command_execution_create.html' template_name = 'ops/command_execution_create.html'
form_class = CommandExecutionForm form_class = CommandExecutionForm

View File

@ -108,7 +108,7 @@ class UserGroupGrantedNodesWithAssetsAsTreeApi(ListAPIView):
group = get_object_or_404(UserGroup, id=user_group_id) group = get_object_or_404(UserGroup, id=user_group_id)
util = AssetPermissionUtil(group) util = AssetPermissionUtil(group)
if self.system_user_id: if self.system_user_id:
util.filter_permission_with_system_user(system_user=self.system_user_id) util.filter_permissions(system_users=self.system_user_id)
nodes = util.get_nodes_with_assets() nodes = util.get_nodes_with_assets()
for node, assets in nodes.items(): for node, assets in nodes.items():
data = parse_node_to_tree_node(node) data = parse_node_to_tree_node(node)

View File

@ -35,10 +35,11 @@ __all__ = [
] ]
class UserPermissionMixin: class UserPermissionCacheMixin:
cache_policy = '0' cache_policy = '0'
RESP_CACHE_KEY = '_PERMISSION_RESPONSE_CACHE_{}' RESP_CACHE_KEY = '_PERMISSION_RESPONSE_CACHE_{}'
CACHE_TIME = settings.ASSETS_PERM_CACHE_TIME CACHE_TIME = settings.ASSETS_PERM_CACHE_TIME
_object = None
@staticmethod @staticmethod
def change_org_if_need(request, kwargs): def change_org_if_need(request, kwargs):
@ -51,56 +52,82 @@ class UserPermissionMixin:
def get_object(self): def get_object(self):
return None return None
# 内部使用可控制缓存
def _get_object(self):
if not self._object:
self._object = self.get_object()
return self._object
def get_object_id(self):
obj = self._get_object()
if obj:
return str(obj.id)
return None
def get_request_md5(self):
full_path = self.request.get_full_path()
return md5(full_path.encode()).hexdigest()
def get_meta_cache_id(self):
obj = self._get_object()
util = AssetPermissionUtil(obj, cache_policy=self.cache_policy)
meta_cache_id = util.cache_meta.get('id')
return meta_cache_id
def get_response_cache_id(self):
obj_id = self.get_object_id()
request_md5 = self.get_request_md5()
meta_cache_id = self.get_meta_cache_id()
resp_cache_id = '{}_{}_{}'.format(obj_id, request_md5, meta_cache_id)
return resp_cache_id
def get_response_from_cache(self):
resp_cache_id = self.get_response_cache_id()
# 没有数据缓冲
meta_cache_id = self.get_meta_cache_id()
if not meta_cache_id:
return None
# 从响应缓冲里获取响应
key = self.RESP_CACHE_KEY.format(resp_cache_id)
data = cache.get(key)
if not data:
return None
logger.debug("Get user permission from cache: {}".format(self.get_object()))
response = Response(data)
return response
def expire_response_cache(self):
obj_id = self.get_object_id()
expire_cache_id = '{}_{}'.format(obj_id, '*')
key = self.RESP_CACHE_KEY.format(expire_cache_id)
cache.delete_pattern(key)
def set_response_to_cache(self, response):
resp_cache_id = self.get_response_cache_id()
key = self.RESP_CACHE_KEY.format(resp_cache_id)
cache.set(key, response.data, self.CACHE_TIME)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.change_org_if_need(request, kwargs) self.change_org_if_need(request, kwargs)
self.cache_policy = request.GET.get('cache_policy', '0') self.cache_policy = request.GET.get('cache_policy', '0')
obj = self.get_object() obj = self._get_object()
if obj is None: if obj is None:
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
request_path_md5 = md5(request.get_full_path().encode()).hexdigest()
obj_id = str(obj.id) if AssetPermissionUtil.is_not_using_cache(self.cache_policy):
expire_cache_key = '{}_{}'.format(obj_id, '*')
if self.CACHE_TIME <= 0 or \
self.cache_policy in AssetPermissionUtil.CACHE_POLICY_MAP[0]:
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
elif self.cache_policy in AssetPermissionUtil.CACHE_POLICY_MAP[2]: elif AssetPermissionUtil.is_refresh_cache(self.cache_policy):
self.expire_cache_response(expire_cache_key) self.expire_response_cache()
util = AssetPermissionUtil(obj, cache_policy=self.cache_policy) resp = self.get_response_from_cache()
meta_cache_id = util.cache_meta.get('id') if not resp:
cache_id = '{}_{}_{}'.format(obj_id, request_path_md5, meta_cache_id) resp = super().get(request, *args, **kwargs)
# 没有数据缓冲 self.set_response_to_cache(resp)
if not meta_cache_id: return resp
response = super().get(request, *args, **kwargs)
self.set_cache_response(cache_id, response)
return response
# 从响应缓冲里获取响应
response = self.get_cache_response(cache_id)
if not response:
response = super().get(request, *args, **kwargs)
self.set_cache_response(cache_id, response)
return response
def get_cache_response(self, _id):
if not _id:
return None
key = self.RESP_CACHE_KEY.format(_id)
data = cache.get(key)
if not data:
return None
return Response(data)
def expire_cache_response(self, _id):
key = self.RESP_CACHE_KEY.format(_id)
cache.delete(key)
def set_cache_response(self, _id, response):
key = self.RESP_CACHE_KEY.format(_id)
cache.set(key, response.data, self.CACHE_TIME)
class UserGrantedAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIView): class UserGrantedAssetsApi(UserPermissionCacheMixin, AssetsFilterMixin, ListAPIView):
""" """
用户授权的所有资产 用户授权的所有资产
""" """
@ -110,7 +137,6 @@ class UserGrantedAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIView):
def get_object(self): def get_object(self):
user_id = self.kwargs.get('pk', '') user_id = self.kwargs.get('pk', '')
if user_id: if user_id:
user = get_object_or_404(User, id=user_id) user = get_object_or_404(User, id=user_id)
else: else:
@ -134,7 +160,7 @@ class UserGrantedAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIView):
return super().get_permissions() return super().get_permissions()
class UserGrantedNodesApi(UserPermissionMixin, ListAPIView): class UserGrantedNodesApi(UserPermissionCacheMixin, ListAPIView):
""" """
查询用户授权的所有节点的API, 如果是超级用户或者是 app切换到root org 查询用户授权的所有节点的API, 如果是超级用户或者是 app切换到root org
""" """
@ -161,7 +187,7 @@ class UserGrantedNodesApi(UserPermissionMixin, ListAPIView):
return super().get_permissions() return super().get_permissions()
class UserGrantedNodesWithAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIView): class UserGrantedNodesWithAssetsApi(UserPermissionCacheMixin, AssetsFilterMixin, ListAPIView):
""" """
用户授权的节点并带着节点下资产的api 用户授权的节点并带着节点下资产的api
""" """
@ -202,17 +228,12 @@ class UserGrantedNodesWithAssetsApi(UserPermissionMixin, AssetsFilterMixin, List
return super().get_permissions() return super().get_permissions()
class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionMixin, ListAPIView): class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionCacheMixin, ListAPIView):
serializer_class = TreeNodeSerializer serializer_class = TreeNodeSerializer
permission_classes = (IsOrgAdminOrAppUser,) permission_classes = (IsOrgAdminOrAppUser,)
show_assets = True show_assets = True
system_user_id = None system_user_id = None
def get(self, request, *args, **kwargs):
self.show_assets = request.query_params.get('show_assets', '1') == '1'
self.system_user_id = request.query_params.get('system_user')
return super().get(request, *args, **kwargs)
def get_permissions(self): def get_permissions(self):
if self.kwargs.get('pk') is None: if self.kwargs.get('pk') is None:
self.permission_classes = (IsValidUser,) self.permission_classes = (IsValidUser,)
@ -226,13 +247,19 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionMixin, ListAPIView):
user = get_object_or_404(User, id=user_id) user = get_object_or_404(User, id=user_id)
return user return user
def list(self, request, *args, **kwargs):
resp = super().list(request, *args, **kwargs)
return resp
def get_queryset(self): def get_queryset(self):
queryset = [] queryset = []
self.show_assets = self.request.query_params.get('show_assets', '1') == '1'
self.system_user_id = self.request.query_params.get('system_user')
user = self.get_object() user = self.get_object()
util = AssetPermissionUtil(user, cache_policy=self.cache_policy) util = AssetPermissionUtil(user, cache_policy=self.cache_policy)
if self.system_user_id: if self.system_user_id:
util.filter_permission_with_system_user( util.filter_permissions(
system_user=self.system_user_id system_users=self.system_user_id
) )
nodes = util.get_nodes_with_assets() nodes = util.get_nodes_with_assets()
for node, assets in nodes.items(): for node, assets in nodes.items():
@ -247,7 +274,7 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionMixin, ListAPIView):
return queryset return queryset
class UserGrantedNodeAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIView): class UserGrantedNodeAssetsApi(UserPermissionCacheMixin, AssetsFilterMixin, ListAPIView):
""" """
查询用户授权的节点下的资产的api, 与上面api不同的是只返回某个节点下的资产 查询用户授权的节点下的资产的api, 与上面api不同的是只返回某个节点下的资产
""" """
@ -283,7 +310,7 @@ class UserGrantedNodeAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIVi
return super().get_permissions() return super().get_permissions()
class UserGrantedNodeChildrenApi(UserPermissionMixin, ListAPIView): class UserGrantedNodeChildrenApi(UserPermissionCacheMixin, ListAPIView):
""" """
获取用户自己授权节点下子节点的api 获取用户自己授权节点下子节点的api
""" """
@ -369,7 +396,7 @@ class UserGrantedNodeChildrenApi(UserPermissionMixin, ListAPIView):
return self.get_children_queryset() return self.get_children_queryset()
class ValidateUserAssetPermissionApi(UserPermissionMixin, APIView): class ValidateUserAssetPermissionApi(UserPermissionCacheMixin, APIView):
permission_classes = (IsOrgAdminOrAppUser,) permission_classes = (IsOrgAdminOrAppUser,)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):

View File

@ -3,6 +3,9 @@
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
import uuid import uuid
from collections import defaultdict from collections import defaultdict
import json
from hashlib import md5
from django.utils import timezone from django.utils import timezone
from django.db.models import Q from django.db.models import Q
from django.core.cache import cache from django.core.cache import cache
@ -101,8 +104,8 @@ class AssetPermissionUtil:
"SystemUser": get_node_permissions, "SystemUser": get_node_permissions,
} }
CACHE_KEY = '_ASSET_PERM_CACHE_{}_{}' CACHE_KEY_PREFIX = '_ASSET_PERM_CACHE_'
CACHE_META_KEY = '_ASSET_PERM_META_KEY_{}' CACHE_META_KEY_PREFIX = '_ASSET_PERM_META_KEY_'
CACHE_TIME = settings.ASSETS_PERM_CACHE_TIME CACHE_TIME = settings.ASSETS_PERM_CACHE_TIME
CACHE_POLICY_MAP = (('0', 'never'), ('1', 'using'), ('2', 'refresh')) CACHE_POLICY_MAP = (('0', 'never'), ('1', 'using'), ('2', 'refresh'))
@ -110,11 +113,31 @@ class AssetPermissionUtil:
self.object = obj self.object = obj
self.obj_id = str(obj.id) self.obj_id = str(obj.id)
self._permissions = None self._permissions = None
self._permissions_id = None # 标记_permission的唯一值
self._assets = None self._assets = None
self._filter_id = 'None' # 当通过filter更改 permission是标记
self.cache_policy = cache_policy self.cache_policy = cache_policy
self.node_key = self.CACHE_KEY.format(self.obj_id, 'NODES_WITH_ASSETS')
self.asset_key = self.CACHE_KEY.format(self.obj_id, 'ASSETS') @classmethod
self.system_key = self.CACHE_KEY.format(self.obj_id, 'SYSTEM_USER') def is_not_using_cache(cls, cache_policy):
return cls.CACHE_TIME == 0 or cache_policy in cls.CACHE_POLICY_MAP[0]
@classmethod
def is_using_cache(cls, cache_policy):
return cls.CACHE_TIME != 0 and cache_policy in cls.CACHE_POLICY_MAP[1]
@classmethod
def is_refresh_cache(cls, cache_policy):
return cache_policy in cls.CACHE_POLICY_MAP[2]
def _is_not_using_cache(self):
return self.is_not_using_cache(self.cache_policy)
def _is_using_cache(self):
return self.is_using_cache(self.cache_policy)
def _is_refresh_cache(self):
return self.is_refresh_cache(self.cache_policy)
@property @property
def permissions(self): def permissions(self):
@ -126,8 +149,10 @@ class AssetPermissionUtil:
self._permissions = permissions self._permissions = permissions
return permissions return permissions
def filter_permission_with_system_user(self, system_user): def filter_permissions(self, **filters):
self._permissions = self.permissions.filter(system_users=system_user) filters_json = json.dumps(filters, sort_keys=True)
self._permissions = self.permissions.filter(**filters)
self._filter_id = md5(filters_json.encode()).hexdigest()
def get_nodes_direct(self): def get_nodes_direct(self):
""" """
@ -169,6 +194,25 @@ class AssetPermissionUtil:
self._assets = assets self._assets = assets
return self._assets return self._assets
def get_cache_key(self, resource):
cache_key = self.CACHE_KEY_PREFIX + '{obj_id}_{filter_id}_{resource}'
return cache_key.format(
obj_id=self.obj_id, filter_id=self._filter_id,
resource=resource
)
@property
def node_key(self):
return self.get_cache_key('NODES_WITH_ASSETS')
@property
def asset_key(self):
return self.get_cache_key('ASSETS')
@property
def system_key(self):
return self.get_cache_key('SYSTEM_USER')
def get_assets_from_cache(self): def get_assets_from_cache(self):
cached = cache.get(self.asset_key) cached = cache.get(self.asset_key)
if not cached: if not cached:
@ -177,9 +221,9 @@ class AssetPermissionUtil:
return cached return cached
def get_assets(self): def get_assets(self):
if self.CACHE_TIME <= 0 or self.cache_policy in self.CACHE_POLICY_MAP[1]: if self._is_not_using_cache():
return self.get_assets_from_cache() return self.get_assets_from_cache()
elif self.cache_policy in self.CACHE_POLICY_MAP[2]: elif self._is_refresh_cache():
self.expire_cache() self.expire_cache()
return self.get_assets_from_cache() return self.get_assets_from_cache()
else: else:
@ -206,9 +250,9 @@ class AssetPermissionUtil:
return cached return cached
def get_nodes_with_assets(self): def get_nodes_with_assets(self):
if self.CACHE_TIME <= 0 or self.cache_policy in self.CACHE_POLICY_MAP[1]: if self._is_using_cache():
return self.get_nodes_with_assets_from_cache() return self.get_nodes_with_assets_from_cache()
elif self.cache_policy in self.CACHE_POLICY_MAP[2]: elif self._is_refresh_cache():
self.expire_cache() self.expire_cache()
return self.get_nodes_with_assets_from_cache() return self.get_nodes_with_assets_from_cache()
else: else:
@ -229,21 +273,28 @@ class AssetPermissionUtil:
return cached return cached
def get_system_users(self): def get_system_users(self):
if self.CACHE_TIME <= 0 or self.cache_policy in self.CACHE_POLICY_MAP[1]: if self._is_using_cache():
return self.get_system_user_from_cache() return self.get_system_user_from_cache()
elif self.cache_policy in self.CACHE_POLICY_MAP[2]: elif self._is_refresh_cache():
self.expire_cache() self.expire_cache()
return self.get_system_user_from_cache() return self.get_system_user_from_cache()
else: else:
return self.get_system_user_without_cache() return self.get_system_user_without_cache()
def get_meta_cache_key(self):
cache_key = self.CACHE_META_KEY_PREFIX + '{obj_id}_{filter_id}'
key = cache_key.format(
obj_id=str(self.object.id), filter_id=self._filter_id
)
return key
@property @property
def cache_meta(self): def cache_meta(self):
key = self.CACHE_META_KEY.format(str(self.object.id)) key = self.get_meta_cache_key()
return cache.get(key) or {} return cache.get(key) or {}
def set_cache_meta(self): def set_meta_to_cache(self):
key = self.CACHE_META_KEY.format(str(self.object.id)) key = self.get_meta_cache_key()
meta = { meta = {
'id': str(uuid.uuid4()), 'id': str(uuid.uuid4()),
'datetime': timezone.now(), 'datetime': timezone.now(),
@ -252,8 +303,9 @@ class AssetPermissionUtil:
cache.set(key, meta, self.CACHE_TIME) cache.set(key, meta, self.CACHE_TIME)
def expire_cache_meta(self): def expire_cache_meta(self):
key = self.CACHE_META_KEY.format(str(self.object.id)) cache_key = self.CACHE_META_KEY_PREFIX + '{obj_id}_*'
cache.delete(key) key = cache_key.format(obj_id=str(self.object.id))
cache.delete_pattern(key)
def update_cache(self): def update_cache(self):
assets = self.get_assets_without_cache() assets = self.get_assets_without_cache()
@ -262,7 +314,7 @@ class AssetPermissionUtil:
cache.set(self.asset_key, assets, self.CACHE_TIME) cache.set(self.asset_key, assets, self.CACHE_TIME)
cache.set(self.node_key, nodes, self.CACHE_TIME) cache.set(self.node_key, nodes, self.CACHE_TIME)
cache.set(self.system_key, system_users, self.CACHE_TIME) cache.set(self.system_key, system_users, self.CACHE_TIME)
self.set_cache_meta() self.set_meta_to_cache()
def expire_cache(self): def expire_cache(self):
""" """
@ -270,17 +322,19 @@ class AssetPermissionUtil:
缓存以免造成不统一的情况 缓存以免造成不统一的情况
:return: :return:
""" """
key = self.CACHE_KEY.format(str(self.object.id), '*') cache_key = self.CACHE_KEY_PREFIX + '{obj_id}_*'
key = cache_key.format(obj_id='*')
cache.delete_pattern(key) cache.delete_pattern(key)
self.expire_cache_meta() self.expire_cache_meta()
def expire_all_cache_meta(self): @classmethod
key = self.CACHE_META_KEY.format('*') def expire_all_cache_meta(cls):
key = cls.CACHE_META_KEY_PREFIX + '*'
cache.delete_pattern(key) cache.delete_pattern(key)
@classmethod @classmethod
def expire_all_cache(cls): def expire_all_cache(cls):
key = cls.CACHE_KEY.format('*', '*') key = cls.CACHE_KEY_PREFIX + '*'
cache.delete_pattern(key) cache.delete_pattern(key)