diff --git a/apps/assets/migrations/0043_auto_20191114_1111.py b/apps/assets/migrations/0043_auto_20191114_1111.py new file mode 100644 index 000000000..a07dee6bb --- /dev/null +++ b/apps/assets/migrations/0043_auto_20191114_1111.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.5 on 2019-11-14 03:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0042_favoriteasset'), + ] + + operations = [ + migrations.AddField( + model_name='gathereduser', + name='date_last_login', + field=models.DateTimeField(null=True, verbose_name='Date last login'), + ), + migrations.AddField( + model_name='gathereduser', + name='ip_last_login', + field=models.CharField(default='', max_length=39, verbose_name='IP last login'), + ), + ] diff --git a/apps/assets/models/gathered_user.py b/apps/assets/models/gathered_user.py index 282f9293a..d00021c56 100644 --- a/apps/assets/models/gathered_user.py +++ b/apps/assets/models/gathered_user.py @@ -12,13 +12,12 @@ __all__ = ['GatheredUser'] class GatheredUser(OrgModelMixin): id = models.UUIDField(default=uuid.uuid4, primary_key=True) asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_("Asset")) - username = models.CharField(max_length=32, blank=True, db_index=True, - verbose_name=_('Username')) + username = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=_('Username')) present = models.BooleanField(default=True, verbose_name=_("Present")) - date_created = models.DateTimeField(auto_now_add=True, - verbose_name=_("Date created")) - date_updated = models.DateTimeField(auto_now=True, - verbose_name=_("Date updated")) + date_last_login = models.DateTimeField(null=True, verbose_name=_("Date last login")) + ip_last_login = models.CharField(max_length=39, default='', verbose_name=_("IP last login")) + date_created = models.DateTimeField(auto_now_add=True, verbose_name=_("Date created")) + date_updated = models.DateTimeField(auto_now=True, verbose_name=_("Date updated")) @property def hostname(self): diff --git a/apps/assets/serializers/gathered_user.py b/apps/assets/serializers/gathered_user.py index 956c19c6b..c055e25bd 100644 --- a/apps/assets/serializers/gathered_user.py +++ b/apps/assets/serializers/gathered_user.py @@ -12,6 +12,7 @@ class GatheredUserSerializer(OrgResourceModelSerializerMixin): model = GatheredUser fields = [ 'id', 'asset', 'hostname', 'ip', 'username', + 'date_last_login', 'ip_last_login', 'present', 'date_created', 'date_updated' ] read_only_fields = fields diff --git a/apps/assets/tasks/const.py b/apps/assets/tasks/const.py index 6810a00bc..5b7db13cd 100644 --- a/apps/assets/tasks/const.py +++ b/apps/assets/tasks/const.py @@ -7,10 +7,7 @@ from django.utils.translation import ugettext_lazy as _ ENV_PERIOD_TASK = os.environ.get("PERIOD_TASK", "on") == 'on' -ENV_PERIOD_TASK_ENABLED = os.environ.get("PERIOD_TASK_ENABLED", "on") == "on" -PERIOD_TASK_ENABLED = settings.CONFIG.PERIOD_TASK_ENABLE \ - and ENV_PERIOD_TASK \ - and ENV_PERIOD_TASK_ENABLED +PERIOD_TASK_ENABLED = settings.PERIOD_TASK_ENABLED and ENV_PERIOD_TASK UPDATE_ASSETS_HARDWARE_TASKS = [ { @@ -97,6 +94,13 @@ GATHER_ASSET_USERS_TASKS = [ "args": "database=passwd" }, }, + { + "name": "get last login", + "action": { + "module": "shell", + "args": "users=$(getent passwd | grep -v 'nologin' | grep -v 'shudown' | awk -F: '{ print $1 }');for i in $users;do last -F $i -1 | head -1 | grep -v '^$' | awk '{ print $1\"@\"$3\"@\"$5,$6,$7,$8 }';done" + } + } ] GATHER_ASSET_USERS_TASKS_WINDOWS = [ diff --git a/apps/assets/tasks/gather_asset_users.py b/apps/assets/tasks/gather_asset_users.py index efeecc25e..7dfe0fb01 100644 --- a/apps/assets/tasks/gather_asset_users.py +++ b/apps/assets/tasks/gather_asset_users.py @@ -2,9 +2,10 @@ import re from collections import defaultdict -from celery import shared_task +from celery import shared_task from django.utils.translation import ugettext as _ +from django.utils import timezone from orgs.utils import tmp_to_org from common.utils import get_logger @@ -19,19 +20,25 @@ ignore_login_shell = re.compile(r'nologin$|sync$|shutdown$|halt$') def parse_linux_result_to_users(result): - task_result = {} - for task_name, raw in result.items(): - res = raw.get('ansible_facts', {}).get('getent_passwd') - if res: - task_result = res - break - if not task_result or not isinstance(task_result, dict): - return [] - users = [] - for username, attr in task_result.items(): + users = defaultdict(dict) + users_result = result.get('gather host users', {})\ + .get('ansible_facts', {})\ + .get('getent_passwd') + if not isinstance(users_result, dict): + users_result = {} + for username, attr in users_result.items(): if ignore_login_shell.search(attr[-1]): continue - users.append(username) + users[username] = {} + last_login_result = result.get('get last login', {}).get('stdout_lines', []) + for line in last_login_result: + data = line.split('@') + if len(data) != 3: + continue + username, ip, dt = data + dt += ' +0800' + date = timezone.datetime.strptime(dt, '%b %d %H:%M:%S %Y %z') + users[username] = {"ip": ip, "date": date} return users @@ -45,7 +52,7 @@ def parse_windows_result_to_users(result): if not task_result: return [] - users = [] + users = {} for i in range(4): task_result.pop(0) @@ -55,7 +62,7 @@ def parse_windows_result_to_users(result): for line in task_result: user = space.split(line) if user[0]: - users.append(user[0]) + users[user[0]] = {} return users @@ -82,8 +89,12 @@ def add_asset_users(assets, results): with tmp_to_org(asset.org_id): GatheredUser.objects.filter(asset=asset, present=True)\ .update(present=False) - for username in users: + for username, data in users.items(): defaults = {'asset': asset, 'username': username, 'present': True} + if data.get("ip"): + defaults["ip_last_login"] = data["ip"] + if data.get("date"): + defaults["date_last_login"] = data["date"] GatheredUser.objects.update_or_create( defaults=defaults, asset=asset, username=username, ) diff --git a/apps/assets/templates/assets/_node_tree.html b/apps/assets/templates/assets/_node_tree.html index 803c29c13..fc7f4ae06 100644 --- a/apps/assets/templates/assets/_node_tree.html +++ b/apps/assets/templates/assets/_node_tree.html @@ -303,9 +303,24 @@ function defaultCallback(action) { return logging } +function toggle() { + if (show === 0) { + $("#split-left").hide(500, function () { + $("#split-right").attr("class", "col-lg-12"); + $("#toggle-icon").attr("class", "fa fa-angle-right fa-x"); + show = 1; + }); + } else { + $("#split-right").attr("class", "col-lg-9"); + $("#toggle-icon").attr("class", "fa fa-angle-left fa-x"); + $("#split-left").show(500); + show = 0; + } +} + $(document).ready(function () { - $('.treebox').css('height', window.innerHeight - 180); + $('.treebox').css('height', window.innerHeight - 60); }) .on('click', '.btn-show-current-asset', function(){ hideRMenu(); @@ -320,6 +335,9 @@ $(document).ready(function () { $('#show_current_asset').css('display', 'inline-block'); setCookie('show_current_asset', ''); location.reload(); +}).on('click', '.tree-toggle-btn', function (e) { + e.preventDefault(); + toggle(); }) diff --git a/apps/assets/templates/assets/asset_list.html b/apps/assets/templates/assets/asset_list.html index fcc17c87d..c17b50b1c 100644 --- a/apps/assets/templates/assets/asset_list.html +++ b/apps/assets/templates/assets/asset_list.html @@ -48,12 +48,12 @@ {% block content %}
-
+
{% include 'assets/_node_tree.html' %}
-
-
+
+
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index b32d53610..d5225f406 100644 Binary files a/apps/locale/zh/LC_MESSAGES/django.mo and b/apps/locale/zh/LC_MESSAGES/django.mo differ diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 6e7cd300b..2e7d867c4 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Jumpserver 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-11-12 14:10+0800\n" +"POT-Creation-Date: 2019-11-14 11:36+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: ibuler \n" "Language-Team: Jumpserver team\n" @@ -96,7 +96,7 @@ msgstr "运行参数" #: terminal/templates/terminal/session_list.html:28 #: terminal/templates/terminal/session_list.html:72 #: xpack/plugins/change_auth_plan/forms.py:73 -#: xpack/plugins/change_auth_plan/models.py:419 +#: xpack/plugins/change_auth_plan/models.py:412 #: 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_subtask_list.html:13 @@ -152,7 +152,7 @@ msgstr "资产" #: users/templates/users/user_profile.html:51 #: users/templates/users/user_pubkey_update.html:57 #: xpack/plugins/change_auth_plan/forms.py:56 -#: xpack/plugins/change_auth_plan/models.py:64 +#: xpack/plugins/change_auth_plan/models.py:63 #: 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/cloud/models.py:59 xpack/plugins/cloud/models.py:144 @@ -199,7 +199,7 @@ msgstr "参数" #: perms/templates/perms/remote_app_permission_detail.html:90 #: users/models/user.py:451 users/serializers/group.py:32 #: users/templates/users/user_detail.html:112 -#: xpack/plugins/change_auth_plan/models.py:109 +#: xpack/plugins/change_auth_plan/models.py:108 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:113 #: xpack/plugins/cloud/models.py:80 xpack/plugins/cloud/models.py:179 #: xpack/plugins/gathered_user/models.py:46 @@ -264,7 +264,7 @@ msgstr "创建日期" #: users/templates/users/user_group_detail.html:67 #: users/templates/users/user_group_list.html:37 #: users/templates/users/user_profile.html:138 -#: xpack/plugins/change_auth_plan/models.py:105 +#: xpack/plugins/change_auth_plan/models.py:104 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:117 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:19 #: xpack/plugins/cloud/models.py:77 xpack/plugins/cloud/models.py:173 @@ -607,7 +607,7 @@ msgstr "端口" #: assets/templates/assets/asset_detail.html:196 #: assets/templates/assets/system_user_assets.html:83 #: perms/models/asset_permission.py:81 -#: xpack/plugins/change_auth_plan/models.py:75 +#: xpack/plugins/change_auth_plan/models.py:74 #: xpack/plugins/gathered_user/models.py:31 #: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:17 msgid "Nodes" @@ -693,7 +693,7 @@ msgid "SSH gateway support proxy SSH,RDP,VNC" msgstr "SSH网关,支持代理SSH,RDP和VNC" #: assets/forms/domain.py:78 assets/forms/user.py:76 assets/forms/user.py:96 -#: assets/models/base.py:29 assets/models/gathered_user.py:16 +#: assets/models/base.py:29 assets/models/gathered_user.py:15 #: assets/templates/assets/_asset_user_auth_update_modal.html:15 #: assets/templates/assets/_asset_user_auth_view_modal.html:21 #: assets/templates/assets/_asset_user_list.html:21 @@ -714,13 +714,13 @@ msgstr "SSH网关,支持代理SSH,RDP和VNC" #: users/templates/users/user_list.html:36 #: users/templates/users/user_profile.html:47 #: xpack/plugins/change_auth_plan/forms.py:58 -#: xpack/plugins/change_auth_plan/models.py:66 -#: xpack/plugins/change_auth_plan/models.py:415 +#: xpack/plugins/change_auth_plan/models.py:65 +#: xpack/plugins/change_auth_plan/models.py:408 #: 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 -#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:74 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:64 msgid "Username" msgstr "用户名" @@ -742,8 +742,8 @@ msgstr "密码或密钥密码" #: users/templates/users/user_profile_update.html:41 #: users/templates/users/user_pubkey_update.html:41 #: users/templates/users/user_update.html:20 -#: xpack/plugins/change_auth_plan/models.py:96 -#: xpack/plugins/change_auth_plan/models.py:264 +#: xpack/plugins/change_auth_plan/models.py:95 +#: xpack/plugins/change_auth_plan/models.py:263 msgid "Password" msgstr "密码" @@ -801,12 +801,12 @@ msgstr "使用逗号分隔多个命令,如: /bin/whoami,/sbin/ifconfig" #: perms/templates/perms/asset_permission_asset.html:58 settings/forms.py:144 #: users/templates/users/_granted_assets.html:31 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:54 -#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:73 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:63 msgid "IP" msgstr "IP" #: assets/models/asset.py:136 assets/serializers/asset_user.py:27 -#: assets/serializers/gathered_user.py:19 +#: assets/serializers/gathered_user.py:20 #: assets/templates/assets/_asset_list_modal.html:46 #: assets/templates/assets/_asset_user_auth_update_modal.html:9 #: assets/templates/assets/_asset_user_auth_view_modal.html:15 @@ -818,7 +818,7 @@ msgstr "IP" #: perms/templates/perms/asset_permission_list.html:73 settings/forms.py:143 #: users/templates/users/_granted_assets.html:30 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:53 -#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:72 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:62 msgid "Hostname" msgstr "主机名" @@ -937,21 +937,21 @@ msgstr "版本" msgid "AuthBook" msgstr "" -#: assets/models/base.py:31 xpack/plugins/change_auth_plan/models.py:100 -#: xpack/plugins/change_auth_plan/models.py:271 +#: assets/models/base.py:31 xpack/plugins/change_auth_plan/models.py:99 +#: xpack/plugins/change_auth_plan/models.py:270 msgid "SSH private key" msgstr "ssh密钥" -#: assets/models/base.py:32 xpack/plugins/change_auth_plan/models.py:103 -#: xpack/plugins/change_auth_plan/models.py:267 +#: assets/models/base.py:32 xpack/plugins/change_auth_plan/models.py:102 +#: xpack/plugins/change_auth_plan/models.py:266 msgid "SSH public key" msgstr "ssh公钥" -#: assets/models/base.py:35 assets/models/gathered_user.py:21 +#: assets/models/base.py:35 assets/models/gathered_user.py:20 #: assets/templates/assets/cmd_filter_detail.html:73 common/mixins/models.py:52 #: ops/models/adhoc.py:46 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:109 -#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:76 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:68 msgid "Date updated" msgstr "更新日期" @@ -1080,12 +1080,22 @@ msgstr "命令过滤规则" msgid "Gateway" msgstr "网关" -#: assets/models/gathered_user.py:17 -#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:75 +#: assets/models/gathered_user.py:16 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:67 msgid "Present" msgstr "存在" -#: assets/models/gathered_user.py:32 +#: assets/models/gathered_user.py:17 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:65 +msgid "Date last login" +msgstr "最后登录日期" + +#: assets/models/gathered_user.py:18 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:66 +msgid "IP last login" +msgstr "最后登录IP" + +#: assets/models/gathered_user.py:31 msgid "GatherUser" msgstr "收集用户" @@ -1188,7 +1198,7 @@ msgstr "手动登录" #: assets/views/label.py:27 assets/views/label.py:45 assets/views/label.py:73 #: assets/views/system_user.py:29 assets/views/system_user.py:46 #: assets/views/system_user.py:63 assets/views/system_user.py:79 -#: templates/_nav.html:39 xpack/plugins/change_auth_plan/models.py:71 +#: templates/_nav.html:39 xpack/plugins/change_auth_plan/models.py:70 msgid "Assets" msgstr "资产管理" @@ -1237,16 +1247,16 @@ msgstr "系统用户" msgid "%(value)s is not an even number" msgstr "%(value)s is not an even number" -#: assets/models/utils.py:43 assets/tasks/const.py:87 +#: assets/models/utils.py:43 assets/tasks/const.py:84 msgid "Unreachable" msgstr "不可达" -#: assets/models/utils.py:44 assets/tasks/const.py:88 +#: assets/models/utils.py:44 assets/tasks/const.py:85 #: assets/templates/assets/asset_list.html:99 msgid "Reachable" msgstr "可连接" -#: assets/models/utils.py:45 assets/tasks/const.py:89 audits/utils.py:30 +#: assets/models/utils.py:45 assets/tasks/const.py:86 audits/utils.py:30 #: xpack/plugins/license/models.py:78 msgid "Unknown" msgstr "未知" @@ -1333,7 +1343,7 @@ msgstr "测试资产可连接性: {}" #: assets/tasks/asset_user_connectivity.py:27 #: assets/tasks/push_system_user.py:130 -#: xpack/plugins/change_auth_plan/models.py:528 +#: xpack/plugins/change_auth_plan/models.py:521 msgid "The asset {} system platform {} does not support run Ansible tasks" msgstr "资产 {} 系统平台 {} 不支持运行 Ansible 任务" @@ -1353,7 +1363,7 @@ msgstr "更新资产硬件信息" msgid "Update asset hardware info: {}" msgstr "更新资产硬件信息: {}" -#: assets/tasks/gather_asset_users.py:96 +#: assets/tasks/gather_asset_users.py:107 msgid "Gather assets users" msgstr "收集资产上的用户" @@ -1706,7 +1716,7 @@ msgstr "Jumpserver 使用该用户来 `推送系统用户`、`获取资产硬件 #: audits/templates/audits/login_log_list.html:91 #: users/templates/users/user_group_list.html:10 #: users/templates/users/user_list.html:10 -#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:59 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:49 #: xpack/plugins/vault/templates/vault/vault.html:55 msgid "Export" msgstr "导出" @@ -2288,7 +2298,7 @@ msgid "MFA" msgstr "MFA" #: audits/models.py:87 audits/templates/audits/login_log_list.html:63 -#: xpack/plugins/change_auth_plan/models.py:423 +#: xpack/plugins/change_auth_plan/models.py:416 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:15 #: xpack/plugins/cloud/models.py:278 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:69 @@ -2317,11 +2327,11 @@ msgstr "登录日期" #: perms/templates/perms/asset_permission_detail.html:86 #: perms/templates/perms/remote_app_permission_detail.html:78 #: terminal/models.py:167 terminal/templates/terminal/session_list.html:34 -#: xpack/plugins/change_auth_plan/models.py:250 -#: xpack/plugins/change_auth_plan/models.py:426 +#: xpack/plugins/change_auth_plan/models.py:249 +#: xpack/plugins/change_auth_plan/models.py:419 #: 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/gathered_user/models.py:143 +#: xpack/plugins/gathered_user/models.py:140 msgid "Date start" msgstr "开始日期" @@ -2888,49 +2898,49 @@ msgstr "Become" msgid "Create by" msgstr "创建者" -#: ops/models/adhoc.py:252 +#: ops/models/adhoc.py:254 msgid "{} Start task: {}" msgstr "{} 任务开始: {}" -#: ops/models/adhoc.py:264 +#: ops/models/adhoc.py:263 msgid "{} Task finish" msgstr "{} 任务结束" -#: ops/models/adhoc.py:356 +#: ops/models/adhoc.py:360 msgid "Start time" msgstr "开始时间" -#: ops/models/adhoc.py:357 +#: ops/models/adhoc.py:361 msgid "End time" msgstr "完成时间" -#: ops/models/adhoc.py:358 ops/templates/ops/adhoc_history.html:57 +#: ops/models/adhoc.py:362 ops/templates/ops/adhoc_history.html:57 #: ops/templates/ops/task_history.html:63 ops/templates/ops/task_list.html:17 -#: xpack/plugins/change_auth_plan/models.py:253 -#: xpack/plugins/change_auth_plan/models.py:429 +#: xpack/plugins/change_auth_plan/models.py:252 +#: xpack/plugins/change_auth_plan/models.py:422 #: 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/gathered_user/models.py:146 +#: xpack/plugins/gathered_user/models.py:143 msgid "Time" msgstr "时间" -#: ops/models/adhoc.py:359 ops/templates/ops/adhoc_detail.html:106 +#: ops/models/adhoc.py:363 ops/templates/ops/adhoc_detail.html:106 #: ops/templates/ops/adhoc_history.html:55 #: ops/templates/ops/adhoc_history_detail.html:69 #: ops/templates/ops/task_detail.html:84 ops/templates/ops/task_history.html:61 msgid "Is finished" msgstr "是否完成" -#: ops/models/adhoc.py:360 ops/templates/ops/adhoc_history.html:56 +#: ops/models/adhoc.py:364 ops/templates/ops/adhoc_history.html:56 #: ops/templates/ops/task_history.html:62 msgid "Is success" msgstr "是否成功" -#: ops/models/adhoc.py:361 +#: ops/models/adhoc.py:365 msgid "Adhoc raw result" msgstr "结果" -#: ops/models/adhoc.py:362 +#: ops/models/adhoc.py:366 msgid "Adhoc result summary" msgstr "汇总" @@ -3350,7 +3360,7 @@ msgstr "刷新授权缓存" msgid "Validity" msgstr "有效" -#: perms/templates/perms/asset_permission_list.html:244 +#: perms/templates/perms/asset_permission_list.html:230 msgid "Refresh success" msgstr "刷新成功" @@ -4832,7 +4842,7 @@ msgstr "生成重置密码链接,通过邮件发送给用户" msgid "Set password" msgstr "设置密码" -#: users/forms.py:152 xpack/plugins/change_auth_plan/models.py:89 +#: users/forms.py:152 xpack/plugins/change_auth_plan/models.py:88 #: 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_execution_list.html:57 @@ -5762,8 +5772,8 @@ msgstr "" "具)
注意: 如果同时设置了定期执行和周期执行,优先使用定期执行" #: xpack/plugins/change_auth_plan/meta.py:9 -#: xpack/plugins/change_auth_plan/models.py:117 -#: xpack/plugins/change_auth_plan/models.py:257 +#: xpack/plugins/change_auth_plan/models.py:116 +#: xpack/plugins/change_auth_plan/models.py:256 #: xpack/plugins/change_auth_plan/views.py:33 #: xpack/plugins/change_auth_plan/views.py:50 #: xpack/plugins/change_auth_plan/views.py:74 @@ -5774,20 +5784,20 @@ msgstr "" msgid "Change auth plan" msgstr "改密计划" -#: xpack/plugins/change_auth_plan/models.py:58 +#: xpack/plugins/change_auth_plan/models.py:57 msgid "Custom password" msgstr "自定义密码" -#: xpack/plugins/change_auth_plan/models.py:59 +#: xpack/plugins/change_auth_plan/models.py:58 msgid "All assets use the same random password" msgstr "所有资产使用相同的随机密码" -#: xpack/plugins/change_auth_plan/models.py:60 +#: xpack/plugins/change_auth_plan/models.py:59 msgid "All assets use different random password" msgstr "所有资产使用不同的随机密码" -#: xpack/plugins/change_auth_plan/models.py:79 -#: xpack/plugins/change_auth_plan/models.py:148 +#: xpack/plugins/change_auth_plan/models.py:78 +#: xpack/plugins/change_auth_plan/models.py:147 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:100 #: xpack/plugins/cloud/models.py:165 xpack/plugins/cloud/models.py:219 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:91 @@ -5796,8 +5806,8 @@ msgstr "所有资产使用不同的随机密码" msgid "Cycle perform" msgstr "周期执行" -#: xpack/plugins/change_auth_plan/models.py:84 -#: xpack/plugins/change_auth_plan/models.py:146 +#: xpack/plugins/change_auth_plan/models.py:83 +#: xpack/plugins/change_auth_plan/models.py:145 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:92 #: xpack/plugins/cloud/models.py:170 xpack/plugins/cloud/models.py:217 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:83 @@ -5806,37 +5816,37 @@ msgstr "周期执行" msgid "Regularly perform" msgstr "定期执行" -#: xpack/plugins/change_auth_plan/models.py:93 +#: xpack/plugins/change_auth_plan/models.py:92 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:74 msgid "Password rules" msgstr "密码规则" -#: xpack/plugins/change_auth_plan/models.py:213 +#: xpack/plugins/change_auth_plan/models.py:212 msgid "* For security, do not change {} user's password" msgstr "* 为了安全,禁止更改 {} 用户的密码" -#: xpack/plugins/change_auth_plan/models.py:217 +#: xpack/plugins/change_auth_plan/models.py:216 msgid "Assets is empty, please add the asset" msgstr "资产为空,请添加资产" -#: xpack/plugins/change_auth_plan/models.py:261 +#: xpack/plugins/change_auth_plan/models.py:260 msgid "Change auth plan snapshot" msgstr "改密计划快照" -#: xpack/plugins/change_auth_plan/models.py:276 -#: xpack/plugins/change_auth_plan/models.py:433 +#: xpack/plugins/change_auth_plan/models.py:275 +#: xpack/plugins/change_auth_plan/models.py:426 msgid "Change auth plan execution" msgstr "改密计划执行" -#: xpack/plugins/change_auth_plan/models.py:442 +#: xpack/plugins/change_auth_plan/models.py:435 msgid "Change auth plan execution subtask" msgstr "改密计划执行子任务" -#: xpack/plugins/change_auth_plan/models.py:460 +#: xpack/plugins/change_auth_plan/models.py:453 msgid "Authentication failed" msgstr "认证失败" -#: xpack/plugins/change_auth_plan/models.py:462 +#: xpack/plugins/change_auth_plan/models.py:455 msgid "Connection timeout" msgstr "连接超时" @@ -6186,19 +6196,19 @@ msgid "Periodic" msgstr "定时执行" #: xpack/plugins/gathered_user/models.py:57 -#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:48 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:38 msgid "Gather user task" msgstr "收集用户任务" -#: xpack/plugins/gathered_user/models.py:140 +#: xpack/plugins/gathered_user/models.py:137 msgid "Task" msgstr "任务" -#: xpack/plugins/gathered_user/models.py:152 +#: xpack/plugins/gathered_user/models.py:149 msgid "gather user task execution" msgstr "收集用户执行" -#: xpack/plugins/gathered_user/models.py:158 +#: xpack/plugins/gathered_user/models.py:155 msgid "Assets is empty, please change nodes" msgstr "资产为空,请更改节点" @@ -6446,6 +6456,11 @@ msgstr "密码匣子" msgid "vault create" msgstr "创建" +#, fuzzy +#~| msgid "Login" +#~ msgid "Login IP" +#~ msgstr "登录" + #~ msgid "succeed: {} failed: {} total: {}" #~ msgstr "成功:{} 失败:{} 总数:{}" diff --git a/apps/ops/models/adhoc.py b/apps/ops/models/adhoc.py index b9c1c4a74..3eebb6636 100644 --- a/apps/ops/models/adhoc.py +++ b/apps/ops/models/adhoc.py @@ -246,30 +246,35 @@ class AdHoc(models.Model): time_start = time.time() date_start = timezone.now() is_success = False + summary = {} + raw = '' try: date_start_s = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') print(_("{} Start task: {}").format(date_start_s, self.task.name)) raw, summary = self._run_only() is_success = summary.get('success', False) - return raw, summary except Exception as e: logger.error(e, exc_info=True) - summary = {} raw = {"dark": {"all": str(e)}, "contacted": []} - return raw, summary finally: date_end = timezone.now() date_end_s = date_end.strftime('%Y-%m-%d %H:%M:%S') print(_("{} Task finish").format(date_end_s)) print('.\n\n.') + try: + summary_text = json.dumps(summary) + except json.JSONDecodeError: + summary_text = '{}' AdHocRunHistory.objects.filter(id=history.id).update( date_start=date_start, is_finished=True, is_success=is_success, date_finished=timezone.now(), - timedelta=time.time() - time_start + timedelta=time.time() - time_start, + _summary=summary_text ) + return raw, summary def _run_only(self): Task.objects.filter(id=self.task.id).update(date_updated=timezone.now()) @@ -321,10 +326,9 @@ class AdHoc(models.Model): except AdHocRunHistory.DoesNotExist: return None - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): - super().save(force_insert=force_insert, force_update=force_update, - using=using, update_fields=update_fields) + def save(self, **kwargs): + instance = super().save(**kwargs) + return instance def __str__(self): return "{} of {}".format(self.task.name, self.short_id) @@ -393,7 +397,10 @@ class AdHocRunHistory(models.Model): @summary.setter def summary(self, item): - self._summary = json.dumps(item) + try: + self._summary = json.dumps(item) + except json.JSONDecodeError: + self._summary = json.dumps({}) @property def success_hosts(self): diff --git a/apps/perms/templates/perms/asset_permission_list.html b/apps/perms/templates/perms/asset_permission_list.html index 18e30bde8..57079b4f8 100644 --- a/apps/perms/templates/perms/asset_permission_list.html +++ b/apps/perms/templates/perms/asset_permission_list.html @@ -23,12 +23,12 @@ {% block content %}
-
+
{% include 'assets/_node_tree.html' %}
-
+
@@ -209,20 +209,6 @@ function initTree() { }) } -function toggle() { - if (show === 0) { - $("#split-left").hide(500, function () { - $("#split-right").attr("class", "col-lg-12"); - $("#toggle-icon").attr("class", "fa fa-angle-right fa-x"); - show = 1; - }); - } else { - $("#split-right").attr("class", "col-lg-9"); - $("#toggle-icon").attr("class", "fa fa-angle-left fa-x"); - $("#split-left").show(500); - show = 0; - } -} $(document).ready(function(){ initTable(); diff --git a/apps/tickets/migrations/0002_auto_20191114_1105.py b/apps/tickets/migrations/0002_auto_20191114_1105.py new file mode 100644 index 000000000..87cec4056 --- /dev/null +++ b/apps/tickets/migrations/0002_auto_20191114_1105.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.5 on 2019-11-14 03:05 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('tickets', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='comment', + name='ticket', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='tickets.Ticket'), + ), + migrations.AlterField( + model_name='ticket', + name='type', + field=models.CharField(choices=[('general', 'General'), ('login_confirm', 'Login confirm')], default='general', max_length=16, verbose_name='Type'), + ), + ]