Compare commits

...

2427 Commits
0.1.0 ... v0.4

Author SHA1 Message Date
ibuler
91601cce9e [Feature] Support multiple ou search 2017-10-12 14:29:00 +08:00
ibuler
a4fa15a7de Update logging 2017-10-10 15:46:14 +08:00
ibuler
d4ed6a97a5 [Bugfix] Update jumpserver settings 2017-10-10 14:28:32 +08:00
ibuler
0db8482873 Update ldap auth 2017-10-10 14:18:08 +08:00
ibuler
8bccaa6ee2 Update issue template 2017-10-08 19:43:55 +08:00
ibuler
2ae3bec335 [Bugfix] Change user public key length to 5000, fixed #631 2017-09-28 21:37:36 +08:00
ibuler
da5b9be5ca [Bugfix] Update some translation and set warning, partial fix #646 2017-09-28 20:52:33 +08:00
ibuler
d1fbbd3213 [Bugfix] Push system user have not result may be error, fixed #701 2017-09-28 07:23:46 +08:00
ibuler
688a836bbe [Copywriting] Copywriting change fixes #733 2017-09-28 07:15:36 +08:00
ibuler
83c49ae78f Update readme icon 2017-09-27 13:29:58 +08:00
ibuler
e1a8f4910f Update readme 2017-09-27 13:26:57 +08:00
ibuler
5ddcc994de Add issue template 2017-09-27 07:38:07 +08:00
ibuler
5446196471 [Bugfix] #695 Asset detail add or delete system user or group mixed 2017-09-27 07:20:16 +08:00
ibuler
0f9ae9efbb Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2017-09-25 22:15:42 +08:00
ibuler
4aef5b8229 [Bugfix] export asset pof error when none of assets 2017-09-25 22:15:22 +08:00
ibuler
6903e05af1 [Bugfix] Remove pdfmake js 404 2017-09-25 21:55:48 +08:00
Caijun
43a0c4fe51 Fix importing csv bugs (#717)
* Fix exporting csv bugs

1. auto detect the encoding of csv
2. if id in csv is empty, let it equal 0
3. if hostname exists, give up this asset

* Add chardet to requirements.txt
2017-09-24 09:16:47 +08:00
老广
8342ba68c0 Update requirements.txt 2017-09-24 08:57:20 +08:00
crisewng
48ef5c421b 更新Mac安装ldap失败解决方法 (#613) 2017-09-24 08:41:42 +08:00
管宜尧
290872dcad bugfix: 解决用户失效时间为空时,无法使用密码进行ssh登录跳板机的问题 (#659)
* bugfix: 解决用户失效时间为空时,无法使用密码进行ssh登录跳板机的问题

bugfix: 解决用户失效时间为空时,无法使用密码进行ssh登录跳板机的问题。

```
AttributeError at /api/users/v1/auth/
'NoneType' object has no attribute 'strftime'

Request Method: POST
Request URL: http://127.0.0.1:8080/api/users/v1/auth/
Django Version: 1.11.4
Python Executable: /opt/py3/bin/python
Python Version: 3.6.1
Python Path: ['/data/deployment/jumpserver/apps', '/usr/local/lib/python36.zip', '/usr/local/lib/python3.6', '/usr/local/lib/python3.6/lib-dynload', '/opt/py3/lib/python3.6/site-packages', '/data/deployment/jumpserver', '/data/deployment/jumpserver/apps']
Server time: Wed, 30 Aug 2017 23:18:47 +0800
Installed Applications:
['users.apps.UsersConfig',
 'assets.apps.AssetsConfig',
 'perms.apps.PermsConfig',
 'ops.apps.OpsConfig',
 'audits.apps.AuditsConfig',
 'common.apps.CommonConfig',
 'applications.apps.ApplicationsConfig',
 'rest_framework',
 'rest_framework_swagger',
 'django_filters',
 'bootstrap3',
 'captcha',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'jumpserver.middleware.TimezoneMiddleware',
 'jumpserver.middleware.DemoMiddleware']


Traceback:  

File "/opt/py3/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)
File "/opt/py3/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)
File "/opt/py3/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.6/contextlib.py" in inner
  53.                 return func(*args, **kwds)
File "/opt/py3/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)
File "/opt/py3/lib/python3.6/site-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)
File "/opt/py3/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  489.             response = self.handle_exception(exc)
File "/opt/py3/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
  449.             self.raise_uncaught_exception(exc)
File "/opt/py3/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  486.             response = handler(request, *args, **kwargs)
File "/data/deployment/jumpserver/apps/users/api.py" in post
  166.             return Response({'token': token, 'user': user.to_json()})
File "/data/deployment/jumpserver/apps/users/models/user.py" in to_json
  207.             'date_expired': self.date_expired.strftime('%Y-%m-%d %H:%M:%S')

Exception Type: AttributeError at /api/users/v1/auth/
Exception Value: 'NoneType' object has no attribute 'strftime'
Request information:
USER: AnonymousUser
GET: No GET data
POST: No POST data
FILES: No FILES data
COOKIES: No cookie data
```

* bugfix: 个人信息页面个人信息pannel错位

bugfix: 个人信息页面个人信息pannel错位
2017-09-24 08:40:59 +08:00
老广
d4fa082e17 Update Dockerfile 2017-09-14 09:49:42 +08:00
ibuler
e6537699fd [Bugfix] Update asset create template bug 2017-09-13 10:09:17 +08:00
老广
1d950c4f49 Update settings.py 2017-09-12 17:58:09 +08:00
老广
5e197fb0db Update README.md 2017-09-08 07:18:26 +08:00
ibuler
594ad0e14f Update db index more than 767 2017-08-31 16:54:45 +08:00
ibuler
d73d6e943b update user model charfield max length more than 767 bug 2017-08-31 16:04:57 +08:00
老广
eb8b02d88b Update README.md 2017-08-03 18:16:32 +08:00
老广
c8728e52d8 Update README.md 2017-08-03 18:14:36 +08:00
本杰明
8537e3e135 Update settings (#595)
修改redis有密码无法连接bug
2017-08-03 15:24:16 +08:00
ibuler
cd1d690fd3 [Bugfix] 修复一些bug 2017-07-28 21:52:43 +08:00
中国娃
67e953902b Update utils.py (#579) 2017-07-28 20:42:16 +08:00
ibuler
5ffd1f99fd [Bugfix] 修复更新bug 2017-07-24 22:42:01 +08:00
ibuler
cc1a339142 [bugfix] system user update bug 2017-07-24 21:59:55 +08:00
ibuler
1c78526f86 Fix bug 2017-07-20 07:58:16 +08:00
ibuler
b0a5289a42 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2017-07-20 07:55:45 +08:00
ibuler
477d23ea37 fix some bug 2017-07-20 07:55:24 +08:00
tonygatescxp
72c2290300 Update settings.py (#515)
修正Redis连接字符串
2017-07-17 17:18:14 +08:00
ibuler
61014c747e Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2017-07-15 13:51:15 +08:00
ibuler
b2ba1f3ca5 update requirements 2017-07-15 13:50:56 +08:00
Eli
7c154abf70 fix bug: variable i should be the host name (#538)
fix bug: variable i is not the host name, because summary['failed'] is something like [("hostname1", "error message 1"),("hostname1", "error message 1")]
2017-07-13 14:00:17 +08:00
ibuler
d012880a90 [Bugfix] 修复bug 2017-07-13 11:46:56 +08:00
ibuler
3ce07cf969 Update README 2017-07-12 20:45:21 +08:00
ibuler
24dd7b6347 update docker config 2017-07-10 15:11:28 +08:00
ibuler
9237c9dcee Add requirements 2017-07-10 11:31:33 +08:00
ibuler
143cabe5fc update settings 2017-07-10 11:02:51 +08:00
Eli
370cdc275a 添加一个资产,然后推送系统用户时出现(Asset实例无法序列化) (#477)
* error while push systemuser. error while create assets with adminuser(ssh key)

* fix errors in case of config.py dose not exist.

* change sign_t return from bytes to str. (#480)

* fix id_dsa check error (#458)

* fix id_dsa check error

* fix 邮件修改密码 token错误

* fix 3c8aec9 add )

* Dockerfile 优化 (#453)
2017-07-10 11:01:20 +08:00
老广
235cbe12ee Update README.md 2017-07-10 10:57:41 +08:00
Fengxu Lin
26a169d938 fix bug in pagination_range function (#511)
start and end may be float when current_num >= 3 and display % 2 == 1
2017-07-10 10:39:18 +08:00
ibuler
4e67749eef [Docs] 添加api dockers 2017-07-10 10:26:17 +08:00
ibuler
e120fd56a6 Update readme 2017-06-19 23:48:36 +08:00
ibuler
51b9e3732f Update readme 2017-06-19 23:41:45 +08:00
ibuler
f3a50610af [Update] update docker-compose 2017-06-19 23:15:09 +08:00
ibuler
4141ae517f update docker-compose 2017-06-19 18:13:44 +08:00
ibuler
29095a869c [Demo] update demo mode code 2017-06-19 17:59:13 +08:00
ibuler
cda22a6f0d add demo mode middleware 2017-06-15 22:35:03 +08:00
Caijun
8f4d8b1c02 Compile messages (#495) 2017-06-13 17:51:12 +08:00
Caijun
b502b06e82 Support i18n for asset platform field (#494) 2017-06-13 16:38:33 +08:00
谢义学
7d541ee916 Dockerfile 优化 (#453) 2017-06-06 11:25:14 +08:00
njqaaa
9b14244363 fix id_dsa check error (#458)
* fix id_dsa check error

* fix 邮件修改密码 token错误

* fix 3c8aec9 add )
2017-06-06 11:23:39 +08:00
bdlzhx
b680a42425 change sign_t return from bytes to str. (#480) 2017-06-06 11:22:29 +08:00
Caijun
cf07a6ebb7 Fix judging request.user valid on UserToken API (#476) 2017-06-02 17:15:59 +08:00
njqaaa
dd6c82b168 fix left's users logout (#446)
* fix left's users logout

* fix issues 445
2017-05-25 14:12:16 +08:00
crisewng
18169251fa [Bugfix] 修复管理用户上传私钥兼容问题 (#451) 2017-05-25 11:14:21 +08:00
ibuler
8ee1e468b8 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2017-05-24 20:13:01 +08:00
ibuler
1719eee264 [Bugfix] 修复py3 bytes bug 2017-05-24 20:12:50 +08:00
老广
ae94948246 Update README.md 2017-05-24 09:49:02 +08:00
老广
f19bcc48f6 Update python_style_guide.md 2017-05-22 23:28:35 +08:00
ibuler
41633be1aa [Bugfix] 修复无法删除资产组 2017-05-22 20:30:31 +08:00
ibuler
d2620a655c [Bugfix] 修复模板bug, 修复getattr bug 2017-05-22 20:18:13 +08:00
ibuler
24c1a931a5 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2017-05-22 19:56:39 +08:00
ibuler
31025b8c52 [bugfix] 修复重置密码bug 2017-05-22 19:51:54 +08:00
ibuler
25f3d5bf02 [Bugfix] 修复翻译一处bug 2017-05-22 19:48:15 +08:00
老广
e21bea6ec0 Update README.md 2017-05-22 12:31:37 +08:00
老广
0399074fcb Update README.md 2017-05-22 11:27:30 +08:00
ibuler
edc631ad60 [Docker] 添加Docker compose 2017-05-20 00:19:10 +08:00
GuangHongwei
ff374b7141 [Docker] Build a docker 2017-05-17 09:42:32 +08:00
GuangHongwei
458989328e [Bugfix] 修改bug,使用py3编程 2017-05-15 23:39:54 +08:00
GuangHongwei
3c8d6fbe1b Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2017-05-11 19:42:58 +08:00
GuangHongwei
a052ac8117 [Bugfix] 注释掉配置,影响登陆 2017-05-11 19:41:13 +08:00
老广
94a022e76b Update install.md 2017-05-11 09:54:00 +08:00
GuangHongwei
831ac60e25 [Update] 更新文档说明,使用python3 2017-05-11 09:43:59 +08:00
GuangHongwei
56e648e924 Update requirements 2017-05-11 09:19:37 +08:00
GuangHongwei
61c5eede94 Merge branch 'dev' of github.com:jumpserver/jumpserver 2017-05-10 10:00:48 +08:00
ibuler
2ec0ab871a Fix form bug 2017-04-12 18:06:32 +08:00
ibuler
695e4da85e [Fixture] 完成批量更新 2017-04-12 11:50:15 +08:00
ibuler
2aa9aafdf6 [Change] Bulk update asset 2017-04-11 17:29:53 +08:00
ibuler
071d1922d0 stash it 2017-04-10 22:55:15 +08:00
ibuler
95e64d7809 [Change] 修改导出和更新逻辑 2017-04-09 17:59:14 +08:00
ibuler
5418d0b44c [Change] Using csv replace xlsx 2017-04-09 00:45:28 +08:00
ibuler
bcc065eb8f [Compat] compat py3 change bootstrap form to bootstrap3 2017-04-07 23:52:46 +08:00
ibuler
a320b9e05e [Bugfix] 兼容py3 2017-04-07 19:11:27 +08:00
ibuler
b913bce398 [Bugfix] 修改翻译bug 2017-04-07 17:09:25 +08:00
ibuler
c11374ae39 [Bugfix] 修改翻译 2017-04-07 16:59:09 +08:00
假想控
eebd54a4e8 Update install.md 2017-04-06 18:46:00 +08:00
ibuler
92ebe85a3f [Fixture] 详情页添加system user 推送 2017-04-05 19:09:51 +08:00
ibuler
25b8108af0 Merge branch 'audits' 2017-04-04 21:52:29 +08:00
ibuler
8a2b008fbf Merge branch 'a' 2017-04-04 21:52:23 +08:00
ibuler
753440faff Merge branch 'dev' of github.com:jumpserver/jumpserver into audits 2017-04-04 21:52:04 +08:00
ibuler
be09db059d Update some bug 2017-04-04 21:47:58 +08:00
假想控
cbb14d140e Update install.md 2017-04-04 20:46:03 +08:00
假想控
f06cf887e1 Update install.md 2017-04-04 20:16:40 +08:00
假想控
194a698372 Update install.md 2017-04-04 20:15:30 +08:00
ibuler
5a5d5bdd51 [Fixture] 添加更新硬件信息api 2017-04-04 19:16:34 +08:00
ibuler
992af0f1cb [Fixture] 拆分asset view 2017-04-04 11:37:52 +08:00
ibuler
ac3553babb [Fixture] 修改asset detail 2017-04-04 11:14:59 +08:00
ibuler
97fb2a4fe6 [Fixture] 修改index页面 2017-04-03 00:27:18 +08:00
ibuler
709552f14c [Fixture] 添加首页 2017-04-02 18:09:40 +08:00
老广
365750565d Update requirements.txt 2017-04-01 13:53:34 +08:00
ibuler
66a2262ee9 [Fixture] 增加 asset groups assets api 2017-04-01 00:41:16 +08:00
ibuler
067426d5e0 [Fixture] 完成用户向导页 2017-03-31 23:46:00 +08:00
ibuler
87eb1914fb Merge branch 'dev' of github.com:jumpserver/jumpserver 2017-03-31 18:50:34 +08:00
ibuler
135899608e Merge branch 'master' of code.jumpserver.org:Jumpserver/jumpserver 2017-03-31 18:48:11 +08:00
ibuler
7720e9f3fd [Change] 修改图片 2017-03-31 18:47:50 +08:00
ibuler
61a481f427 [Fixture] 添加用户连接终端 2017-03-31 11:25:25 +08:00
ibuler
3fa5ce5404 [Fixture] 添加用户信息更改 2017-03-30 16:28:00 +08:00
ibuler
0983f294b7 [Fixture] 添加用户profile 2017-03-30 00:51:36 +08:00
ibuler
4e7b665ea8 [Change] 添加翻译,并添加用户登陆页面 2017-03-29 15:26:32 +08:00
右书僮
b34c5dde40 Merge branch 'master' of code.jumpserver.org:Jumpserver/jumpserver
# Conflicts:
#	apps/assets/templates/assets/asset_list.html
2017-03-27 08:03:23 +08:00
右书僮
9de2ff2052 修复idc_list删除时重新加载table 2017-03-27 07:58:35 +08:00
ibuler
a4ad9b49b9 Merge branch 'audits' 2017-03-26 19:41:17 +08:00
ibuler
90055f7680 [Bugfix] 添加翻译 2017-03-26 19:41:10 +08:00
假想控
2e31cf51f3 Update install.md 2017-03-26 14:56:17 +08:00
假想控
4714d5d42f Update install.md 2017-03-26 13:55:01 +08:00
假想控
5984b0b579 Update install.md 2017-03-26 13:54:11 +08:00
假想控
d700c448c6 Update install.md 2017-03-26 13:50:10 +08:00
假想控
ef8599b836 Update install.md 2017-03-26 13:46:26 +08:00
假想控
dd5b1097f2 Update install.md 2017-03-26 13:40:27 +08:00
假想控
f7c35fde2d Update install.md 2017-03-26 13:38:48 +08:00
假想控
4fbb4dfb55 Update install.md 2017-03-26 13:35:26 +08:00
假想控
84af0405d9 Update install.md 2017-03-26 13:32:38 +08:00
假想控
c0e5e5f896 Update install.md 2017-03-26 13:31:38 +08:00
老广
12bc63fbc9 Update install.md 2017-03-26 13:06:34 +08:00
老广
7bbb1d24ac Update install.md 2017-03-26 13:05:33 +08:00
ibuler
49f6ed524d Merge with master 2017-03-26 11:54:46 +08:00
ibuler
7ddfa2d25e [Doc] 添加doc 2017-03-26 11:50:09 +08:00
ibuler
d3cdfc1b9d Update ignore 2017-03-24 23:14:10 +08:00
ibuler
1f9dbb6bdc [Change] 修复验证码模糊度 2017-03-24 23:13:17 +08:00
ibuler
10eb13920b [Delete] 删除资产tag 2017-03-24 14:48:18 +08:00
ibuler
a57dac0706 [Fixture] 拆分proxy log 为在线和离线 2017-03-24 14:23:51 +08:00
右书僮
e0179ea332 删除资产HTML页面中SystemUser相关内容(视图中的相关API暂时未动) 2017-03-24 11:13:40 +08:00
右书僮
c931d3179b 修复资产组更新中 用户己选择的资产项不全问题 2017-03-24 11:02:55 +08:00
右书僮
c5666f1357 fix some files 2017-03-24 10:37:05 +08:00
ibuler
b60e5a7ee3 [Change] 修改一些view 2017-03-24 00:27:33 +08:00
ibuler
c940a4c0fb [Fixture] 增加 task list 删除按钮 2017-03-23 00:15:25 +08:00
ibuler
3f72ce4b1f [Update] 更新生成fake数据脚本 2017-03-22 23:36:43 +08:00
ibuler
5613dbb28b [Update] 更新生成fake数据脚本 2017-03-22 23:36:30 +08:00
ibuler
2ae57a7970 [Delete] 删除 system user一些属性 2017-03-22 22:15:15 +08:00
ibuler
610c9c5149 Pull it 2017-03-22 22:05:24 +08:00
ibuler
caec9709ef [Fixture] 添加task list 搜索,重试 2017-03-22 21:57:05 +08:00
ibuler
a4504dc0c7 [Change] 拆分tasks 2017-03-16 00:43:43 +08:00
ibuler
0fbd9843bd [Change] 修改runner, inventory位置 2017-03-16 00:19:47 +08:00
ibuler
240c7db416 [Fixture] 添加 rerun function 2017-03-14 14:15:13 +08:00
ibuler
915873135e [Fixture] 添加runner run record 2017-03-14 00:58:25 +08:00
ibuler
a822f667af [Fixture] 完成用户推送task 2017-03-09 14:55:33 +08:00
ibuler
c234b5b2d5 Update AdHocRunner 2017-03-06 23:34:54 +08:00
xiaokong1937@gmail.com
694899799b trivial changes 2017-03-06 21:05:00 +08:00
ibuler
eb5a9dd20f Remote ansible_api file 2017-03-05 23:30:14 +08:00
ibuler
6015f2423b [Fixture] 添加PlaybookRunner 2017-03-05 20:53:24 +08:00
ibuler
01e50d592e 完成AdHoc JMSHost JMSInventory 2017-03-05 11:38:02 +08:00
老广
0524e8dddf Update README.md 2017-03-04 16:41:36 +08:00
ibuler
ab62bfca7e [Bugfix] 修改一些bug 2017-03-04 16:38:26 +08:00
ibuler
7833fc8c80 Merge remote-tracking branch 'new_git/dev' into dev 2017-03-03 15:19:55 +08:00
ibuler
9c2c38c74a [Bugfix] 修复导入自定义过滤器问题 2017-03-03 15:15:10 +08:00
ibuler
78700cd2f5 merge with version 0.4.0 2017-03-03 10:28:45 +08:00
ibuler
695dc96ce8 Merge branch 'audits' 2017-03-03 10:24:34 +08:00
ibuler
f1d4cae20b Delete 0.3.1 version code 2017-03-03 10:13:58 +08:00
ibuler
9518672ad2 Add 2017-03-02 18:29:29 +08:00
ibuler
b055144908 Merge with audits 2017-03-01 15:35:11 +08:00
ibuler
7825c107ab [Bugfix] model FieldError 2017-03-01 15:30:19 +08:00
右书僮
dd5dd9d7e1 fixed html files 2017-02-25 23:20:20 +08:00
Webb
63fd3cfff2 fixed asset_group delete html 2017-02-25 20:18:13 +08:00
Webb
a6825ac91e fixed asset_list html and asset_update 2017-02-25 17:25:27 +08:00
Webb
8ee9d02ffc fixed html 2017-02-24 21:29:11 +08:00
ibuler
008be6a8e3 [Fixtrue] 完成terminal detail 和批量结束会话 2017-02-12 16:51:32 +08:00
ibuler
1f544b98ab [Stash] 删除结束会话之前 2017-02-11 19:49:15 +08:00
ibuler
42e4c64d06 [Bugfix] 修复一些bug 2017-02-11 12:13:02 +08:00
xiaokong1937@gmail.com
548d7ef99a fix #13;fix user context conflict problem in user-detail page 2017-02-09 21:19:49 +08:00
ibuler
9c7bd7d285 [Fixture] 添加record log 2017-02-07 21:51:44 +08:00
ibuler
a79c3dd156 [Fixture] 添加command log backends, 未来支持es 2017-02-06 23:13:27 +08:00
xiaokong1937@gmail.com
fe01f92545 user profile: update ssh pk 2017-02-03 13:37:05 +08:00
xiaokong1937@gmail.com
8a5d0b2d92 remove unused templatetags: users_tags and common_tags 2017-01-26 20:24:50 +08:00
xiaokong1937@gmail.com
f3647ea46d user-profile page 2017-01-25 21:19:16 +08:00
xiaokong1937@gmail.com
31bded8953 CAPTCHA_TEST_MODE settings and small fix 2017-01-23 12:29:36 +08:00
xiaokong1937@gmail.com
3f7cb4a458 ignore windows bat files 2017-01-23 10:52:59 +08:00
ibuler
0869931e67 [Bugfix] 修改了一些issue上的bug 2017-01-20 20:13:22 +08:00
ibuler
948214cacb Merge branch 'audits' 2017-01-20 14:00:11 +08:00
ibuler
df94d11f53 [Fix] 修改一些api bug 2017-01-20 13:59:53 +08:00
ibuler
ffed28c9c7 [Change] 修改perm的代码, 强制79个字符内 2017-01-17 17:11:01 +08:00
ibuler
25cb47d2f5 [Change] 拆分user view为多个view 2017-01-17 16:34:47 +08:00
wangfeng7399
0979480103 update dockerfile 2017-01-13 15:43:51 +08:00
王胜辉
dc4c37afb6 Update README.md 2017-01-13 07:30:23 +00:00
ibuler
87bbb6afde [Bugfix] 修改添加系统用户view 2017-01-10 23:41:14 +08:00
ibuler
8916221bba [Bugfix] 紧急修复url解析失败错误 2017-01-10 18:03:00 +08:00
ibuler
8658675f67 [Bugfix] 重命名applications导致api请求content_type不对 2017-01-09 23:12:32 +08:00
ibuler
be3f94d86c [BugFix] 修改requirements添加新的库 2017-01-09 01:58:23 +08:00
ibuler
17657deb0e [Bugfix] 和Master分支合并后,修复冲突,DRF 新版本要求 fields和exclude 2017-01-08 13:35:59 +08:00
ibuler
49861b6a84 Merge with master 2017-01-07 22:34:12 +08:00
ibuler
3da33a57e2 [Bugfix] 修改tab -> space, 删除system user的 as default 2017-01-07 20:17:22 +08:00
ibuler
9c6c6d6b4c [Feature] 添加Dockerfile 2017-01-07 20:07:33 +08:00
右书僮
dbdb8a58fe 资产相关API及Web 2017-01-06 20:34:24 +08:00
ibuler
b670259ab6 Modify terminal reqject templatte 2017-01-03 00:11:44 +08:00
ibuler
0907f5021e Finish form ajax submmit 2016-12-30 22:21:50 +08:00
ibuler
301e02bcd8 Update some api 2016-12-30 00:19:47 +08:00
ibuler
70da177ed7 Update api 2016-12-29 19:17:00 +08:00
ibuler
92d854b971 Update api 2016-12-29 00:29:59 +08:00
ibuler
d80fec6e60 Update some api 2016-12-28 00:28:52 +08:00
广宏伟
4c06257070 Update README.md 2016-12-27 23:44:05 +08:00
ibuler
d56f030dc4 Finish terminal accept 2016-12-27 00:59:52 +08:00
ibuler
775cd523eb Update app terminal name to applications 2016-12-25 23:10:53 +08:00
ibuler
a8fa4d2f0c update terminal regist 2016-12-25 17:44:39 +08:00
ibuler
2707012325 Finish access key auth 2016-12-25 13:15:28 +08:00
ibuler
c5ab49c515 Finish access key auth 2016-12-25 13:15:19 +08:00
ibuler
fe17bec752 Add access key auth 2016-12-22 01:07:05 +08:00
ibuler
5b4ce709af Add private token and change user group 2016-12-22 00:36:31 +08:00
ibuler
875aaa0029 update user model for create application user 2016-12-21 01:17:36 +08:00
ibuler
589b6d7cfe update 2016-12-21 01:03:52 +08:00
ibuler
649509dec1 Change models dir 2016-12-21 00:43:52 +08:00
ibuler
4d96978b4f Merge branch 'master' into audits 2016-12-20 23:08:09 +08:00
ibuler
81ec121918 Merge branch 'master' of code.jumpserver.org:jumpserver/jumpserver 2016-12-20 23:07:57 +08:00
ibuler
a448fd02e2 merged 2016-12-20 23:07:33 +08:00
ibuler
96d32f2e3e prepare merge ops 2016-12-20 23:06:27 +08:00
ibuler
4d71c2d1ff 修改token获取,拆分认证文件和权限文件 2016-12-20 01:19:50 +08:00
广宏伟
6ef33eb0c3 Merge branch 'ops_dev' into 'master'
Ops dev

See merge request !1
2016-12-19 23:58:49 +08:00
yumaojun03
046c7e21e9 Merge remote-tracking branch 'origin/master' into ops_dev
# Conflicts:
#	requirements.txt
2016-12-19 23:55:54 +08:00
yumaojun03
47d87e38a6 补充task需要的一些接口 2016-12-19 23:46:03 +08:00
ibuler
2ab8e92bf4 Add black line 2016-12-19 23:10:16 +08:00
yumaojun03
150e1030c3 ansible Task接口更上层抽象的基本实现 2016-12-19 14:07:21 +08:00
yumaojun03
86c5f0d3d3 完成cron和sudo的list和detail基础,ansible Task接口更上层抽象中 2016-12-19 00:24:51 +08:00
ibuler
d964221689 Update api 2016-12-16 19:32:05 +08:00
wangjun5
87eed2e59b add asset tool 2016-12-15 19:55:15 +08:00
广宏伟
a737564a6c Add new file 2016-12-14 19:58:20 +08:00
广宏伟
6374a9772c Add new file 2016-12-14 19:57:47 +08:00
yumaojun03
b348f7f1ce 添加了部分cron的list页面 2016-12-14 09:54:16 +08:00
yumaojun03
a0c9e3d117 添加了部分sudo的页面 2016-12-14 00:06:16 +08:00
yumaojun03
3eb8a702c8 为模型生成fake数据 2016-12-12 11:08:10 +08:00
yumaojun03
806d38bbb2 模拟数据测试 2016-12-11 20:50:26 +08:00
yumaojun03
84613e51d8 为了防止循环导入,采用__all__导出模块变量 2016-12-11 12:05:11 +08:00
ibuler
0e4804b59f Merge branch 'audits' 2016-12-06 10:43:05 +08:00
ibuler
69767e978d Add fake 2016-12-06 10:40:17 +08:00
yumaojun03
baba65ad43 修改url模块, 匹配整体架构风格. 2016-12-05 23:02:08 +08:00
yumaojun03
d0460d8691 修改url模块, 匹配整体架构风格. 2016-12-05 22:54:38 +08:00
ibuler
a7476222a9 Update import 2016-11-27 23:36:35 +08:00
Administrator
61ac9129b0 url少加了下划线 2016-11-27 22:45:53 +08:00
ibuler
3aea994101 asset import 2016-11-27 14:37:50 +08:00
Administrator
8e0afb2cc4 调整模型 2016-11-27 11:30:23 +08:00
ibuler
c1c9c7b68a update asset 2016-11-25 22:45:47 +08:00
ibuler
6e843533cb Base finish user 2016-11-25 11:00:51 +08:00
ibuler
d8a229c09b to Commpany 2016-11-25 08:39:24 +08:00
Administrator
2494fa5846 修改url 2016-11-24 22:34:55 +08:00
Administrator
984391e2b2 同步Master分支上的代码, 解决部分冲突问题 2016-11-24 22:10:04 +08:00
ibuler
72ad4b44ce update bug 2016-11-24 19:36:49 +08:00
Administrator
1bc88e5b11 Merge branch 'ansible_api' into ops_dev
# Conflicts:
#	apps/jumpserver/urls.py
#	apps/locale/zh/LC_MESSAGES/django.po
#	apps/templates/_nav.html
#	requirements.txt
#	run_server.py
2016-11-24 18:22:36 +08:00
Administrator
c289d6a4c5 Merge branch 'ansible_api' into ops_dev
# Conflicts:
#	apps/jumpserver/urls.py
#	apps/locale/zh/LC_MESSAGES/django.po
#	apps/templates/_nav.html
#	requirements.txt
#	run_server.py
2016-11-24 17:57:50 +08:00
Administrator
7c4aefd959 兼容py3测试 2016-11-24 17:10:43 +08:00
ibuler
c1a74aebc5 [BugFix] update some user import bug 2016-11-24 17:08:20 +08:00
ibuler
eae580e51f Update user import and export 2016-11-24 15:45:08 +08:00
ibuler
e28f7a3bec Add export and import 2016-11-24 00:48:57 +08:00
ibuler
be99eb82e8 udpate some bug 2016-11-23 19:37:47 +08:00
ibuler
5af97c969b export csv 2016-11-23 19:09:11 +08:00
ibuler
7dfde3a3c5 Update 2016-11-23 16:17:23 +08:00
Administrator
cd22c39078 [future] 将Task移到一个包内管理 2016-11-23 11:45:50 +08:00
Administrator
32a5aec34e [future] 调整app架构 2016-11-22 23:02:12 +08:00
Administrator
fea76178ee 添加作业中心i18n 2016-11-22 21:40:05 +08:00
Administrator
3abe2196dd [future] 添加作业中心 i18n相关 2016-11-22 21:38:38 +08:00
Administrator
18e0fee1a7 [future] 添加作业中心基础框架 2016-11-22 21:08:45 +08:00
Administrator
954814da65 [future] 添加Cron相关的基础API框架 2016-11-22 10:41:18 +08:00
ibuler
180af7e0bd Update csv 2016-11-22 00:59:49 +08:00
Administrator
79971d677d [future] 使用mixin去掉重复多余代码 2016-11-20 18:12:18 +08:00
Administrator
1e835d2fa9 [future] 增加503和501的自定义异常 2016-11-20 16:23:45 +08:00
Administrator
76f72dfb58 [future] 添加路由, 增加api认证, 测试所有添加的api 2016-11-20 16:22:41 +08:00
Administrator
5ae2711c6e sudo privilege删除走api 2016-11-20 14:48:18 +08:00
Administrator
39ae4a3a10 [future] url 调整 2016-11-20 12:22:56 +08:00
Administrator
961ecb3ee8 [future] 添加sudo相关的api方法 2016-11-20 12:18:44 +08:00
ibuler
205c11dfba Finish list paganation 2016-11-18 12:00:23 +08:00
广宏伟
c743715459 Update README.md 2016-11-18 10:22:35 +08:00
广宏伟
b4bd923304 Update README.md 2016-11-18 10:14:46 +08:00
ibuler
e89d3b3807 Update asset 2016-11-17 19:28:45 +08:00
ibuler
6e69c018b4 Merge branch 'audits' 2016-11-16 18:12:40 +08:00
ibuler
aff37092bf Rename urls 2016-11-16 18:12:14 +08:00
ibuler
5745c8cc4a Finish url namespace change 2016-11-16 17:45:46 +08:00
ibuler
a5e487441f prepare change api name 2016-11-16 17:38:03 +08:00
Administrator
c588436d55 初始化模板和api模块 2016-11-16 15:00:46 +08:00
Administrator
82412831d5 initial sudo views 2016-11-16 14:20:44 +08:00
ibuler
aa08f0aa48 Merge branch 'audits' of code.jumpserver.org:Jumpserver/jumpserver into audits 2016-11-16 12:34:01 +08:00
ibuler
32d12b7f78 Update user group asset permission 2016-11-16 12:33:54 +08:00
ibuler
3b30eb3278 Weiteng 2016-11-15 23:09:36 +08:00
ibuler
99c36f2a2c Fix bug 2016-11-15 19:44:08 +08:00
ibuler
db8b0022fc Update usergroup detail 2016-11-15 19:33:04 +08:00
ibuler
bd882c8bef User group detail 2016-11-15 00:48:48 +08:00
ibuler
8d358a7a68 UPdate some 2016-11-14 19:28:21 +08:00
广宏伟
8731e0816d Update README.md 2016-11-14 19:25:17 +08:00
广宏伟
074cc2f26e Update README.md 2016-11-14 19:24:27 +08:00
广宏伟
6eaaddd8ed Update README.md 2016-11-14 19:21:46 +08:00
ibuler
419876b575 Update heatbeat 2016-11-13 22:34:38 +08:00
ibuler
2635217421 Update celery 2016-11-11 09:48:47 +08:00
ibuler
c6fc3dfe91 Update terminal interval 2016-11-11 02:13:13 +08:00
ibuler
10aa8c40a7 Add login log 2016-11-10 23:54:21 +08:00
ibuler
f70abec5ef Finish user detail 2016-11-10 22:06:23 +08:00
ibuler
69f2bf664b Finish user permission revoke 2016-11-10 16:59:50 +08:00
ibuler
dde9ffb2ae Update perm api 2016-11-10 00:18:57 +08:00
ibuler
47090eb0f7 update some user api 2016-11-09 23:49:10 +08:00
ibuler
c5d625e261 Merge branch 'audits' of code.jumpserver.org:Jumpserver/jumpserver into audits 2016-11-09 19:29:26 +08:00
ibuler
8d7759d22f change user api 2016-11-09 19:29:15 +08:00
ibuler
0d4d64c274 Update api 2016-11-09 00:36:23 +08:00
ibuler
ea3f8af161 Fix pubkey auth bug 2016-11-07 16:59:52 +08:00
ibuler
a75e1db970 Add form validate 2016-11-07 00:39:26 +08:00
ibuler
072da114db Finish system user list 2016-11-06 22:45:26 +08:00
ibuler
968b1b4cb6 Stash 2016-11-06 21:29:04 +08:00
ibuler
afb923737c Merge with audits 2016-11-06 11:52:25 +08:00
ibuler
79c8f2275c Update perm api 2016-11-05 23:34:45 +08:00
Administrator
d9278c2c24 [future] 添加sudo相关的表,以及实现生成sudo内容的方法 2016-11-05 13:10:44 +08:00
ibuler
5b0f897118 Update proxy log and command log view 2016-11-05 12:45:59 +08:00
ibuler
41337d28c3 add proxy log search 2016-11-05 01:15:25 +08:00
ibuler
1d29c52a43 Update datatable 2016-11-04 19:25:10 +08:00
ibuler
53e97dac40 stash it 2016-11-04 18:33:16 +08:00
Administrator
8716d9c725 [future] 添加用于记录sudo相关的表 2016-11-04 18:12:10 +08:00
ibuler
f278b735cc Modify settings 2016-11-04 00:41:21 +08:00
ibuler
2a65e81316 detail page add update 2016-11-03 23:16:16 +08:00
ibuler
f437d3f883 update 2016-11-03 19:42:47 +08:00
Administrator
1fd0f8fdde [future] 添加sudo的配置模板 2016-11-03 18:26:10 +08:00
ibuler
61eadf6891 Modify asset detail 2016-11-03 00:09:38 +08:00
ibuler
3448f3eb0a Modify init data 2016-11-02 23:00:47 +08:00
ibuler
05a5e9cc69 Finish some bug 2016-11-02 19:44:11 +08:00
ibuler
34a0a37b63 Add token 2016-11-01 19:31:35 +08:00
ibuler
1159d9494c Update signer 2016-11-01 17:21:16 +08:00
Administrator
92f396761c [future] 完成获取硬件和链接测试的第一版v1
1. 完成数据结果的封装, 添加数据结构样列
2. 完成硬件和链接测试接口v1版
2016-11-01 10:37:03 +08:00
ibuler
f1dfba6a93 Update some asset issues 2016-10-31 19:31:56 +08:00
ibuler
b36d70987d Finish token access api 2016-10-31 18:58:30 +08:00
ibuler
315af35296 Finish token access api 2016-10-31 18:58:23 +08:00
Administrator
97b8bcd5ca [future]
1. settings 添加ops 的logger, 关于Ansible的log单独记录
2. models 增加Tasker模型, 添加AnsibleHostReuslt 对于数据处理的方法
3. ansible_api, callback 类,增加保存Tasker的逻辑,i其他兼容
4. taskers, 实现获取硬件信息和ping的 tasker接口。
2016-10-31 17:41:26 +08:00
江世峰
6b6fdcd5fd asset:add assets_bulk_update 2016-10-28 21:24:01 +08:00
江世峰
3d4f79ca59 asset:add assets_bulk_update 2016-10-28 21:19:37 +08:00
Administrator
ccf3851d81 [future] 初步添加测试链接的接口 2016-10-28 17:43:56 +08:00
Administrator
97d7e6cb9b [future] 修改celery 使用eventlet 作为concurrent pool, 添加获取资产硬件信息的 初步接口 2016-10-28 17:28:32 +08:00
Administrator
fd945513ac [fix] 修改模型的显示, 因为字段默认会加上Class的Name 2016-10-28 15:47:37 +08:00
ibuler
92251f2a45 Merge with master 2016-10-28 15:09:38 +08:00
Administrator
51c530c123 [future] ansible运行结果存入数据库 2016-10-28 14:58:09 +08:00
Administrator
96bc1cd8f1 [future]ansible运行结果存入数据库中... 2016-10-28 13:41:11 +08:00
ibuler
374dfbdac2 Force merge 2016-10-28 11:36:37 +08:00
ibuler
534321d1aa Merge with master 2016-10-28 11:34:07 +08:00
ibuler
69c6f81c31 Add fake to 2016-10-28 00:21:11 +08:00
ibuler
9e3d740b43 Add fake to 2016-10-28 00:17:10 +08:00
ibuler
5cdc80ec11 Add init data 2016-10-27 23:59:54 +08:00
ibuler
217586b536 Add fake 2016-10-27 23:55:19 +08:00
ibuler
2abec15691 Rm ws4redis 2016-10-27 23:50:44 +08:00
ibuler
688bfa556c Merge with audits 2016-10-27 23:04:02 +08:00
ibuler
589d0d0fac Finish command log list 2016-10-27 22:58:19 +08:00
ibuler
3c00c578c3 Update some vie 2016-10-27 19:35:02 +08:00
Administrator
eb5f0fcf68 [future] 在主机层面支持多种sudo, 以及回调结果的分类 2016-10-27 15:20:16 +08:00
ibuler
c0de35a683 Add layer and layer open command log 2016-10-27 00:52:44 +08:00
ibuler
d19b47a427 add command log modal 2016-10-27 00:03:05 +08:00
ibuler
573b3a8743 Update log_command modal 2016-10-26 19:31:54 +08:00
ibuler
5d3f9b4a03 Add command list 2016-10-26 19:10:14 +08:00
ibuler
c2aab50c7b Add proxy log list 2016-10-25 23:23:01 +08:00
Administrator
13f34a8bdd ops: [future]完成ansible2.0 API 的基本封装. 2016-10-25 18:15:02 +08:00
江世峰
f88c149076 asset:add assets_bulk 2016-10-25 02:16:20 +08:00
ibuler
6a510dad6c Update some bug 2016-10-24 19:32:53 +08:00
江世峰
cdb1602e06 asset:add assets_bulk 2016-10-22 20:21:36 +08:00
江世峰
80baecc8be Merge branch 'master' of code.jumpserver.org:Jumpserver/jumpserver
Merge
2016-10-21 21:15:04 +08:00
江世峰
73f0199dc0 asset:add assets_bulk 2016-10-21 21:14:49 +08:00
ibuler
6b161d5971 Update import 2016-10-20 19:01:57 +08:00
ibuler
67ecc108bd Command parser 2016-10-20 00:26:53 +08:00
ibuler
df380c343e Update api 2016-10-19 19:30:55 +08:00
ibuler
6164896793 Update some thing 2016-10-19 18:33:14 +08:00
ibuler
45dcb26123 Merge branch 'audits' 2016-10-19 15:14:07 +08:00
ibuler
bb9a067293 Finish command log 2016-10-19 01:05:28 +08:00
ibuler
961abad14b Add heatbeat 2016-10-18 23:49:04 +08:00
ibuler
17ade287ab Add proxy log api 2016-10-18 19:28:36 +08:00
ibuler
7513474366 Finish terminal app 2016-10-17 17:28:07 +08:00
ibuler
303659cb0e Change app name apps => terrminal 2016-10-17 15:24:41 +08:00
江世峰
4e1f9c97a5 asset:update assets_list by tag 2016-10-16 22:35:25 +08:00
ibuler
4531157c72 may be some wrong 2016-10-16 22:12:13 +08:00
ibuler
26a8bce2c3 Change auto_now to auto_now_add 2016-10-15 23:34:02 +08:00
ibuler
3383b2b535 Add terminal mode 2016-10-15 18:28:49 +08:00
ibuler
9960a6cd21 Plan create a new app: terminal 2016-10-15 17:14:56 +08:00
ibuler
0446f449e9 Add auth and permission backends 2016-10-15 16:04:54 +08:00
ibuler
a62a2178d0 Add user backend 2016-10-15 00:49:59 +08:00
ibuler
f038423ce2 Add isdangerous 2016-10-14 20:18:34 +08:00
江世峰
a3683f184e Merge branch 'master' of code.jumpserver.org:Jumpserver/jumpserver
Merge
2016-10-14 19:29:15 +08:00
江世峰
abe09e2a85 asset:update assets_list by tag 2016-10-14 19:28:58 +08:00
ibuler
3efad338eb Merge branch 'connect' 2016-10-13 14:49:04 +08:00
ibuler
29b3ef70ef Merge branch 'master' of code.jumpserver.org:Jumpserver/jumpserver 2016-10-12 19:43:43 +08:00
江世峰
73f5891f87 asset:update assets_list by tag 2016-10-12 18:57:51 +08:00
ibuler
081af2f953 Add proxy log api for create or update 2016-10-10 00:39:24 +08:00
ibuler
0c8922e30f Modify some bug 2016-10-09 19:27:49 +08:00
广宏伟
82610163cb Update README.md 2016-10-09 18:14:19 +08:00
ibuler
ba82c395f2 Move terminal to a new project 2016-10-09 15:14:41 +08:00
ibuler
0954f6d7e8 Add audits api 2016-10-09 00:12:18 +08:00
江世峰
b99b88a30f asset:update tag 2016-10-08 18:33:00 +08:00
ibuler
59727656c3 Update table desgin doc and audit log 2016-10-07 23:54:29 +08:00
江世峰
0c611b6429 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver
merage
2016-10-07 23:04:48 +08:00
江世峰
2829445f4f assets:add tag 2016-10-07 23:04:37 +08:00
ibuler
0cda4e0905 Record command history 2016-10-07 08:53:28 +08:00
ibuler
aa02c211fe Modify inital data 2016-10-02 22:16:15 +08:00
ibuler
6b6105491c Add migrations 2016-10-02 22:13:08 +08:00
ibuler
45df58114c Merge branch 'connect' 2016-10-02 21:45:44 +08:00
ibuler
a04d772501 Merge with master 2016-10-02 21:45:26 +08:00
ibuler
820d608b18 Rm teminal app 2016-10-02 21:43:22 +08:00
ibuler
b54c973d82 Update requirement 2016-10-02 21:38:27 +08:00
ibuler
0234ff0252 Pripare web terminal server 2016-10-02 17:09:27 +08:00
xiaokong1937@gmail.com
6856fad0c0 integrate the user-group list page with its api; 2016-10-02 11:09:27 +08:00
xiaokong1937@gmail.com
d40aa49d8c user bulk import through Excel and close #20 2016-10-01 20:26:43 +08:00
xiaokong1937@gmail.com
05e961f29f user-group detail: fix #15 2016-09-30 20:50:40 +08:00
江世峰
474f7e0f68 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver
merge
2016-09-30 18:26:02 +08:00
江世峰
fd52a85dbb fix #25 2016-09-30 18:25:50 +08:00
ibuler
d9866e1f38 Debug to find command 2016-09-30 00:07:55 +08:00
ibuler
0d25a8f5b7 Use thread replace process 2016-09-29 23:52:07 +08:00
ibuler
b4c6499139 Try to fix ssh server close client bug 2016-09-29 21:36:15 +08:00
xiaokong1937@gmail.com
d8143a67cd user-group-detail: user-adding frontend integration 2016-09-29 21:14:55 +08:00
ibuler
e3c620e138 Debug some bug for auth failed and exit 2016-09-29 18:35:52 +08:00
ibuler
acf51238d0 Modify ssh server bug for using public key 2016-09-29 18:01:26 +08:00
xiaoyu
e7fddf80ae user-group-detail: add users support 2016-09-29 16:41:55 +08:00
xiaokong1937@gmail.com
f9b49605e4 user-group detail page: users op 2016-09-28 21:11:43 +08:00
江世峰
0dec647116 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver
rollback user_list.html
2016-09-28 13:45:03 +08:00
江世峰
3201853cdf rollback user_list.html 2016-09-28 13:44:51 +08:00
江世峰
e83ecb1254 assets_group_forbug 2016-09-28 12:05:34 +08:00
xiaokong1937@gmail.com
2522f0d80f trivial changes: refactor the jumpserver DataTable api 2016-09-27 21:28:02 +08:00
xiaokong1937@gmail.com
70a6ddc897 fix #27 2016-09-27 20:16:46 +08:00
ibuler
b17a12662c modify change windows size 2016-09-27 00:10:14 +08:00
ibuler
be1a374b14 Modify log 2016-09-26 22:16:21 +08:00
xiaokong1937@gmail.com
49f007601f add user-list-delete support for user-group detail page 2016-09-26 21:22:48 +08:00
xiaokong1937@gmail.com
74cdd2d0f3 user list groups bulk update 2016-09-26 19:39:43 +08:00
xiaoyu
15dcc760b4 user list bulk update modal 2016-09-26 16:33:10 +08:00
xiaoyu
d2197d99c2 fix #26 2016-09-26 11:30:43 +08:00
ibuler
badd319bb4 Modify some bug and add some logging 2016-09-26 00:05:23 +08:00
ibuler
e627b14e55 finish ssh server use more class 2016-09-25 23:38:42 +08:00
ibuler
4b7419559c Update ssh_server to some class 2016-09-25 23:11:09 +08:00
ibuler
2c64b78487 Update terminal 2016-09-25 21:21:25 +08:00
ibuler
5e33c2dc6b Update ssh config 2016-09-25 20:41:56 +08:00
ibuler
ebb30424fa Use process except thread 2016-09-25 19:53:55 +08:00
ibuler
216163f436 stash 2016-09-25 11:30:02 +08:00
ibuler
d3e9c8c9c0 Replace ssh server dir 2016-09-25 00:21:32 +08:00
ibuler
cfef374454 Update ssh server 2016-09-25 00:11:31 +08:00
ibuler
0d4ca9717e Merge branch 'master' into connect 2016-09-24 22:18:07 +08:00
ibuler
7ab47916f2 add __init__.py 2016-09-24 22:12:49 +08:00
ibuler
283c53fddf Update gitignore 2016-09-24 22:11:53 +08:00
ibuler
c5c11864e0 update 2016-09-24 22:10:17 +08:00
ibuler
da56310db9 update .gitignore 2016-09-24 22:09:20 +08:00
ibuler
7935c00338 update .gitignore 2016-09-24 22:02:44 +08:00
ibuler
1620f6a311 Update ignore 2016-09-24 22:01:19 +08:00
ibuler
4925f3227a update .gitignore 2016-09-24 21:57:24 +08:00
ibuler
c158edb574 Modify ignore 2016-09-24 21:54:58 +08:00
ibuler
ab18fe466b stash 2016-09-24 21:47:10 +08:00
ibuler
88bb620af2 Modify ignore 2016-09-24 11:50:25 +08:00
ibuler
a65d5269fe Modify git ignore 2016-09-24 11:46:11 +08:00
ibuler
1f3d763490 Add requirement 2016-09-24 11:44:59 +08:00
江世峰
184ac728db Merge branch 'master' of code.simcu.com:jumpserver/jumpserver
update:add_assets-group
2016-09-23 20:23:02 +08:00
江世峰
5bf414ffb5 update add_assets-group 2016-09-23 20:22:45 +08:00
xiaoyu
22163173fe user bulk delete view 2016-09-23 16:30:59 +08:00
ibuler
de0f8c24f7 finish example 2016-09-22 23:56:27 +08:00
ibuler
f946a4bfb3 finish example 2016-09-22 23:26:44 +08:00
江世峰
18341717a1 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver
"assets-group"
2016-09-22 18:31:15 +08:00
江世峰
d2e989403f update assets-group 2016-09-22 18:31:04 +08:00
xiaoyu
af713672fb user list page bulk action 2016-09-22 16:06:46 +08:00
ibuler
db2d00f828 implement a some server 2016-09-22 00:37:13 +08:00
xiaoyu
515406c05d temp: deactive test 2016-09-21 16:43:41 +08:00
xiaoyu
61d1d9ec90 temp 2016-09-21 15:48:21 +08:00
ibuler
e020aaa368 ssh server 2016-09-21 00:43:19 +08:00
ibuler
771cf39944 ssh server 2016-09-21 00:38:17 +08:00
ibuler
c7f3aaa654 Change appname webterminal to terminal 2016-09-20 23:34:37 +08:00
ibuler
220892824c Finish some bug 2016-09-20 01:13:50 +08:00
ibuler
ce5950ca73 Merge with asset 2016-09-20 00:43:30 +08:00
ibuler
24e31a69cb finish asset 2016-09-20 00:39:33 +08:00
xiaokong1937@gmail.com
65461a09a7 user-group edit implement 2016-09-19 21:08:08 +08:00
江世峰
6c7e51041f update assets_group 2016-09-19 18:01:13 +08:00
江世峰
98757aa428 update assets_group 2016-09-19 17:25:41 +08:00
xiaoyu
9a81057d95 fix a typo 2016-09-19 15:51:28 +08:00
xiaoyu
f00da20764 user-group delete implement 2016-09-19 15:47:58 +08:00
ibuler
d323c9df88 Modify asset create 2016-09-19 00:07:52 +08:00
xiaokong1937@gmail.com
4e2a41f4cf user-group draft 2016-09-18 21:00:07 +08:00
xiaoyu
8a5a4f3362 fix #14 2016-09-18 14:28:34 +08:00
xiaoyu
8cdc4674d7 update toastr js and close #8 2016-09-18 10:32:23 +08:00
ibuler
acfe8950b8 MOdify asset create 2016-09-18 00:10:08 +08:00
ibuler
502c7e756b Modify asset 2016-09-17 23:43:41 +08:00
ibuler
7fd224e690 Merge with user-perm 2016-09-17 19:15:14 +08:00
ibuler
dc4d388d9a Merge with master 2016-09-17 18:53:11 +08:00
ibuler
df281defd8 Finish user detail asset grant .. 2016-09-17 18:51:19 +08:00
ibuler
7d3474aeea Add user permission user list 2016-09-17 15:20:33 +08:00
wangyong
343f139904 alter asset add and detail 2016-09-17 14:52:14 +08:00
wangyong
b95c1deee1 alter asset add and detail 2016-09-17 14:50:14 +08:00
ibuler
b5abb17568 Jiu zhe yang ba 2016-09-17 13:04:26 +08:00
ibuler
ab2eeb0da3 Finish user asset form 2016-09-17 01:04:52 +08:00
ibuler
e232962649 Update some template 2016-09-16 20:53:10 +08:00
wangyong
42012d7bfe merge master 2016-09-16 17:32:35 +08:00
ibuler
06b2c623cb Modify some bug 2016-09-16 17:23:47 +08:00
wangyong
792908eb35 asset add 2016-09-16 17:23:23 +08:00
ibuler
a091036744 Add user permission select 2016-09-16 16:09:11 +08:00
ibuler
d9812e2bdb Remove action from asset permission 2016-09-16 09:55:26 +08:00
ibuler
74b8ee8c10 Pre delete action 2016-09-16 09:38:07 +08:00
xiaokong1937@gmail.com
db5d04c37f fix #13 2016-09-16 08:45:29 +08:00
xiaokong1937@gmail.com
7984806b38 change user ssh reset type from private key to public key 2016-09-15 16:54:00 +08:00
ibuler
766bd3b76d Move js to jumpserver.js 2016-09-15 13:09:24 +08:00
ibuler
b2444c2aca Add fake data to init.json 2016-09-15 12:21:34 +08:00
ibuler
bb8852d57e Modify some style 2016-09-15 12:20:53 +08:00
ibuler
037d9323a4 Modify and code review 2016-09-15 11:19:36 +08:00
ibuler
f253d2ea69 Merge with master 2016-09-14 23:31:22 +08:00
ibuler
a4dc27f073 Finish permissin detail asset list and user list 2016-09-14 23:29:39 +08:00
ibuler
812df7b07b Restore settings.py 2016-09-14 16:52:09 +08:00
unknown
c237f82e51 restore settings 2016-09-14 16:10:15 +08:00
unknown
e7c20f0707 add assets manage Sweet Alert" 2016-09-14 15:51:09 +08:00
unknown
0f9bdab108 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-09-14 15:40:47 +08:00
unknown
1005fbabbd add assets manage
Sweet Alert
2016-09-14 15:38:54 +08:00
unknown
8490583d73 add assets manage
Sweet Alert
2016-09-14 15:19:27 +08:00
ibuler
5bca783e12 permission user search 2016-09-14 01:08:26 +08:00
xiaokong1937@gmail.com
6751c5a63a reset user password and ssh pk implement 2016-09-13 21:45:10 +08:00
xiaoyu
00502ce33d trivial js style changes; bugfix for patch method 2016-09-13 16:38:43 +08:00
ibuler
4c4f598552 Finish asset permission detail and add user or user group list 2016-09-13 00:37:24 +08:00
unknown
7cff5cbf61 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-09-12 15:36:13 +08:00
unknown
12831a7d21 text 2016-09-12 15:35:50 +08:00
ibuler
7b99a33a2f permission update and delete finished 2016-09-11 23:20:14 +08:00
ibuler
6d736d7309 Finish permission create and list 2016-09-11 22:45:24 +08:00
ibuler
f558ded5bb Plan delete some view 2016-09-11 20:13:56 +08:00
ibuler
324bb68667 user-pserm 2016-09-11 16:59:19 +08:00
ibuler
70cae93a4b Add user perm model and form 2016-09-11 09:50:42 +08:00
ibuler
627a5825f4 Add user perm 2016-09-10 21:08:10 +08:00
xiaokong1937@gmail.com
899233338d #8 user first login view 2016-09-10 13:20:34 +08:00
xiaokong1937@gmail.com
a7e3f9c465 #8 user first login view 2016-09-10 13:16:58 +08:00
ibuler
6069b8946b Start asset extend 2016-09-10 00:29:57 +08:00
ibuler
c58725dbc0 Finish system user view 2016-09-09 23:19:39 +08:00
ibuler
292179d41d system-user 2016-09-09 21:48:44 +08:00
ibuler
a89ae94d85 Update system user create template script 2016-09-09 00:34:23 +08:00
ibuler
4fc9274e00 Add asset system user 2016-09-09 00:09:49 +08:00
ibuler
5259dd8054 Asset form: Add some comment 2016-09-08 22:54:05 +08:00
xiaokong1937@gmail.com
d8fe59debb temp save for issue 8 2016-09-08 21:51:44 +08:00
ibuler
409fac3ef1 Merge branch 'admin-user' 2016-09-08 20:39:25 +08:00
ibuler
239dd0567f Finish admin user view 2016-09-08 20:39:06 +08:00
xiaokong1937@gmail.com
62cac20ba7 fix #9 2016-09-08 19:30:22 +08:00
ibuler
ff30435eb4 Finish adin user add 2016-09-08 18:12:53 +08:00
ibuler
5a0b119410 Stash it 2016-09-08 00:59:00 +08:00
ibuler
ccfe9b9d08 Merge branch 'admin-user' 2016-09-08 00:41:22 +08:00
ibuler
6f4a832389 Add admin user list view 2016-09-08 00:40:59 +08:00
xiaokong1937@gmail.com
8acbcb2ed2 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-09-07 21:53:33 +08:00
xiaokong1937@gmail.com
04151b9957 user group quickedit frontend and rest API 2016-09-07 21:53:27 +08:00
ibuler
dfc628a397 modify idc 2016-09-07 21:03:18 +08:00
ibuler
4db352f55b Add idc 2016-09-07 20:51:33 +08:00
ibuler
d8e6433404 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-09-07 20:06:01 +08:00
ibuler
d0ba17374e Finish asset group create 2016-09-07 20:05:42 +08:00
xiaokong1937@gmail.com
7f09b486d9 user-group edit serializer and url implement 2016-09-06 21:44:23 +08:00
ibuler
30fd51c268 Asset group detail 2016-09-06 21:39:21 +08:00
xiaokong1937@gmail.com
556fb4e09f refactor is_active trigger view and enable_otp trigger view in UserDetail page;trivial changes 2016-09-06 21:03:51 +08:00
xiaokong1937@gmail.com
a3096689b5 Merge branch 'xiaoyu' 2016-09-06 19:14:16 +08:00
wangyong
bc232c4f77 merge cmdb 2016-09-06 18:45:40 +08:00
wangyong
342e4bdee8 change some html 2016-09-06 18:43:13 +08:00
ibuler
dc01833a5b Forget to forgot 2016-09-06 16:55:57 +08:00
ibuler
170b49428c change date_added -> date_created 2016-09-06 16:50:19 +08:00
xiaoyu
c6f875c517 temp commit 2016-09-06 16:40:44 +08:00
ibuler
07dd6d1192 Reslove conflict 2016-09-06 15:56:03 +08:00
ibuler
25d9dbe93c Merge with cmdb 2016-09-06 15:09:00 +08:00
xiaoyu
8cc09f0e5a move login and logout view back to CBV 2016-09-06 15:03:37 +08:00
ibuler
02b5483d81 Update add->create edit->update and assetgrou->asset-grou etc format 2016-09-06 14:38:19 +08:00
ibuler
b8c10a0350 Add assetgroup form save action 2016-09-06 01:09:03 +08:00
ibuler
126d7fd62c Add asset group add Form m2m 2016-09-06 00:49:42 +08:00
ibuler
3c6f50b788 Modify some bug 2016-09-05 23:42:10 +08:00
ibuler
2cb6b15bc3 set textarea rows 2016-09-05 23:12:01 +08:00
ibuler
2f5b7ad654 Modify asset model 2016-09-05 22:57:43 +08:00
xiaokong1937@gmail.com
6aedfb5219 fix small template erros 2016-09-05 22:20:50 +08:00
xiaokong1937@gmail.com
397da7d676 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-09-05 21:38:37 +08:00
xiaokong1937@gmail.com
e75d33439a fix captcha not valid bug of login view; use django's default login and logout view to enhance robustness 2016-09-05 21:38:21 +08:00
ibuler
7241f7509f Update nav 2016-09-05 20:27:44 +08:00
ibuler
8827fd2d74 Modify translation 2016-09-05 20:17:45 +08:00
ibuler
6fc3bbb97d Update initial data: fixtures dir 2016-09-05 19:41:34 +08:00
ibuler
508bda37f5 Modify form datetime valid error, because form format 2016-09-05 19:37:37 +08:00
ibuler
a0ef3cfc34 Update locale dir name to zh 2016-09-05 19:17:18 +08:00
ibuler
1b9c9c48b6 Merge branch 'cmdb' 2016-09-04 21:54:17 +08:00
ibuler
22e20d29f5 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-09-04 21:50:39 +08:00
ibuler
0604f76f56 Merge branch 'cmdb' of code.simcu.com:jumpserver/jumpserver into cmdb 2016-09-04 21:47:20 +08:00
ibuler
4855e86a3f Add asset group view 2016-09-04 21:47:10 +08:00
wangyong
69349368bf cmdb merge model and url 2016-09-04 19:15:31 +08:00
wangyong
b531d9eeb2 asset add html 2016-09-04 19:12:31 +08:00
ibuler
246fcb8efa Modify run_server.py 2016-09-04 19:10:28 +08:00
ibuler
3972bd3ff3 Add asset traslation 2016-09-04 19:05:47 +08:00
ibuler
d1c96cd4b2 Merge branch 'cmdb' of code.simcu.com:jumpserver/jumpserver into cmdb 2016-09-04 18:07:19 +08:00
ibuler
154783a974 Modify some and pull from server 2016-09-04 18:07:15 +08:00
wangyong
fa07f4ee8a fix null 2016-09-04 18:06:14 +08:00
wangyong
0e8e88fac0 add admin|sys user model 2016-09-04 17:50:30 +08:00
wangyong
426c3c4062 add asset amdin|sys user model 2016-09-04 17:43:03 +08:00
ibuler
8d0334e003 Add translation 2016-09-04 17:34:48 +08:00
ibuler
0ab015abfd Asset add traslation 2016-09-04 17:15:26 +08:00
ibuler
7350e150c8 Merge branch 'master' into cmdb 2016-09-04 16:39:27 +08:00
ibuler
61f0205529 Modify users url to singular 2016-09-04 16:05:58 +08:00
ibuler
11d06b5e2b Add asset group view and url 2016-09-04 16:02:51 +08:00
ibuler
a9b5762fbc Modify api style guide info 2016-09-04 15:31:10 +08:00
广宏伟
724b1c6fd4 Add new directory logs 2016-09-04 12:37:42 +08:00
ibuler
acd98365c1 Fix translation 2016-09-04 12:31:20 +08:00
liuzheng712
32c49c080c update 2016-09-04 07:04:15 +08:00
liuzheng712
d371c0c5ae mkdirp 2016-09-04 06:55:12 +08:00
ibuler
47171174b5 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-09-04 00:52:04 +08:00
ibuler
f274684473 Add translation for support i18n 2016-09-04 00:51:36 +08:00
wangyong
d96ac56460 merge master 2016-09-03 23:01:36 +08:00
wangyong
77f3a1f146 add asset add 2016-09-03 19:05:50 +08:00
ibuler
ba3f46fbd6 i18n 2016-09-03 19:02:18 +08:00
ibuler
0b406b6988 Add captch login using 2016-09-03 14:37:01 +08:00
ibuler
6f0cfd23c1 Rm logout.html 2016-09-03 00:39:52 +08:00
ibuler
10d51ada37 Update login error message 2016-09-03 00:39:06 +08:00
lijiejie
9fa70f6cb8 create a restframework api for cmdb models 2016-09-02 22:52:30 +08:00
lijiejie
cec5a7f2c6 create the restframework url 2016-09-02 22:51:10 +08:00
lijiejie
829df26b0f create the api 2016-09-02 22:49:51 +08:00
ibuler
b8bebc9b64 Merge branch 'api' of code.simcu.com:jumpserver/jumpserver into api 2016-09-02 22:24:05 +08:00
ibuler
90ca5a8bb7 start capcha support 2016-09-02 22:23:15 +08:00
ibuler
2c11255828 Add capacha support 2016-09-02 22:21:26 +08:00
ibuler
9803dd9547 Add ico, Modify forget_password 2016-09-02 18:10:26 +08:00
ibuler
dcff84958f Add run development server script: run_server.py 2016-09-01 23:10:28 +08:00
ibuler
3a9cf6c360 Add forget password and reset password 2016-09-01 23:09:58 +08:00
ibuler
8ff872f41d Add ls config 2016-09-01 16:05:14 +08:00
ibuler
5940cec0e6 Add user and send mail 2016-09-01 01:12:02 +08:00
ibuler
5359da3ce2 Finish user login 2016-08-31 23:42:06 +08:00
ibuler
c9369db578 Add new login page 2016-08-31 20:39:25 +08:00
ibuler
d70deaf1ac Modify config-example 2016-08-31 19:48:37 +08:00
ibuler
b31f8d5867 Add user generate reset password token 2016-08-31 19:28:06 +08:00
ibuler
5350f83275 Add celery usage more 2016-08-31 16:48:12 +08:00
广宏伟
dd80b94b43 Update README.md 2016-08-31 16:43:44 +08:00
广宏伟
4cbadbd941 Update README.rst 2016-08-31 16:43:18 +08:00
广宏伟
e61341df79 Update README.md to README.rst 2016-08-31 16:33:05 +08:00
ibuler
f7ab26a5da Add celery broker 2016-08-31 15:54:04 +08:00
ibuler
0d3bde1191 User add confirmed 2016-08-31 12:14:25 +08:00
ibuler
c143735393 Add ssh-key-gen function 2016-08-31 01:00:20 +08:00
ibuler
43af5383e3 Add model user method: get_token set_token 2016-08-30 20:30:47 +08:00
ibuler
ffed46175d update .gitignore 2016-08-30 17:26:33 +08:00
ibuler
31a39be9ea Resolve conflicts 2016-08-30 17:22:06 +08:00
ibuler
2022ca8e10 Add test code 2016-08-30 17:20:39 +08:00
wangyong
d0d433db1a add asset_list 2016-08-30 13:50:30 +08:00
yumaojun03
e8d8f7c406 ops: ansible_api add ansible api 2.0 adhoc runner 2016-08-30 13:00:06 +08:00
yumaojun03
f6b2abb1fb add ansible 2.0 2016-08-30 01:16:14 +08:00
ibuler
011c125564 Modify user active api And Add Token authorization 2016-08-30 00:10:27 +08:00
ibuler
1a9f90a08e Modify api 2016-08-29 21:09:32 +08:00
ibuler
3eb4897bd3 Merge branch 'api' of code.simcu.com:jumpserver/jumpserver into api 2016-08-29 19:27:23 +08:00
ibuler
3c9dbaf860 Fix some bug 2016-08-28 23:58:22 +08:00
ibuler
d918d5b466 Add Logger setting . 2016-08-26 16:56:50 +08:00
ibuler
d95ffdfbf7 Test permmision 2016-08-26 00:51:05 +08:00
yumaojun03
363ddb70e2 add celery support (not use django-celery) 2016-08-25 19:52:03 +08:00
ibuler
bb76f6c652 Add api authentication 2016-08-25 19:29:59 +08:00
ibuler
641e998504 Update context name path1, path2 => app, action 2016-08-25 13:56:49 +08:00
ibuler
0a9e4a5e85 Modify urls.conf: Merge to single 2016-08-25 13:28:02 +08:00
ibuler
8aa92bb688 Add api: UserApi And UserGroupApi 2016-08-24 19:42:16 +08:00
ibuler
1d5faa3101 Delete Model: Role 2016-08-24 17:14:21 +08:00
ibuler
b97b34961c Modify api: complete some setting 2016-08-24 12:29:19 +08:00
liuzheng712
be92ac58ae merge 2016-08-24 06:48:50 +08:00
liuzheng712
1df0def9ea pip freeze 2016-08-24 06:47:14 +08:00
ibuler
a43ac90b21 Modify CRLF to LF 2016-08-24 00:13:58 +08:00
ibuler
bbecbc8578 Merge with webternimal 2016-08-24 00:12:46 +08:00
ibuler
6458231946 Add api file 2016-08-24 00:11:13 +08:00
yumaojun03
97a2e8bb50 test add celery 2016-08-23 23:51:39 +08:00
liuzheng712
400d744938 add api redirect 2016-08-23 23:29:33 +08:00
ibuler
9a6d20b6ec Modify requirement: add some module 2016-08-23 23:00:55 +08:00
liuzheng712
7cebc4efe8 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-08-23 22:35:00 +08:00
liuzheng712
91f0800e26 add webterminal 2016-08-23 22:34:52 +08:00
ibuler
a99a6b6946 Split tests file in tests module 2016-08-23 22:19:39 +08:00
ibuler
c37dea2079 Add user add view Test Case 2016-08-23 19:36:15 +08:00
ibuler
b55b516fc3 Update foot_js.html add active 2016-08-23 17:34:52 +08:00
ibuler
1f3c0d004f Change update batch, add _list_base.html 2016-08-23 17:14:08 +08:00
ibuler
3c3fda8064 Change chosen To select2 lib 2016-08-23 14:44:06 +08:00
ibuler
ae9bbb40fd Add flash message template 2016-08-23 12:18:19 +08:00
ibuler
8e5e788bcd Test case added 2016-08-23 00:39:07 +08:00
liuzheng712
c50cdd2976 add webterminal 2016-08-22 23:53:14 +08:00
ibuler
f45690b34f Add test case 2016-08-22 19:53:01 +08:00
ibuler
f0b0e41d33 Update user edit 2016-08-21 22:37:55 +08:00
ibuler
308aa2eca2 Modify README.md 2016-08-21 22:26:50 +08:00
wangyong
3771b2ff70 add asset detail and list 2016-08-21 22:12:17 +08:00
ibuler
8b0f31c43a modify list, edit url error 2016-08-21 21:32:20 +08:00
ibuler
8ba7b078fd Finish expaire date 2016-08-21 21:31:25 +08:00
ibuler
57f0b04387 Modify project statucure guide and init data 2016-08-21 20:59:39 +08:00
ibuler
24d7cb3d5d add init data dir fixture 2016-08-21 15:03:57 +08:00
ibuler
85cf2169d4 Modify readme 2016-08-21 13:59:44 +08:00
ibuler
0427d406b9 Add init data file 2016-08-21 01:16:30 +08:00
ibuler
96dd2f5c85 add config 2016-08-20 20:35:58 +08:00
ibuler
e355c7b8ef Modify pagination and Role model 2016-08-20 18:33:18 +08:00
xRain
7789c8d13d 增加了缺失的必需组件 2016-08-20 09:44:40 +08:00
ibuler
6e46a17d98 Useradd group change 2016-08-20 00:42:50 +08:00
ibuler
e48f36397e Modify url 2016-08-20 00:18:44 +08:00
ibuler
cf15b7eaff Add UserGroup some View 2016-08-19 01:39:08 +08:00
ibuler
651e89994e modify list and sort 2016-08-18 22:29:35 +08:00
ibuler
342298ad3e reslove conflict 2016-08-18 14:43:10 +08:00
ibuler
a76191ffdc Change view detail template 2016-08-18 10:20:37 +08:00
ibuler
279987925a Modify user detail of usergroup 2016-08-18 00:47:34 +08:00
ibuler
824b1c7f6f update user update view 2016-08-17 22:17:16 +08:00
ibuler
bcae7beae6 upload avatar 2016-08-17 00:36:54 +08:00
ibuler
9353022627 add context 2016-08-17 00:23:52 +08:00
ibuler
35abf16f7d Modify panel color 2016-08-17 00:22:33 +08:00
ibuler
c14eb42186 reslove conflict add user detail template 2016-08-17 00:14:56 +08:00
ibuler
98d6043f2d merged 2016-08-16 23:25:30 +08:00
ibuler
7a8d4a3a59 Add delete view 2016-08-16 22:13:06 +08:00
ibuler
3bf0d4aabb Add common app
common app used as write public api or templatetags

modify user list view and user edit view
2016-08-16 00:09:48 +08:00
ibuler
edd60cad11 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-08-15 22:54:56 +08:00
广宏伟
e3223f745a app users
Modify user list view
Modify user add view
2016-08-15 21:10:30 +08:00
wangyong
fcd39370ed add asset some cbv 2016-08-14 22:10:10 +08:00
广宏伟
86ffcc973c Add user template 2016-08-14 19:18:41 +08:00
ibuler
9493fb07cb Add user list view 2016-08-14 17:21:04 +08:00
ibuler
9303415b89 modify some issues 2016-08-14 00:40:21 +08:00
ibuler
8b8e391feb Modify project structure design 2016-08-13 22:02:05 +08:00
ibuler
234684c875 Rename dir name dashboard to apps
It's may be well
2016-08-13 21:59:08 +08:00
ibuler
25f1c9ccf3 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-08-13 16:17:42 +08:00
ibuler
1dd17b1814 Add django CBV interitance 2016-08-13 16:17:30 +08:00
广宏伟
089b54986a Update README.md 2016-08-13 01:16:52 +08:00
ibuler
224797e5e7 Merge branch 'master' of code.simcu.com:jumpserver/jumpserver 2016-08-13 01:11:58 +08:00
ibuler
346fbcc286 add logs,install dir, modify table_design 2016-08-13 01:11:46 +08:00
广宏伟
1ee53c6877 Update README.md 2016-08-13 01:09:33 +08:00
广宏伟
7f4d737503 Update README.md 2016-08-13 01:03:51 +08:00
ibuler
551d3df892 Finish table design 2016-08-13 00:18:34 +08:00
ibuler
b2bfdb097b Modify table design 2016-08-12 19:34:26 +08:00
ibuler
40572cdc00 Modify table design 2016-08-11 15:49:24 +08:00
ibuler
46f0d17da7 update table_design.xml 2016-08-10 23:54:31 +08:00
ibuler
bc474c6c06 Add table design 2016-08-10 23:03:01 +08:00
ibuler
31a41000bf 添加 user 表结构,简单思考 2016-08-10 01:30:19 +08:00
ibuler
a5621a4178 修改README.md, 采用绝对地址 2016-08-09 19:43:20 +08:00
ibuler
17869dc5d8 修改README.md, 采用相对地址 2016-08-09 19:41:58 +08:00
ibuler
69c1639e46 修改 README.md 采用相对路径 2016-08-09 19:39:18 +08:00
ibuler
ffcd669898 修改readme显示,采用相对路径 2016-08-09 19:37:55 +08:00
ibuler
8121e48825 添加 api设计风格文档
详细描述了设计原则和遵守风格, 还不够完善,会随着开发进程逐渐完善它
2016-08-09 19:29:52 +08:00
ibuler
aed18698a3 修改python编码风格指导
添加api风格约定, python风格添加了详细说明,更改project的骨架说明
2016-08-09 18:36:13 +08:00
ibuler
e1d5cbd06e 添加 utils和api样例文件 2016-08-09 17:27:37 +08:00
ibuler
964247b1f2 修改 nav导航显示 2016-08-09 16:12:11 +08:00
ibuler
ef604615ec 修改项目骨架,添加前端框架 base.html 2016-08-09 14:42:21 +08:00
ibuler
bd3735e755 Change some word 2016-08-09 01:10:23 +08:00
ibuler
7bb6890370 Change content of README.md 2016-08-09 01:05:57 +08:00
ibuler
734f6564fa Change project_structure content to a new file 2016-08-09 00:57:31 +08:00
ibuler
b5c159c967 Init project structure 2016-08-09 00:43:11 +08:00
ibuler
ba215335bf Add .gitignore 2016-08-09 00:42:33 +08:00
ibuler
da4bd937a8 Merge branch 'dev' 2016-07-26 18:43:26 +08:00
ibuler
b5b14373d0 Merge branch 'master' of github.com:jumpserver/jumpserver 2016-07-26 18:42:40 +08:00
老广
270499a4fd 修改删除系统用户的交互 (#276)
* fix(api) 修改建立目录的bug

使用bash代替python完成建立777目录的功能

* fix passwd input

* fix(mkdir) 修改mkdirs策略

修改原来导致的bug

* fix passwd input (#232)

修复记录敏感密码bug

* fix passwd input

* fix passwd input

* fix passwd input

* fix(connect) 输入role id时,输入了role名称异常

抓取后并处理

* Update perm_role_edit.html

* fix role delete
2016-07-26 18:41:58 +08:00
ibuler
26ad623d0e fix role delete 2016-07-26 11:59:04 +08:00
ibuler
f8eedc8650 Merge branch 'dev' 2016-07-26 10:20:39 +08:00
ibuler
89e32b327d Merge branch 'master' of github.com:jumpserver/jumpserver 2016-07-26 10:20:20 +08:00
假想控
27223a1883 Update next.py
修改安装成功访问web提示信息
2016-07-23 18:14:26 +08:00
老广
e0ae7eeee7 Update user_api.py 2016-07-12 17:08:26 +08:00
老广
b5fefb4687 Update user_api.py 2016-07-12 17:00:20 +08:00
chnliyong
ecfb2f3d40 fix reset password bug (#274)
感谢PR
2016-07-08 03:22:38 -05:00
老广
1614dd5a4d Update README.md 2016-06-20 10:01:35 +08:00
liuzheng
cf3e89c374 Update run_server.py
because if someone need run jumpserver at 127.0.0.1 need this fix
2016-06-15 22:06:26 +08:00
老广
0f0908d3f3 Update jumpserver.conf 2016-06-14 17:32:28 +08:00
ibuler
31c3def1a8 Update group_add.html 2016-06-07 17:34:08 +08:00
ibuler
f75003461a Update settings.py 2016-06-07 16:39:35 +08:00
ibuler
49504e46ee Update docker-compose.yaml 2016-06-07 16:37:06 +08:00
ibuler
699bdd1348 Update config_tmpl.conf 2016-06-07 16:35:48 +08:00
ibuler
e608fbaad5 Update settings.py 2016-06-07 16:17:10 +08:00
ibuler
6a7d105484 Update jumpserver.conf 2016-06-07 16:12:38 +08:00
xRain
6acda5fcd1 add docker support and update the locally 2016-06-07 11:51:16 +08:00
xRain
57ba8ed2fb add docker support 2016-06-07 11:49:59 +08:00
kikiyou
d6c4017a2e 使示例可以正确运行 (#237)
为了安全pattern=空,后示例代码无法使用,运行示例时加上pattern='*',使示例可以返回正确的结果
2016-06-06 21:55:54 -05:00
lrqrun
b7be5d14e0 User object is not the user, must update at the user (#254)
修改信息保存后数据不是最新的而是之前的数据,因为在object的惰性查询不会获取到最新的数据,因此需要在缓存的对象基础上修改save后commit到数据库。
2016-06-06 21:55:28 -05:00
lrqrun
f130a78f0a users_selected keep new (#255)
用户组保存后数据显示的问题,在已选用户处显示选择的数据
2016-06-06 21:54:11 -05:00
__YoYO
a077053b68 Dev (#250)
* Update perm_role_edit.html
2016-06-06 21:52:41 -05:00
Kallen Ding
c93c8de7fe Replace os.makedirs to mkdir. (#251)
解决Tty Logs 日志跨天后目录权限不对的问题
2016-06-06 21:50:38 -05:00
ibuler
3176156639 Update connect.py 2016-06-03 10:03:12 +08:00
ibuler
7072d16f00 Update install.py 2016-05-31 19:25:10 +08:00
ibuler
f2dda35f28 Update footer.html 2016-05-19 17:47:50 +08:00
zheng
0cc04ee20d Group edit (#241)
* 修复主机组编辑时回车导致主机丢失问题

在主机组编辑页面,如果直接执行回车会导致主机组中主机信息丢失。
本修复方法是关闭回车提交

* 编辑主机组在移除过滤保存时数据会丢失

现象:在反向移除选择的主机时,用过滤框搜索移除主机此时保存的数据是当前过滤显示的数据
后果:会造成原有主机组数据丢失
修复:在保存之前触发一次空值搜索
2016-05-18 05:14:18 -05:00
ibuler
7531a3ada7 修复编辑系统用户,用户名jsbug (#240)
* Update perm_role_edit.html
2016-05-18 04:08:12 -05:00
ibuler
08717d196f Update perm_role_edit.html 2016-05-18 17:00:35 +08:00
ibuler
a1859676e4 fix(connect) 输入role id时,输入了role名称异常
抓取后并处理
2016-05-11 19:13:38 +08:00
ibuler
e4a54ddbf8 Merge branch 'master' into dev 2016-05-11 19:10:59 +08:00
ibuler
5b9a9779c8 Merge branch 'master' of github.com:jumpserver/jumpserver 2016-05-11 19:10:45 +08:00
ibuler
32ab8a1646 完美修复vim等交互式命令记录 (#236)
* fix(api) 修改建立目录的bug

使用bash代替python完成建立777目录的功能

* fix passwd input

* fix(mkdir) 修改mkdirs策略

修改原来导致的bug

* fix passwd input (#232)

修复记录敏感密码bug

* fix passwd input

* fix passwd input

* fix passwd input
2016-05-11 18:48:38 +08:00
kelianchun
f0e943ebcc Merge pull request #235 from jumpserver/fix_passwd_input
fix passwd input
2016-05-11 18:29:21 +08:00
kelianchun_miller
c0e91896df fix passwd input 2016-05-11 18:27:26 +08:00
ibuler
d60562a034 修复交互式记录密码bug,merge to master (#234)
* fix(api) 修改建立目录的bug

使用bash代替python完成建立777目录的功能

* fix passwd input

* fix(mkdir) 修改mkdirs策略

修改原来导致的bug

* fix passwd input (#232)

修复记录敏感密码bug

* fix passwd input

* fix passwd input
2016-05-11 17:44:22 +08:00
ibuler
93e08a6e29 修复创建tty日志文件失败, 请修改目录 bug (#231)
* fix(api) 修改建立目录的bug

使用bash代替python完成建立777目录的功能

* fix passwd input

* fix(mkdir) 修改mkdirs策略

修改原来导致的bug

* fix passwd input (#232)

修复记录敏感密码bug

* fix passwd input

* fix passwd input
2016-05-11 17:41:46 +08:00
ibuler
0f09172ed0 conflict reslove 2016-05-11 17:38:38 +08:00
ibuler
948763443e Merge branch 'fix_passwd_input' of github.com:jumpserver/jumpserver into fix_passwd_input 2016-05-11 17:21:41 +08:00
kelianchun_miller
3ef3b452e2 fix passwd input 2016-05-11 17:21:15 +08:00
ibuler
39ebdb2f61 Merge branch 'fix_passwd_input' of github.com:jumpserver/jumpserver into fix_passwd_input 2016-05-11 17:20:47 +08:00
kelianchun_miller
dff50305de fix passwd input 2016-05-11 17:18:40 +08:00
ibuler
f71c8551e8 fix passwd input (#232)
修复记录敏感密码bug
2016-05-11 11:31:53 +08:00
ibuler
d63d4eb019 Merge branch 'dev' into fix_passwd_input 2016-05-11 11:25:43 +08:00
zheng
d66ba9d6c6 修复主机组编辑时回车导致主机丢失问题 (#230)
在主机组编辑页面,如果直接执行回车会导致主机组中主机信息丢失。
本修复方法是关闭回车提交
2016-05-11 11:22:08 +08:00
ibuler
8526437c88 fix(mkdir) 修改mkdirs策略
修改原来导致的bug
2016-05-11 11:19:32 +08:00
kelianchun_miller
987b1c2c36 fix passwd input 2016-05-11 11:10:48 +08:00
ibuler
18e159350b fix(api) 修改建立目录的bug
使用bash代替python完成建立777目录的功能
2016-05-11 11:10:02 +08:00
ibuler
1338d25b4e fix bug 2016-05-10 13:55:06 +08:00
ibuler
f994c4d1da fix(connect.py) 修复max引起的异常
已经修复
2016-05-10 13:48:55 +08:00
ibuler
5fab276c26 fix(jperm) fix jperm role detail list.
* 1. Add a window to list pushed error asset
* 2. Fix old bug for pagninator
2016-05-10 12:19:54 +08:00
ibuler
9f171da570 修复cli 端资产列表显示 (#226)
* modify(jperm) 授权列表模糊搜索

修改授权规则搜索为模糊搜索

* fix(cli nav align) Max Hostname length 30, else will be truncate.
2016-05-10 10:11:32 +08:00
ibuler
fed00d04a6 fix(cli nav align) Max Hostname length 30, else will be truncate. 2016-05-09 20:19:01 +08:00
ibuler
ecfaf9f02d modify(jperm) 授权列表模糊搜索 (#225)
修改授权规则搜索为模糊搜索
2016-05-09 18:54:33 +08:00
ibuler
d05e9d0b45 modify(jperm) 授权列表模糊搜索
修改授权规则搜索为模糊搜索
2016-05-09 18:53:04 +08:00
ibuler
d4385c7e43 Merge branch 'master' into dev 2016-04-28 15:56:22 +08:00
ibuler
04fc9962ff Merge branch 'dev' 2016-04-28 15:55:08 +08:00
ibuler
2fd68845ce Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-04-28 15:54:33 +08:00
yumaojun03
bd69339e22 Bug fix hostname (#216)
* fix (jasset):   修复资产hostname过长和密码过长引起的bug

1. 修改password字段的长度,对称加密过后的字符串会变长,所有设置得比较大(256)
2. 添加check hostname 和 password的 长度校验

* fix (jumpserver/jasset):   修复setting时,秘密过长问题。

1. 修改password字段的长度,对称加密过后的字符串会变长,所有设置得比较大(256)
2. 后端修复views秘密超过30位不保存
3.前段使用js限制秘密长多不能超过30位

* fix (jumpserver/jasset):   setting and asset hostname password  too long.

1. 添加setting password字段长度验证
2. 添加资产主机名和密码长度验证

* fix (jumpserver/jasset):   setting and asset hostname password  too long.

1. 修正setting时的 输入密码的提示错误.
2016-04-28 15:44:48 +08:00
liuzheng
c6404f7ed6 Static bug (#208)
* 紧急修复下载文件后静态文件404问题

* 紧急修复监控白屏问题

* 紧急修复下载文件后静态文件404问题

* 紧急修复下载文件后静态文件404问题

* 修复zip包为空问题
2016-04-24 20:42:02 +08:00
huangguozhen
6ce948366d Update base.html (#213)
fix(frontend): use webkit default in multi kernel browsers
2016-04-23 10:35:28 +08:00
ibuler
9e78fd3651 Merge master to dev (#212)
* Update install.py

修改centos7支持

* Update install.py

* Support resize web terminal size

Support resize web terminal size.

Change new windows to a new tab.
May be more hommization

* Static bug (#204)

* 紧急修复下载文件后静态文件404问题

* 紧急修复监控白屏问题

* bugfix(upload web) When download file, static file will unreachable.

Didn't change dir

fixed

* bugfix(upload web) When download file, static file will unreachable. (#206) (#207)

* Update install.py

修改centos7支持

* Update install.py

* Support resize web terminal size

Support resize web terminal size.

Change new windows to a new tab.
May be more hommization

* Static bug (#204)

* 紧急修复下载文件后静态文件404问题

* 紧急修复监控白屏问题

* bugfix(upload web) When download file, static file will unreachable.

Didn't change dir

fixed

* fix bug index out of range (#210)
2016-04-22 11:51:36 +08:00
kelianchun
5afd135967 fix bug index out of range (#210) 2016-04-22 11:49:50 +08:00
ibuler
d5aa9324fa Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-04-21 18:12:58 +08:00
ibuler
9096a6e5b8 bugfix(upload web) When download file, static file will unreachable. (#206) (#207)
* Update install.py

修改centos7支持

* Update install.py

* Support resize web terminal size

Support resize web terminal size.

Change new windows to a new tab.
May be more hommization

* Static bug (#204)

* 紧急修复下载文件后静态文件404问题

* 紧急修复监控白屏问题

* bugfix(upload web) When download file, static file will unreachable.

Didn't change dir

fixed
2016-04-20 15:21:55 +08:00
ibuler
cb58012a82 bugfix(upload web) When download file, static file will unreachable. (#206)
* Update install.py

修改centos7支持

* Update install.py

* Support resize web terminal size

Support resize web terminal size.

Change new windows to a new tab.
May be more hommization

* Static bug (#204)

* 紧急修复下载文件后静态文件404问题

* 紧急修复监控白屏问题

* bugfix(upload web) When download file, static file will unreachable.

Didn't change dir

fixed
2016-04-20 15:20:11 +08:00
ibuler
58bb3cc84f Merge branch 'dev'
fix download error

static file lost
2016-04-20 15:17:04 +08:00
ibuler
c2ff05201a Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-04-20 14:44:06 +08:00
yumaojun03
9be13cf08f fix (jperm): 修复密码添加和更新 role时 密码过长引起的bug (#202)
1. 修改password字段的长度,对称加密过后的字符串会变长,所有设置得比较大(512)
2. 修改后端检查密码长度,并触发异常。
2016-04-20 14:31:52 +08:00
ibuler
eb4ec47f7a bugfix(upload web) When download file, static file will unreachable.
Didn't change dir

fixed
2016-04-20 14:29:11 +08:00
liuzheng
e2eb9b72f8 Static bug (#204)
* 紧急修复下载文件后静态文件404问题

* 紧急修复监控白屏问题
2016-04-20 13:08:26 +08:00
ibuler
c9ff235089 fix(connect) input exact ip for connect
modify search strategy

if some ip match pass
2016-04-16 16:27:15 +08:00
ibuler
9af809a4f0 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-04-12 11:12:32 +08:00
Astraeux
288a42663a TTY nav sort by ip / hostname / none (#198)
* TTY nav sort by ip / hostname / none

* add newline at end of file
2016-04-12 11:11:19 +08:00
liuzheng
cca15d4211 Support resize web terminal size
Support resize web terminal size.

Change new windows to a new tab.
May be more hommization
2016-04-07 15:45:48 +08:00
jiaxiangkong
fe2081b407 Update install.py 2016-04-07 15:07:03 +08:00
ibuler
fa323d4987 Update install.py
修改centos7支持
2016-04-07 11:56:00 +08:00
ibuler
eeef4a2f95 Merge branch 'windowResize' of github.com:jumpserver/jumpserver into windowResize 2016-04-06 13:04:47 +08:00
liuzheng712
2e49f51093 update 2016-04-06 12:58:00 +08:00
ibuler
0481e83ec4 Merge branch 'dev' into windowResize 2016-04-06 12:57:54 +08:00
liuzheng712
ff8b5bd6c0 默认terminal100x35 2016-04-06 10:26:30 +08:00
liuzheng712
aabab653d3 默认terminal大小100x35 2016-04-06 10:24:18 +08:00
ibuler
efe0b3acc0 Fix nav info and delete user key when delete a user
Fix nav info and delete user key when delete a user

reviewd by ibuler <ibuler@qq.com>
2016-04-05 23:47:27 +08:00
ibuler
35cc966132 change(info) Modify some nav info
May be clearly.
2016-04-05 23:44:01 +08:00
ibuler
777997202b patch again with 1f09a40c77
print => debug
2016-04-05 22:37:55 +08:00
ibuler
1f09a40c77 fix(user manage and connect first login)
When delete a user, but didn't delete the user sysuser key. When create
a user with same username, error occur.

When user login tty, and type a num first, it will search a host, but
login the asset with the id.

fixed
2016-04-05 22:34:37 +08:00
ibuler
d20fecadac Merge branch 'dev' 2016-04-05 16:53:06 +08:00
ibuler
fa430bf104 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-04-05 16:52:44 +08:00
ibuler
8bb66ac254 fix(install.py) delete old pycrypto module
fixed
2016-04-05 16:51:58 +08:00
liuzheng712
6518aa3670 bugfix 2016-04-05 13:05:07 +08:00
liuzheng712
c76d9ebd88 bugfix 2016-04-05 12:56:37 +08:00
liuzheng712
7f4d3ffdbc bug_fix 2016-04-05 12:54:37 +08:00
liuzheng712
b908fdafc6 udpate 2016-04-05 12:50:09 +08:00
liuzheng712
ef59cff44b bug_fix 2016-04-05 12:42:44 +08:00
ibuler
f511802db5 fix asset group judge
reviewed by: ibuler <ibuler@qq.com>
2016-04-05 11:22:31 +08:00
ibuler
30c74b8427 Merge pull request #192 from jumpserver/group_judge
new feature (connect) Ignore case in searching
2016-04-05 11:19:55 +08:00
ibuler
2dd16b91ec Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-04-05 11:18:54 +08:00
liuzheng712
bb7a3ea053 Merge branch 'master' of github.com:jumpserver/jumpserver 2016-04-05 10:53:47 +08:00
liuzheng712
0499a7265a 手动修改窗口大小问题 2016-04-05 10:53:35 +08:00
ibuler
1959c685b9 new feature (connect) Ignore case in searching
finshed
2016-04-01 17:52:47 +08:00
ibuler
cd80fbcdbb Merge pull request #190 from jumpserver/dev
Dev
2016-04-01 17:24:45 +08:00
ibuler
5814b833ed Merge pull request #189 from jumpserver/webexec_log
Webexec log
2016-04-01 16:44:35 +08:00
ibuler
cda0b9c90a fix(web exec) Web execute command log didn't get the real ip if behind the lb proxy.
fixed
2016-04-01 16:42:01 +08:00
ibuler
609bba569e fix(web exec) Web execute command log didn't get the real ip if behind the lb proxy.
fixed
2016-04-01 16:40:53 +08:00
ibuler
77c7f8fb54 fix(web exec) Web execute command log didn't get the real ip if behind the lb proxy.
fixed
2016-04-01 16:38:37 +08:00
ibuler
f65290ef38 Merge pull request #188 from jumpserver/dev
新增功能
2016-04-01 13:49:28 +08:00
ibuler
de594aebd5 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-04-01 12:12:34 +08:00
ibuler
2be81c0322 fix(connect) delete debug
fixed
2016-04-01 12:11:31 +08:00
ibuler
e902fccd39 Merge pull request #187 from jumpserver/search_sort
feat (sort search) 对搜索结果排序
2016-04-01 11:54:28 +08:00
ibuler
61d162312f Merge pull request #185 from Astraeux/support_amazon_linux
支持 Amazon Linux
2016-04-01 11:53:55 +08:00
ibuler
30a3cd2911 feat (sort search) 对搜索结果排序
tty登陆连接,搜索时对结果进行排序

finished
2016-04-01 11:50:35 +08:00
ibuler
2dfe9337a2 Merge pull request #186 from jumpserver/conn_search
fix(connect) 增加模糊搜索
2016-03-31 23:50:37 +08:00
ibuler
c188696328 fix(connect) 增加模糊搜索
之前只是输入id登陆,增加了模糊搜索登陆

如果搜索唯一则登陆
2016-03-31 23:45:01 +08:00
Astraeux
f8fac06e1b 支持 Amazon Linux 2016-03-31 15:14:41 +08:00
ibuler
edad26e05b Merge pull request #183 from jumpserver/connect_slow
fix(connect) 修复paramiko连接速度特么慢问题
2016-03-31 00:16:18 +08:00
ibuler
6c8117045f fix(connect) 修复paramiko连接速度特么慢问题
导致的原因是 pycrypto库有问题

fixed
2016-03-31 00:14:46 +08:00
ibuler
b573170d69 Merge pull request #182 from jumpserver/web_width
fix(web terminal) 修改web terminal初始窗口大小
2016-03-30 22:25:35 +08:00
ibuler
1d14f08541 fix(web terminal) 修改web terminal初始窗口大小
代码缺陷,没有复用
2016-03-30 22:22:43 +08:00
ibuler
489d796d7b Merge pull request #180 from jumpserver/bugfix
修复日志回放问题
2016-03-29 23:52:19 +08:00
liuzheng712
1efede4de8 bugfix 2016-03-29 21:37:56 +08:00
liuzheng712
a1187757bc bugfix 2016-03-29 21:22:18 +08:00
liuzheng712
263ff1ee08 bugfix 2016-03-29 21:18:04 +08:00
liuzheng712
2f2289a863 bugfix 2016-03-29 21:16:30 +08:00
liuzheng712
e07305ef46 bugfix 2016-03-29 21:06:46 +08:00
liuzheng712
1c61ed6a8b bugfix 2016-03-29 21:05:29 +08:00
liuzheng712
cf1da2a420 bugfix 2016-03-29 20:56:19 +08:00
liuzheng712
7de03c0fc7 Merge branch 'master' of github.com:jumpserver/jumpserver 2016-03-29 20:44:45 +08:00
liuzheng712
9c38f39e5b 紧急修复监控白屏问题 2016-03-29 17:20:05 +08:00
ibuler
0937e64c2e Merge pull request #178 from jumpserver/dev
Fix a bug for get_log function 

hot fix
2016-03-29 17:18:46 +08:00
ibuler
5a6e0283dd Merge branch 'master' into dev 2016-03-29 17:17:54 +08:00
ibuler
5489797900 Merge branch 'dev' 2016-03-29 17:17:03 +08:00
liuzheng712
6e48fe6357 紧急修复监控白屏问题 2016-03-29 17:16:26 +08:00
ibuler
485b45675d Merge pull request #177 from jumpserver/fixed_log
fix(log) fix load_full_log function bug
2016-03-29 17:14:15 +08:00
ibuler
d31f882f1a fix(log) fix load_full_log function bug
fixed
2016-03-29 17:11:56 +08:00
ibuler
209c078614 Merge pull request #176 from jumpserver/merge_master
Merge with master
2016-03-29 15:39:46 +08:00
ibuler
d2b4594bc2 Merge branch 'master' into dev 2016-03-29 15:38:28 +08:00
ibuler
6fcfb385cd Update README.md 2016-03-29 14:07:44 +08:00
ibuler
b12b83cbb5 Update requirements.txt 2016-03-29 14:07:14 +08:00
ibuler
26804b4093 Merge pull request #174 from jumpserver/dev
Release 0.3.1 version, Fix most bugs
2016-03-29 11:33:05 +08:00
ibuler
8ebcd47599 Merge pull request #173 from jumpserver/version_num
change(version num) change jumpserver version
2016-03-28 23:38:42 +08:00
ibuler
d810a082c5 change(version num) change jumpserver version
from 0.3.0 -> 0.3.1
2016-03-28 23:37:32 +08:00
ibuler
2f9255a46f Merge pull request #172 from jumpserver/web_log
fix(web terminal and log kill) fix close web terminal when not init finished
2016-03-28 23:09:37 +08:00
ibuler
5d0171d5b7 fix(web terminal and log kill) fix close web terminal when not init finished
when web terminal not init complete, you close the window, online log you will see the log and cann't kill it

catch a except fix it
2016-03-28 23:04:30 +08:00
ibuler
c5382c88a2 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-03-28 22:59:35 +08:00
ibuler
98f9e632ac Merge pull request #170 from jumpserver/TermLogRecorder
Term log recorder, 需要数据库增加filename字段
2016-03-28 22:59:06 +08:00
ibuler
f912869de6 fix(web monitor) 修改监控特殊编码卡住
编码字符,强制utf-8
2016-03-28 22:00:48 +08:00
liuzheng712
8cd6d23ff2 update 2016-03-28 20:24:02 +08:00
liuzheng712
f3d863ea45 filename 2016-03-28 20:19:49 +08:00
liuzheng712
958909551d bug_fix 2016-03-28 20:09:51 +08:00
liuzheng712
b132a0c0b5 use_old_way 2016-03-28 20:06:05 +08:00
ibuler
6e7e4d4742 Merge pull request #169 from jumpserver/new-line-
New line
2016-03-28 19:16:48 +08:00
ibuler
c95c76d0e0 change(web terminal) 修复web terminal遇到-换行
添加css

	white-space: nowrap;
        display: inline-block;

之前通过修改字体解决
2016-03-28 19:14:45 +08:00
ibuler
8735af4cbb fix(monitor) 修复监控-换行
修复实时监控-导致的换行,添加css

  .terminal {
      white-space: nowrap;
      display: inline-block;
  }
2016-03-28 19:11:56 +08:00
liuzheng712
edfef5822f bug fix 2016-03-27 22:58:59 +08:00
liuzheng712
ebef54ca44 Merge branch 'TermLogRecorder' of github.com:jumpserver/jumpserver into TermLogRecorder 2016-03-27 22:30:04 +08:00
liuzheng712
c937abe098 bugfix 2016-03-27 22:29:39 +08:00
liuzheng712
587c9b2c3f bugfix 2016-03-27 22:20:20 +08:00
kelianchun
74ac1dc06b Merge pull request #167 from kelianchun/TermLogRecorder
connect.py use TermLog
2016-03-27 22:00:59 +08:00
kelianchun_miller
0707b68796 connect.py use TermLog 2016-03-27 22:00:00 +08:00
liuzheng712
445a83f78a remove this log in loglist 2016-03-27 12:17:02 +08:00
liuzheng712
bc1d89da89 here I didn't use int to record the dict , changed 2016-03-27 11:13:15 +08:00
liuzheng712
dc5751951e disuse pyinotify, use TermLogRecord to record the log and monitor 2016-03-27 11:11:50 +08:00
ibuler
3ca6629175 Merge pull request #166 from jumpserver/font_size
change(font) 修改使用websocket的页面字体,增加监控size
2016-03-26 11:42:12 +08:00
ibuler
1e1aa67b3e change(font) 修改使用websocket的页面字体,增加监控size
增加 "Microsoft Yahei"
2016-03-26 11:39:49 +08:00
kelianchun
3dfd9cd512 Merge pull request #165 from kelianchun/dev
pull issue #120  remove ps1
2016-03-26 08:50:21 +08:00
kelianchun_miller
6a51bd1a1c pull issue #120 remove ps1 2016-03-26 00:01:48 +08:00
liuzheng712
5e329f51a4 Merge branch 'dev' of github.com:jumpserver/jumpserver into TermLogRecorder 2016-03-25 23:58:04 +08:00
kelianchun
d86cebf99a Merge pull request #164 from kelianchun/dev
pull issue #120  remove ps1
2016-03-25 23:55:26 +08:00
liuzheng712
9b43c6c238 update 2016-03-25 23:52:48 +08:00
liuzheng712
1084be4712 update 2016-03-25 22:28:49 +08:00
liuzheng712
44b2bcb759 修改日志数据库部分 2016-03-25 22:24:56 +08:00
liuzheng712
2d1e001ddf 日志回放ok 2016-03-25 22:20:50 +08:00
liuzheng712
8e8d8c9d6a 日志回放OK 2016-03-25 22:19:31 +08:00
liuzheng712
a1862d912a Merge branch 'dev' of github.com:jumpserver/jumpserver into TermLogRecorder 2016-03-25 21:08:55 +08:00
kelianchun_miller
fd713e0e5c pull issue #120 remove ps1 2016-03-25 21:08:52 +08:00
ibuler
d7442b4879 Update views.py 2016-03-25 17:36:12 +08:00
ibuler
4f79e909e5 Merge pull request #161 from jumpserver/user_edit
fix(user edit) 修改用户导致密码问题
2016-03-25 17:20:21 +08:00
ibuler
69061791ed fix(user edit) 修改用户导致密码问题
简单修改,更改结构和变量名

close #160
2016-03-25 17:18:41 +08:00
ibuler
38f15c976f Merge pull request #159 from jumpserver/terminal_font
fix(web terminal) Windows 浏览器使用chrome -换行
2016-03-24 19:07:55 +08:00
ibuler
b745ebdda1 fix(web terminal) Windows 浏览器使用chrome -换行
经测试由于字体原因,可以安装Monaco字体解决,然而不太方便

添加第二字体为 微软雅黑,经测试解决

fixed
close #158
2016-03-24 19:03:20 +08:00
ibuler
ae58fd548f Merge pull request #157 from jumpserver/force_del_user
fix(userdel) 修复无法删除在线用户bug
2016-03-24 18:07:28 +08:00
ibuler
fbc3078c07 fix(userdel) 修复无法删除在线用户bug
当用户已经登录到jumpserver时,web上删除用户时失败,也没有提示

修改方法: userdel -r -f 强制删除

close #156
2016-03-24 18:04:04 +08:00
liuzheng712
860c7f1508 Merge branch 'dev' of github.com:jumpserver/jumpserver into TermLogRecorder 2016-03-24 17:29:59 +08:00
liuzheng712
3fcd9589a4 update 2016-03-24 17:29:50 +08:00
liuzheng712
ba5e90abc3 update 2016-03-24 17:17:47 +08:00
kelianchun
5587ff59b0 Merge pull request #155 from kelianchun/dev
Dev
2016-03-24 13:35:46 +08:00
kelianchun
6d329b130a remove ps1 search
remove ps1 search
2016-03-24 13:02:02 +08:00
liuzheng712
357aea1693 update jumpserver.conf only for myself 2016-03-24 12:49:39 +08:00
liuzheng712
3ab0c94496 update settings for myself, use sqlite 2016-03-24 12:49:06 +08:00
liuzheng712
b3f83c3362 update 2016-03-23 22:38:02 +08:00
liuzheng712
17a7470a2a update_TermLogRecorder 2016-03-23 18:26:23 +08:00
liuzheng712
365a5ccd46 update_TermLogRecorder 2016-03-23 18:25:18 +08:00
liuzheng712
742a2b1b85 Merge branch 'dev' of github.com:jumpserver/jumpserver into TermLogRecorder 2016-03-23 17:08:33 +08:00
liuzheng712
388ebe3bee update 2016-03-23 17:07:57 +08:00
ibuler
6d302eb25a Merge pull request #154 from jumpserver/term_log_bug
fix: command recoder bug fix
2016-03-23 17:07:28 +08:00
liuzheng712
fa1f2404d9 日志记录 2016-03-23 17:05:35 +08:00
liuzheng712
52d8825d95 修复tmux等会重复出现命令的bug 2016-03-23 17:05:02 +08:00
liuzheng712
e743ae3dbe model 2016-03-23 16:36:55 +08:00
kelianchun
db72048c31 Update run_server.py 2016-03-23 15:47:08 +08:00
liuzheng712
f1ff52eb6b fix: command recoder bug fix 2016-03-23 15:46:42 +08:00
ibuler
0b05899818 Merge pull request #152 from jumpserver/pyte
change(install.py) 增加pyte库
2016-03-23 15:12:07 +08:00
ibuler
bd59b6316e change(install.py) 增加pyte库
增加pyte库来分析命令
2016-03-23 15:10:28 +08:00
jiaxiangkong
2c74c8a8df Update README.md 2016-03-23 14:42:26 +08:00
kelianchun
dc2ea0d6bf Merge pull request #149 from kelianchun/dev
Dev
2016-03-23 12:40:06 +08:00
kelianchun
73382cbcfb Update run_server.py 2016-03-23 12:37:55 +08:00
kelianchun
e6254ddc2c deal command data
deal command data
2016-03-23 12:36:29 +08:00
kelianchun
30607730f2 Merge pull request #148 from kelianchun/dev
no command data
2016-03-23 12:29:38 +08:00
kelianchun
b92c5188d1 no command data
no command data
2016-03-23 12:28:32 +08:00
ibuler
524cd1d990 Merge pull request #147 from jumpserver/bug_asset_upload_01
fix asset upload bug
2016-03-23 12:09:20 +08:00
wangyong
231f961945 fix asset upload bug 2016-03-23 11:56:32 +08:00
ibuler
267c1cd696 Merge pull request #142 from jumpserver/bug_asset_upload
fix asset upload bug
2016-03-22 18:03:00 +08:00
wangyong
a1e947ae1e fix asset upload bug 2016-03-22 17:32:43 +08:00
ibuler
300e106143 Merge pull request #140 from Astraeux/smtp_ssl_fix
SMTP发邮件支持SSL
2016-03-22 16:32:51 +08:00
ibuler
57e85affde Merge pull request #141 from jumpserver/termShake
fix: when moniter the terminal, fix the shake
2016-03-22 10:22:42 +08:00
liuzheng712
34b74b9e4e fix: when moniter the terminal, fix the shake 2016-03-21 22:51:28 +08:00
Astraeux
c218949556 SMTP发邮件支持SSL 2016-03-21 21:55:03 +08:00
Astraeux
4b90cd9b82 Merge pull request #3 from jumpserver/dev
update from origin
2016-03-21 20:08:34 +08:00
ibuler
fcb3fd7186 Merge pull request #139 from jumpserver/issue_52_bugfix
Issue 52 bugfix: 修复录像播放,web terminal hang住bug
2016-03-21 11:11:21 +08:00
ibuler
4dbc6803fb Update README.md 2016-03-21 11:00:31 +08:00
ibuler
b6af8368b6 Merge pull request #138 from jumpserver/role_pass_long_bug
修复系统用户role密码过长引起的异常
2016-03-21 10:40:59 +08:00
ibuler
6e4b291808 fix(perm_role_edit) 修复编辑系统用户密码过长bug
1. 添加前端验证

close #173
2016-03-21 10:32:08 +08:00
ibuler
4c88ea3c05 fix(perm_role_add) 修复添加系统用户密码过长导致的异常bug
1. 修改表结构password长度
2. 修改template添加js验证
2016-03-21 10:30:29 +08:00
ibuler
0e5fd68e6c Merge pull request #129 from jumpserver/bug_fix_100_and_127
fix (jperm):   统一调整系统用户 仅使用秘钥进行通信, 已存在的用户不会修改密码
2016-03-19 13:18:06 +08:00
liuzheng712
1103ee8f52 len(vim_data) 2016-03-18 23:55:06 +08:00
liuzheng712
9efa9e979c len(vim_data) 2016-03-18 23:51:25 +08:00
liuzheng712
f331b4471f Merge branch 'dev' of github.com:jumpserver/jumpserver into issue_52_bugfix 2016-03-18 23:41:19 +08:00
kelianchun
f11016f57c Merge pull request #136 from kelianchun/dev
pull issue #120
2016-03-18 23:38:26 +08:00
Astraeux
4b53bae57b Merge pull request #1 from jumpserver/dev
update from origin
2016-03-18 23:37:22 +08:00
kelianchun_miller
b2ccbc3f9e pull issue #120 2016-03-18 23:36:31 +08:00
kelianchun_miller
7dcf050dc4 pull issue #120 2016-03-18 22:06:40 +08:00
kelianchun_miller
717869fd30 Merge remote-tracking branch 'remotes/origin/master' into dev 2016-03-18 22:04:12 +08:00
kelianchun_miller
598d6cffa4 pull issue #120 2016-03-18 20:43:25 +08:00
liuzheng712
c022c81100 Merge branch 'dev' of github.com:jumpserver/jumpserver into issue_52_bugfix 2016-03-18 17:32:46 +08:00
liuzheng712
5af9dd655e delete_require_chardet 2016-03-18 17:08:15 +08:00
ibuler
abdf9c72ca Merge pull request #122 from jumpserver/bug_fix_80
fix (jasset):  修复连接超时,以及freebsd无法更新硬件信息
2016-03-18 17:00:09 +08:00
ibuler
3778724b73 Merge pull request #134 from kelianchun/dev
修复命令截取bug
2016-03-18 16:46:02 +08:00
kelianchun
d76865c1ed pull issue #120
修复了命令处理的bug
2016-03-18 15:38:31 +08:00
liuzheng712
3ccf7adac1 终于修复了乱码啦啦啦 2016-03-18 15:01:07 +08:00
yumaojun
c0e8ff8620 fix (jperm): 统一调整系统用户 仅使用秘钥进行通信, 已存在的用户不会修改密码
1. perm_role_add 同上 保留 密码选项
2. perm_role_edit 同上 保留 密码选项
3. 仅保持入数据,不设计远程操作

close #100
close #127
2016-03-16 23:03:43 +08:00
yumaojun
ca75484eb8 fix (jperm): 统一调整系统用户 仅使用秘钥进行通信, 已存在的用户不会修改密码
1. perm_role_push 模板取消密码选项,但是为了 那么留下秘钥推送可勾选,允许空推送
2. perm_role_add 同上 取消 密码选项
3. perm_role_edit 同上 取消 密码选项
4. views 调整role push add edit 相关视图
5. perm_api,调整 gen_resource,仅支持秘钥认证(是否需要支持密码认证,我觉得没必要,如果需要请提出)

close #100
close #127
2016-03-16 22:30:39 +08:00
liuzheng712
8adf1c5d71 requirement 2016-03-15 15:11:33 +08:00
liuzheng712
5f35b740df test 2016-03-15 15:06:37 +08:00
liuzheng712
b0d1dd9485 test 2016-03-15 15:04:15 +08:00
liuzheng712
ade8fb927c test 2016-03-15 15:02:16 +08:00
liuzheng712
31708c0d24 udpate 2016-03-15 14:53:30 +08:00
liuzheng712
9b3a51469e install_chardet 2016-03-15 14:46:25 +08:00
yumaojun
cdd31227b7 fix (jasset):  修复连接超时,以及freebsd无法更新硬件信息
1. 超时原因应该是sshd 的配置引起的,当前bsd的更新 相对于其他发行版 慢,这个原因估计的bsd自身有关
 2. ansible 的setup模块对于b sd获取的字段 越有偏差,而且无法获取硬盘信息,这个后期可以 提交patch 给ansible的setup模块。

 close #80
2016-03-14 22:47:33 +08:00
jiaxiangkong
b02a45ee6c Update README.md 2016-03-10 17:43:37 +08:00
jiaxiangkong
f796e8f673 Update README.md 2016-03-10 17:42:45 +08:00
jiaxiangkong
930c57398a Update README.md 2016-03-10 17:40:54 +08:00
ibuler
6b39c9946b Merge pull request #116 from jumpserver/bug_fix_guang
fix(bug) 修复首页点击头像404问题
2016-03-06 09:51:31 +08:00
ibuler
3a71d7f1a8 fix(bug) 修复首页点击头像404问题
处理结果,直接干掉连接
2016-03-06 09:50:01 +08:00
liuzheng712
d48020a919 test 2016-03-04 23:59:18 +08:00
liuzheng712
210b3c8588 test 2016-03-04 23:57:39 +08:00
liuzheng712
bdf6d97478 test 2016-03-04 23:50:19 +08:00
liuzheng712
1ac9bebb8d fix: delete monkey patch 2016-03-04 23:17:19 +08:00
liuzheng712
ef3156e6f7 fix(test): monkey patch 2016-03-04 23:15:39 +08:00
liuzheng712
95a7557acf fix: 2016-03-04 20:42:08 +08:00
liuzheng712
8e30ffb840 fix(run_server.py): test if it invoke_shell bug 2016-03-04 20:40:37 +08:00
liuzheng712
20b5facc38 fix(webterminal): data 2016-03-04 20:30:58 +08:00
liuzheng712
f7eda41a54 fix(webterminal): data.data.data 2016-03-04 20:29:54 +08:00
liuzheng712
6a0edb63f0 fix(webterminal): data.data 2016-03-04 20:28:52 +08:00
liuzheng712
e7976e4235 fix(webterminal.js): }) bug 2016-03-04 20:22:46 +08:00
liuzheng712
2bd3fdb4e7 fix(webterminal): url bug 2016-03-04 20:21:20 +08:00
liuzheng712
94a4d68be2 fix(webterminal.js): send bug 2016-03-04 20:12:09 +08:00
liuzheng712
b879e724e2 fix(webterminal.js): forget rowHeight and colWidth 2016-03-04 20:09:05 +08:00
liuzheng712
234f79857c fix(webterminal): change it to HTML5 websocket 2016-03-04 20:07:05 +08:00
liuzheng712
f73d34b9cc fix(monitor): change monitor url 2016-03-04 19:48:52 +08:00
liuzheng712
936faad1b9 fix(base.jinja2): change script with term.js 2016-03-04 19:35:53 +08:00
ibuler
649783d2c3 Merge pull request #114 from jumpserver/bug_fix_guang
change(with pre fix) 修改安装和jumpserver.conf
2016-03-03 18:18:36 +08:00
ibuler
c0bacb7c7c change(with pre fix) 修改安装和jumpserver.conf
上次修改已可以自动获取 ws地址,去掉无用设置和配置文件指定
去掉install.py中的设置
2016-03-03 18:16:11 +08:00
ibuler
6436fab837 Merge pull request #113 from jumpserver/bug_fix_guang
fix(ws protocal): 修复所有ws自动获取
2016-03-03 18:09:26 +08:00
ibuler
e38620a2a2 Merge pull request #111 from jumpserver/install_bug_fix
修复一些install.py 中的小问题
2016-03-03 18:08:04 +08:00
ibuler
702b1bd3b7 fix(ws protocal): 修复所有ws自动获取
自动获取websocket无需再手动指定
2016-03-03 18:05:10 +08:00
ibuler
c2c833f279 Merge pull request #112 from jumpserver/issue_110_bugfix
修复webterminal vim后命令double
2016-03-03 17:21:42 +08:00
liuzheng712
a816a7b149 fix(webterminal): bug fix test 2016-03-03 17:03:47 +08:00
liuzheng712
32519f8eae fix: 2016-03-03 16:50:49 +08:00
liuzheng712
dbb4904513 fix(webterminal): test 2016-03-03 16:41:41 +08:00
liuzheng712
0e7a8c1a62 fix(webterminal): test 2016-03-03 16:39:14 +08:00
yumaojun
68582ca466 fix (install.py):  修复lockfile 创建失败问题 2016-03-03 16:37:12 +08:00
liuzheng712
b1f0297e82 fix(web terminal): test 2016-03-03 16:35:48 +08:00
liuzheng712
eeff2ab215 fix(webterminal): test 2016-03-03 16:34:22 +08:00
yumaojun
62fb6429f9 fix (install.py):  更新install.py 和 service.sh
1. 添加软件安装失败后的用户提醒
2. service.sh脚本添加对lockfile 目录缺失的处理。
2016-03-03 15:53:46 +08:00
ibuler
90c3ed96e3 Merge pull request #109 from jumpserver/bug_fix_guang
fix(web teminal): 修改动态改变窗口大小bug
2016-03-02 11:40:28 +08:00
ibuler
c79e625000 fix(web teminal): 修改动态改变窗口大小bug
变量名写错引起的不明显bug
2016-03-02 11:38:38 +08:00
Huang Chengwei
bce3def4c6 Update run_server.py
fix signal call in auth
2016-03-01 17:09:27 +08:00
ibuler
1437140f87 Merge pull request #108 from jumpserver/bug_fix_guang
fix(run_server.py) 修改一个常规错误,函数参数个数
2016-03-01 17:03:33 +08:00
ibuler
fd19bb6299 fix(run_server.py) 修改一个常规错误,函数参数个数
已fix
2016-03-01 17:01:11 +08:00
ibuler
a401440004 Merge pull request #105 from jumpserver/hot_fix_log
hot_fix(kill invalid connection) 紧急修复超时异常连接

修改日志参数
修改处理间隔,每10分钟处理一次
修改处理策略 ssh: 1小时不操作,就kill掉 web: 超过1天,就设置完成
2016-02-29 18:18:57 +08:00
ibuler
06aef8fb1a Merge pull request #106 from jumpserver/issue_57_bug_fix
1. 修复tonrado数据库连接bug
2. 修改定期处理长时间连接
3. 添加nginx文档

ref #57
2016-02-29 18:18:10 +08:00
ibuler
c418f142ba Merge remote-tracking branch 'origin/issue_57_bug_fix' into dev 2016-02-29 18:15:31 +08:00
ibuler
88d21caa19 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-02-29 18:14:50 +08:00
ibuler
f6c58054a6 Merge branch 'hot_fix_log' into dev 2016-02-29 17:59:25 +08:00
ibuler
b4d74bc589 hot_fix(kill invalid connection) 紧急修复超时异常连接
1. 修改日志参数
2. 修改处理间隔,每10分钟处理一次
3. 修改处理策略
   ssh: 1小时不操作,就kill掉
   web: 超过1天,就设置完成
2016-02-29 17:53:15 +08:00
ibuler
d7bb4c1005 fix(kill invalid connection) 紧急处理超时连接
1. 紧急修复异常bug
2. 修改处理策略
3. 每10分钟处理一次
   ssh连接:超过1小时没有操作就干掉
   web:超过1天的就设置完成
2016-02-29 17:48:14 +08:00
ibuler
3c610668b5 fix(invalid connection again) 定期处理长时间连接
1. 减少了处理时间间隔
2. 处理策略更改为 超过 1小时没有动的连接就干掉
2016-02-29 17:07:53 +08:00
ibuler
5d28a6e402 fix(invalid connection) 定期处理长时间连接
1. 减少了处理时间间隔
2. 处理策略更改为 超过 1小时没有动的连接就干掉
2016-02-29 16:35:09 +08:00
黄成维
e886b55727 fix signal send 2016-02-29 16:09:01 +08:00
黄成维
8c552ccc45 fix signal send 2016-02-29 16:06:20 +08:00
黄成维
054edeefb6 try fix tornado connection timeout 2016-02-29 15:03:48 +08:00
ibuler
6c599e0127 Merge pull request #101 from jumpserver/bug_fix_yu
install.py安装兼容多个平台
2016-02-29 12:21:41 +08:00
ibuler
4f97987061 Merge pull request #97 from jumpserver/bug_fix_guang
fix 启动脚本,配置文件,批量命令异常等
2016-02-29 12:17:31 +08:00
yumaojun
50e82c5b99 fix (install.py):  更新wiki地址 2016-02-29 11:08:48 +08:00
yumaojun
1f9337feca fix (install.py):  compatible fedora
1. mysql-python编译不过, 添加rpm-build 依赖
2016-02-29 10:58:31 +08:00
ibuler
cba53bba55 modify(jumpserver.conf) 修改jumpserver.conf默认配置
django和tornado统一入口后,配置默认启动端口80
websocket和web都使用该端口
2016-02-29 10:25:59 +08:00
yumaojun
427fda1015 fix (install.py):  compatible fedora
1. compatible fedora (test fedora22)
2016-02-29 10:09:05 +08:00
yumaojun
a95e1bb835 fix (install.py):  compatible fedora
1. compatible fedora (test fedora22)
2016-02-29 09:52:10 +08:00
Tad Wang
5ab882ae66 update configuration doc
typo of KEYWORD of SSL configuration
2016-02-29 01:37:20 +08:00
Tad Wang
e5ce5766be add document for nginx ssl setting #88
add document for nginx ssl configuration. #88
2016-02-29 01:27:51 +08:00
ibuler
725405e4fd change(install) 修改提示,更改变化的文件名 run_server.py
websocket -> websocket_url
2016-02-28 16:41:44 +08:00
ibuler
cad7a193b3 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-02-28 16:32:33 +08:00
ibuler
69ac8ae147 Merge pull request #99 from jumpserver/misunderstand_4_default_DB_user
安装脚本默认数据库用户名
2016-02-28 16:09:31 +08:00
yumaojun
247e5e7f24 fix (install.py):  little update to contain liuzheng pr.
1. 请输入数据库服务器用户 [root] , 修改成 [jumpserver]
2016-02-28 15:55:21 +08:00
yumaojun
04821a00f8 fix (install.py):  compatable centos7
1. use systemctl  stop firewalld
2. add  dependence:  readline-devel and lrzsz
3. use mariadb as mysql server
2016-02-28 15:47:39 +08:00
yumaojun
ad3178fe94 fix (install.py):  compatable centos7
1. use systemctl  stop firewalld
2. add  dependence:  readline-devel and lrzsz
2016-02-28 15:23:14 +08:00
yumaojun
ccd1a10892 fix (install.py):  compatable centos7
1. use systemctl  stop firewalld
2. add  dependence:  readline-devel and lrzsz
2016-02-28 15:01:55 +08:00
yumaojun
b80ad40f54 fix (install.py):  compatable centos7
1. use systemctl  stop firewalld
2. add  dependence:  readline-devel and lrzsz
2016-02-28 14:40:17 +08:00
liuzheng712
7cf190e3f9 refactor(install/install.py): default database user should be jumpserver 2016-02-27 21:25:09 +08:00
yumaojun
cac94245ea fix (install.py):  ubuntu auto install mysql-server
1. set ansible_api connector as paramiko
2. set ubuntu apt-get --force-yes  when install packages
2016-02-27 18:35:00 +08:00
yumaojun
a729e54425 fix (install.py):  ubuntu auto install mysql-server
1. auto install mysql server
2016-02-27 13:24:19 +08:00
yumaojun
d4b57fc1b0 fix (install.py):  ubuntu auto install mysql-server
1. auto install mysql server
2016-02-27 12:43:59 +08:00
yumaojun
d63b5772e4 fix (install.py):  check platform
1. check platform , support CentOS, ReaHat, Fedora, Ubuntu, debian
2016-02-27 12:05:34 +08:00
yumaojun
37e0f80fb8 fix (install.py): fix install.py add user failed and service failed
1. use shlex.os.system  replace  subprocess.call
2. next.py use bash service start
2016-02-27 12:01:44 +08:00
ibuler
532fbbd4f1 change(service.sh, run_websocket) 修改启动脚本, rename run_websocket.py
1. 修改启动脚本,支持放到 init.d
2. rename run_websocket.py -> run_server.py 交互式启动
2016-02-27 01:26:36 +08:00
ibuler
16f5906979 Merge pull request #96 from jumpserver/ip_port_config
jumpserver.conf添加字段,tornado根据需求监听端口
2016-02-27 00:24:15 +08:00
ibuler
bf3fb24c3a Merge pull request #95 from jumpserver/IP_get_bug
修复使用反向代理还不使用反向代理获取 remote_ip异常wen问题
2016-02-27 00:23:00 +08:00
ibuler
a8eb9f3e79 fix(jlog, websocket url) 修复ws使用 ws协议还是wss协议
1. 不再需要浏览器判断什么协议,需要在jumpserver.conf注明

ref #63
2016-02-27 00:19:04 +08:00
ibuler
a88d8ca410 fix(upload, download, exec, gn) 修复上传下载文件名,上传目录层次,执行命令回车报错,g+不存在id报错
1. 上传下载文件名 改为 时间+随机4位字母数字
2. 命令回车判断,为空返回
3. g+1判断,不过不存在该组,则返回

close #52
close #93

ref https://github.com/jumpserver/jumpserver/issues/53
ref https://github.com/jumpserver/jumpserver/issues/93
2016-02-26 23:51:21 +08:00
liuzheng712
ba8d808cd9 fix(service.sh): annotate django runserver 2016-02-26 23:09:19 +08:00
liuzheng712
d67aab573d fix: ip and port use jumpserver.conf to configure 2016-02-26 22:59:17 +08:00
liuzheng712
5098b1c696 fix(run_websocket.py): remote IP get bug
when use nginx  self.request.headers.get(X-Real-IP) will get real remote IP,
self.request.remote_ip will get 127.0.0.1 ; if not it will git null, so need to use
self.request.remote_ip for get the ip
2016-02-26 22:48:07 +08:00
yumaojun
0b9b94bc0b Merge branch 'bug_fix_yu' into dev
# Conflicts:
#	service.sh
2016-02-26 15:36:42 +08:00
yumaojun
8aec0c1ac7 fix (install jumpserver): install jumpserver compatible with ubuntu
1.  install.py  add  platform judge, fix get_ip_addr function
2.  next.py  little adjust
3. service.sh little adjust
2016-02-26 14:13:21 +08:00
liuzheng712
77f69fbc5e fix(service.sh): annotate django runserver 2016-02-26 11:52:53 +08:00
liuzheng712
14a0c1871f Merge branch 'issue_59_bug_fix' into dev 2016-02-26 10:53:29 +08:00
liuzheng712
49e7796df9 Merge branch 'feat_Only_run_one' into dev 2016-02-26 10:45:40 +08:00
liuzheng712
318a053dbf real ip 2016-02-26 10:38:04 +08:00
ibuler
29953eb7c7 Merge pull request #87 from liuzheng712/feat_run_one
整合Tornado和Django,修复web阻断功能
2016-02-26 10:12:23 +08:00
liuzheng712
1816723f16 fix(run_websocket.py): get real ip from headers 2016-02-25 22:43:52 +08:00
liuzheng712
5fb5c1bb40 merge 2016-02-25 21:16:09 +08:00
liuzheng712
4d5d56fe79 fix(jlog/views.py): kill bug, because cross domain 2016-02-25 21:07:18 +08:00
liuzheng712
7213c5c637 fix(log_online.html): log kill bug
change $.ajax to $.get
2016-02-25 21:04:27 +08:00
liuzheng712
eb161b978a test kill 2016-02-25 21:00:48 +08:00
liuzheng712
23d4c926b7 web log_kill 2016-02-25 20:45:48 +08:00
liuzheng712
c354b64679 web log_kill 2016-02-25 20:44:13 +08:00
liuzheng712
9c93d5a8d2 add /ws/ 2016-02-25 20:42:35 +08:00
liuzheng712
4f75f76db8 fix: web socket url update 2016-02-25 20:05:20 +08:00
ibuler
4dfef99216 Merge pull request #85 from jumpserver/bug_fix_issue_83
修复用户禁用后仍可ssh登陆跳板机
2016-02-25 18:42:59 +08:00
ibuler
47ce09393c fix(connect.py) 用户禁用后仍可ssh登陆jumpserver
修改connect.py添加判断
资产禁用还没有考虑,改动太大,留后续版本更改

ref https://github.com/jumpserver/jumpserver/issues/83
2016-02-25 18:34:46 +08:00
liuzheng712
92e9f988f3 feat(run_websocket.py): add main function, it need only run run_websocket.py
I want to run one program at once, open two terminal is ridiculous
2016-02-25 16:51:41 +08:00
liuzheng712
037a88f0f5 fix(term.js): my mistake
use yoshiokatsuneo term.js
2016-02-25 13:58:31 +08:00
yumaojun
e8db8addd7 fix (service.sh): ubuntu service.sh 脚本不可用
由于service.sh 脚本依赖外部的函数库 /etc/init.d/functions, 而ubuntu 和其他一起系统并没有这个文件,所以直接把 这个文件copy 到了当前目录下
不在依赖外部环境。
2016-02-25 13:26:18 +08:00
ibuler
d0ba0503e5 Merge pull request #81 from jumpserver/v3.0_beta_issue_62
V3.0 beta issue 62 用户下载key后,就删除,为了安全
2016-02-25 13:15:13 +08:00
liuzheng712
27be35ae77 fix(user_list.html & juser/views.py): only for user delete sshkey when downloaded, add generate butt
https://github.com/jumpserver/jumpserver/issues/62
2016-02-25 13:04:09 +08:00
yumaojun
835706f780 fix (jperm.view): 修复回收主机时, 未修改sudoers文件的bug
1. 恢复ansible 使用的 连接器配置未 smart
2. 修改perm_role_recycle 删除, 添加回收sudo配置.
2016-02-25 11:59:29 +08:00
ibuler
f79675b265 Merge pull request #78 from jumpserver/bug_fix_guang
#78 统一资产添加文案,修改添加用户流程,修复添加系统用户使用key推送,不生成密码
2016-02-24 15:06:20 +08:00
ibuler
0a35f757e9 modify(function arg) only for writing style
修改函数使用kwarg
2016-02-24 14:46:28 +08:00
liuzheng712
856852592d fix(term.js): CJK support, Copy and Paste support
Use yoshiokatsuneo's code, fix this bug. His idea is append a textarea and bind all click event on
it. That works for us

https://github.com/jumpserver/jumpserver/issues/59  https://github.com/chjj/term.js/pull/97
2016-02-24 13:39:00 +08:00
ibuler
f60a896926 modify(jasset) 统一管理用户文案
所有用得到管理用户文案的地,都进行了统一
更改了 管理用户使用默认的对齐
去掉了分隔线
2016-02-24 12:32:41 +08:00
ibuler
b6fc8b777f change(juse) 修改用户添加流程
1. 添加新用户,不在为该用户设置密码
2. 强制用户使用key登陆跳板机,为了安全性
3. 更改邮件文案和不发送邮件提示文案
2016-02-24 12:29:47 +08:00
ibuler
caefbdc917 fix(juser) 推送系统用户,选择密钥时不为用户生成密码
当推送系统用户时,选择系统用户使用密钥时没有必要为系统用户生成密码,
以免造成安全上的问题,在代码上也属于冗余.
2016-02-24 11:34:33 +08:00
yumaojun
c6823be302 修复sudo 命令 小写all 引起的推送失败(map) 2016-02-23 23:29:15 +08:00
yumaojun
7bfb1d19fe 修复sudo 命令 小写all 引起的推送失败 2016-02-23 23:04:46 +08:00
yumaojun
f24b34758c 修复sudo 命令 小写all 引起的推送失败 2016-02-23 21:14:54 +08:00
ibuler
d4b1bdef8e modify(with 0e9a962506) 变更启动脚本
1. 启动时添加 django crontab
2. 关闭时删除 django crontab
2016-02-23 18:46:00 +08:00
ibuler
dee1d31fc0 change(with 6be7003) 联动改变安装脚本
1. 为init.sh添加执行权限
2. 统一函数功能  修改其他需要改变权限的脚本或目录
2016-02-23 18:29:23 +08:00
ibuler
363bce82d8 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-02-23 17:49:59 +08:00
ibuler
6be7003ac2 bugfix(登录初始化) 避免登录时ctrl+c进入系统内部
此bug信息见 #72
1. 修改思路 重命名zzjumpserver.sh,并移动到外层
2. 服务器添加用户时指定shell为 some_dir/jumpserver/init.sh

升级修复方案:
1. 删除/etc/profile.d/zzjumpserver.sh
2. git pull 更新
3. vim编辑 /etc/passwd,把之前建的用户的sh改为 some_dir/jumpserver/init.sh

终
Closes #72
closes #31
2016-02-23 17:40:33 +08:00
ibuler
586e43c8d0 Merge pull request #71 from jumpserver/dev
fix(bsd推送系统用户bug)
2016-02-23 15:50:59 +08:00
ibuler
18e66f52dd Merge remote-tracking branch 'origin/dev' into dev 2016-02-23 15:45:32 +08:00
yumaojun
09e86f0a6b Merge branch 'dev' of https://github.com/jumpserver/jumpserver into dev 2016-02-23 15:22:15 +08:00
yumaojun
3b5daf19c3 1. 修复freebsd 推送带sudo规则的用户时 , sudo 路径引发的问题。 2016-02-23 15:21:27 +08:00
liuzheng712
a037108cf3 refactor: double meaning 2016-02-23 14:23:07 +08:00
liuzheng712
b8a8c3ebf3 feat(juser/views.py;func:down_key): delete the private key when user download it
issue:62
2016-02-23 14:15:55 +08:00
ibuler
9fa7f8762e Merge branch 'master' into dev 2016-02-23 13:35:36 +08:00
ibuler
9ec457bf5f Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2016-02-23 13:35:28 +08:00
ibuler
2691cc0b6d Merge branch 'master' into dev 2016-02-23 13:33:32 +08:00
yumaojun
4645029a27 1. 配置ansible 使用paramiko进行链接(ssh 有卡死问题, 等待反馈.)
2. 修复freebsd 推送带sudo规则的用户时 由于 sed  引起的问题。
2016-02-23 11:48:09 +08:00
ibuler
b1768565c1 修复
1. 推送时 验证改为  /usr/sbin/visudo -c
    2. 添加系统用户的key 认证更改 支持 RSA|DSA
    3. web terminal 行数 -1
2016-02-22 16:31:33 +08:00
ibuler
7323b72c4b 修复
1. 推送时 验证改为  /usr/sbin/visudo -c
2. 添加系统用户的key 认证更改 支持 RSA|DSA
3. web terminal 行数 -1
2016-02-22 16:29:36 +08:00
ibuler
2e5c01a4da Merge pull request #47 from iambocai/master
当用户未被授予任何角色/主机权限时,提示用户
根据用户实际安装路径,替换启动脚本中connect.py的路径
修正几处拼写错误
2016-02-20 22:53:27 +08:00
ibuler
19dd1af4dc Merge pull request #49 from wangjunj/master
添加本地mysqld自启动服务
2016-02-20 22:51:15 +08:00
ibuler
0e9a962506 具体体现在 日志监控页,定期回收过期的在线log
需要运行python manage.py crontab add来添加

运行 python manage.py crontab remove 来去掉

crontab -l
2016-02-20 16:02:31 +08:00
iambocai bob.chen.cs@gmail.com
fa195c3808 update for pull#47 2016-02-17 15:16:36 +08:00
wangjunj
cd6cfc6ae9 Update install.py 2016-01-28 23:08:12 +08:00
wangjunj
02e9ba54f9 添加本地mysqld自启动服务
添加数据库自启动服务。修复服务器重启后./server.sh start 会提示错误——“Starting jumpsever
service:run_websocket.py not running”
2016-01-28 14:50:57 +08:00
ibuler
b79056295b Merge branch 'dev' 2016-01-26 15:37:27 +08:00
ibuler
8653630d83 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2016-01-26 15:37:19 +08:00
ibuler
99f09709ec 修改默认端口获取 2016-01-26 15:37:12 +08:00
wangyong
bcb914485d fix asset edit port not save 2016-01-26 15:35:47 +08:00
iambocai bob.chen.cs@gmail.com
0b79f754f9 1. 当用户未被授予任何角色/主机权限时,提示用户
2. 根据用户实际安装路径,替换启动脚本中connect.py的路径
3. 修正几处拼写错误
2016-01-25 18:21:07 +08:00
ibuler
fe87e32e2b roll back 2016-01-21 19:37:20 +08:00
ibuler
9c9390878e Merge branch 'master' of github.com:ibuler/jumpserver 2016-01-21 18:17:29 +08:00
ibuler
1c2cba64ec 修改推送默认端口bug 2016-01-21 18:17:18 +08:00
ibuler
b69853a608 Merge pull request #46 from wptad/master
监控支持 ssl
2016-01-21 13:21:59 +08:00
Tad Wang
852de35e3e fix term.js input error problem
handler is undefined.
2016-01-21 13:02:23 +08:00
Tad Wang
6fbb387488 fix wss support for web_monitor_uri
Https support
2016-01-21 11:53:56 +08:00
ibuler
36bfb50aad 系统用户支持. 2016-01-18 12:01:39 +08:00
ibuler
28e0ea3e81 支持用户名带小数点,上传文件大小最大2G 2016-01-15 15:54:49 +08:00
ibuler
6ba9191b30 update LANG setting 2016-01-14 11:58:53 +08:00
ibuler
b6f82ca020 修复vim修改窗口大小中断bug 2016-01-14 11:10:07 +08:00
ibuler
81a6f4841f 修复用户组编辑导致该用户组都丢失问题 2016-01-14 11:01:19 +08:00
ibuler
f2487a22cd 修复 su - 无法获取 Env的bug 2016-01-13 17:57:32 +08:00
ibuler
4d0331e105 Update connect.py 2016-01-13 15:51:29 +08:00
ibuler
66e53c2701 Update zzjumpserver.sh 2016-01-13 14:06:36 +08:00
ibuler
2e6f3d3579 Merge pull request #42 from hhding/master
Get SSH client IP address from environment
2016-01-13 13:20:28 +08:00
ibuler
80fde52dc5 Merge pull request #38 from wptad/master
fix wss issue when using https  #37 支持 wss 和 https
2016-01-13 12:32:16 +08:00
ibuler
82a88e0b0a fix 硬盘超过6块数据库溢出 2016-01-12 22:39:44 +08:00
wangyong
d3f9fc7a21 disk length 128 to 1024 2016-01-12 22:17:02 +08:00
ibuler
9d7c30336e 修复中文字符报错 2016-01-11 18:12:30 +08:00
ibuler
ff5b339ce8 Update asset_cu_list.html 2016-01-09 21:51:07 +08:00
ibuler
70c86d2a44 修改windows下 web terminal窗口高度 2016-01-09 21:50:22 +08:00
ibuler
0924484bc4 Update install.py 2016-01-09 21:42:44 +08:00
Honghui Ding
dd36857cf8 Get SSH client IP address 2016-01-09 07:37:28 +00:00
ibuler
2f54c369f7 Update README.md 2016-01-08 17:16:06 +08:00
ibuler
9e5402e2c3 Merge branch 'master' of github.com:ibuler/jumpserver 2016-01-08 11:49:33 +08:00
ibuler
097d77755a Merge branch 'dev' 2016-01-08 11:48:57 +08:00
wangyong
4fbeb5c172 fix cpu bug 2016-01-07 19:19:05 +08:00
ibuler
23b04fbbd7 Merge pull request #36 from chnliyong/master
Ubuntu的passwd命令不支持--stdin选项,使用chpasswd替代,在CentOS上已经验证有效
2016-01-07 19:06:12 +08:00
Tad Wang
d9455e3f9b fix wss issue when using https #37 2016-01-07 15:59:57 +08:00
yumaojun
beeb2442ad 回收sudo用户, 添加sudo别名添加规则检查 2016-01-07 15:21:39 +08:00
yumaojun
f6a228008b 回收sudo用户, 添加sudo别名添加规则检查 2016-01-07 15:15:44 +08:00
LI Yong
73522dc4c1 Ubuntu's passwd command doesn't support --stdin option, use chpasswd which is also available in CentOS 2016-01-07 14:09:11 +08:00
ibuler
d9b4f5504c Merge branch 'dev' 2016-01-05 19:29:56 +08:00
yumaojun
01511c0d5a Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2016-01-05 17:22:44 +08:00
yumaojun
01cf2d4e7b 删除role时提醒那些 主机上的系统用户会被删除, (需求:http://bbs.jumpserver.org/read/325.html) 2016-01-05 17:22:25 +08:00
ibuler
e9212d5ce6 fix普通用户大小修改 2016-01-04 17:15:33 +08:00
ibuler
bc2345ba14 Merge branch 'master' of github.com:ibuler/jumpserver 2016-01-04 16:38:20 +08:00
wangyong
c2818870d3 fix aliyun disk bug 2016-01-04 16:37:02 +08:00
ibuler
38b0f2f5f9 Merge pull request #34 from t57root/forget_password_vul
当有用户uuid 或账号姓名电邮地址信息时,可以修改任意账号的密码
2016-01-04 15:05:31 +08:00
ParInshOvGotQuep
79300b752b 修复找回密码及静态key问题 2016-01-04 13:56:47 +08:00
yumaojun
ed6559bbe9 修改前端禁止root的正则表达式,做精确匹配 2016-01-04 13:17:58 +08:00
yumaojun
0821e7cf41 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2016-01-04 13:13:35 +08:00
yumaojun
38f72a85e4 修改前端禁止root的正则表达式,做精确匹配 2016-01-04 13:13:13 +08:00
ibuler
ccc2bcf066 Merge branch 'dev' 2016-01-04 12:08:14 +08:00
ibuler
d9d009ab1f Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2016-01-04 12:08:02 +08:00
ibuler
f268af945f 修复web执行命令没有结果 2016-01-04 12:01:47 +08:00
yumaojun
34e8b32180 添加系统用户删除 提醒 2016-01-04 11:47:50 +08:00
yumaojun
c6626e83f2 禁止添加root用户作为系统用户 2016-01-04 11:43:17 +08:00
ibuler
4e5c501041 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2016-01-03 22:03:26 +08:00
yumaojun
0832ea97b1 去除sudo 添加和修改是 空格会被识别为 分隔符的问题 2016-01-03 21:11:55 +08:00
ibuler
7bef517518 支持修改窗口大小 2016-01-01 22:38:50 +08:00
ibuler
ea973bbb52 修复交换机小bug 2015-12-31 22:37:01 +08:00
ibuler
b673fec532 添加失败点击提示 2015-12-31 19:12:17 +08:00
ibuler
7e185197aa Merge branch 'sh' 2015-12-31 16:42:21 +08:00
ibuler
5e86b06db8 添加调试 2015-12-31 16:41:52 +08:00
ibuler
2e2b065c42 Merge pull request #31 from t57root/modify-default-shell
修改普通用户默认shell为connect.py,修复jailbreak
2015-12-31 16:41:22 +08:00
ibuler
91e006cfb0 Merge branch 'sh1' into sh 2015-12-31 16:35:33 +08:00
ibuler
b1a36bbb11 fix 2015-12-31 16:35:17 +08:00
ParInshOvGotQuep
ac40098ac5 修改硬编码的shell路径 2015-12-31 16:24:46 +08:00
ibuler
6ff030847e Merge branch 'sh1' into sh 2015-12-31 16:18:50 +08:00
ibuler
a12e401f15 fix comment 2015-12-31 12:54:15 +08:00
ibuler
49f2f92a9c fix输入换行 2015-12-31 11:20:41 +08:00
ibuler
d1ac7ca647 Merge branch 'master' into dev 2015-12-31 10:20:08 +08:00
wangyong
f6c26a201e 修改硬盘不显示问题 2015-12-30 22:35:32 +08:00
ParInshOvGotQuep
90b875adae 修改普通用户默认shell为connect.py,修复jailbreak 2015-12-30 19:15:33 +08:00
ibuler
7be7772af6 修复授权修改显示ip 2015-12-30 15:38:28 +08:00
ibuler
2fa1d7a95b fix connect.py 字符报错 2015-12-30 12:36:34 +08:00
ibuler
6e747fa299 Merge branch 'master' of github.com:ibuler/jumpserver 2015-12-30 12:12:00 +08:00
ibuler
86cc963673 更换alert我layer 2015-12-30 12:11:39 +08:00
ibuler
e776c3c5f9 Update README.md 2015-12-29 22:54:55 +08:00
wangyong
33da9fd143 fix hostname unicode 2015-12-29 14:20:47 +08:00
ibuler
09416286bf fix install port bug 2015-12-29 13:09:05 +08:00
ibuler
c5f9db450d 添加查看quickstart提示 2015-12-29 11:37:52 +08:00
ibuler
1e93b13b4c Merge branch 'master' of github.com:ibuler/jumpserver 2015-12-29 11:13:04 +08:00
ibuler
48cf64cd3a port int 2015-12-29 11:12:41 +08:00
ibuler
ff3666c6af Update README.md 2015-12-28 11:08:23 +08:00
ibuler
3918025ffd Update README.md 2015-12-28 10:53:00 +08:00
ibuler
1b7ee3b575 返回上个版本 2015-12-26 11:09:48 +08:00
ibuler
b370f01551 Merge branch 'master' into dev 2015-12-26 10:53:01 +08:00
ibuler
18da6f69a2 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-26 10:52:57 +08:00
yumaojun
d040e2719f 修复Role 删除时 秘钥问题等异常引起的Bug 2015-12-26 10:12:00 +08:00
ibuler
9eb64466bc fix user perm group perm 2015-12-25 20:26:31 +08:00
ibuler
9fc0c9da06 Merge branch 'master' of github.com:ibuler/jumpserver 2015-12-24 11:31:31 +08:00
ibuler
f63b75c01b fix 随机密码默认长度 2015-12-24 11:31:05 +08:00
ibuler
aa1dea1b08 Merge pull request #26 from wcc526/master
fix remote ip bug
2015-12-23 15:24:19 +08:00
chi-chi weng
71116bc525 fix remote ip bug
fix remote ip bug
2015-12-23 15:17:14 +08:00
ibuler
8f1e8af2e1 Merge branch 'dev' 2015-12-22 23:12:08 +08:00
ibuler
c691759af8 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-22 23:12:02 +08:00
yumaojun
d604639b96 修复添加role 时 因私钥格式不对而引起的bug(2) 2015-12-22 23:05:38 +08:00
ibuler
cde3185a20 Merge branch 'dev' 2015-12-22 22:50:17 +08:00
ibuler
40ae57d7ea Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-22 22:50:08 +08:00
ibuler
9efd42d4ed 添加team照片 2015-12-22 22:49:59 +08:00
yumaojun
3248ee1a3d 修复添加role 时 因私钥格式不对而引起的bug 2015-12-22 22:39:59 +08:00
ibuler
13d325e259 捕捉smtp异常 2015-12-22 17:18:53 +08:00
ibuler
79994e13c7 添加交流群 2015-12-22 15:57:16 +08:00
ibuler
3f9a9157f4 添加交流群 2015-12-22 15:56:39 +08:00
ibuler
7adcb11f1d comment newline 2015-12-21 16:58:30 +08:00
ibuler
42f6392cc4 fix install script bug 2015-12-21 16:10:07 +08:00
ibuler
835e32b1cc service.sh 脚本修改 2015-12-21 14:28:12 +08:00
ibuler
a7e2592fa8 fix install bug 2015-12-21 12:18:36 +08:00
ibuler
f17001e86c fix comment 2015-12-21 11:12:52 +08:00
ibuler
7113852cd6 update README 2015-12-21 10:25:51 +08:00
ibuler
7d85c0393f fix readme 2015-12-20 21:20:08 +08:00
ibuler
48af55adab 添加readline 2015-12-20 19:30:42 +08:00
ibuler
c36267dc17 rebase version 2015-12-20 19:09:18 +08:00
ibuler
b7eb95f85f 修复安装bug 2015-12-20 17:45:57 +08:00
ibuler
08cbaa1622 fix sudo bug 2015-12-20 00:30:31 +08:00
ibuler
a73fa7811c Merge branch 'dev' 2015-12-19 22:52:16 +08:00
wangyong
0d5fa418af Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-19 22:49:46 +08:00
wangyong
cf59ebf1aa fix asset add batch bug 2015-12-19 22:49:39 +08:00
ibuler
52566cb562 modify service.sh 2015-12-19 22:08:56 +08:00
ibuler
75b307105b fix 2015-12-19 22:00:54 +08:00
ibuler
998281d86d Merge branch 'dev' of git.coding.net:jumpserver/jumpserver 2015-12-19 21:57:15 +08:00
ibuler
8494989715 修改install 2015-12-19 21:56:42 +08:00
jumpserver
b73527fb33 update jumpserver.conf 2015-12-19 21:39:56 +08:00
ibuler
f18c68b8ba Update jumpserver.conf 2015-12-19 21:38:23 +08:00
ibuler
c8c0366b39 Merge with dev 2015-12-19 21:14:16 +08:00
ibuler
22c90eecfc 修改安装脚本 2015-12-19 21:12:47 +08:00
ibuler
3695989866 fix install bug 2015-12-19 20:31:06 +08:00
ibuler
80c5acef81 Merge branch 'dev' 2015-12-19 17:57:51 +08:00
ibuler
2cb6a1aac0 merge with github master 2015-12-19 17:46:30 +08:00
ibuler
39b7a7290f merge with dev 2015-12-19 17:30:21 +08:00
ibuler
7b792907d3 merge with dev 2015-12-19 17:27:12 +08:00
ibuler
c103738302 merge with dev 2015-12-19 17:26:34 +08:00
ibuler
89901fa7fb fix url error 2015-12-19 17:13:37 +08:00
ibuler
3176608eaa Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-19 17:09:55 +08:00
ibuler
94d0f7ebea 添加作者 2015-12-19 17:09:43 +08:00
wangyong
04eb4484da Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-19 17:01:23 +08:00
wangyong
9ffc887adf fix common user asset list search bug 2015-12-19 17:01:13 +08:00
ibuler
f5b97c57f8 fix readme pic width 2015-12-19 16:11:43 +08:00
ibuler
46c17b055e fix readme pic width 2015-12-19 16:10:08 +08:00
ibuler
b5bbbf7eb3 fix 2015-12-19 15:26:25 +08:00
ibuler
87f5a531bb fix 2015-12-19 15:24:50 +08:00
ibuler
3afeda8b19 fix 2015-12-19 15:20:49 +08:00
ibuler
832dc0b0e1 修改readme 2015-12-18 23:45:12 +08:00
ibuler
13cecd9b91 修改readme 2015-12-18 23:42:17 +08:00
ibuler
cba7195670 chmod +x script 2015-12-18 23:03:48 +08:00
ibuler
446a51122f 添加doc 2015-12-18 18:55:42 +08:00
ibuler
e3c0757166 添加doc 2015-12-18 18:52:32 +08:00
ibuler
0715e11c05 fix install bug 2015-12-18 18:35:07 +08:00
ibuler
1fc86733ba fix install bug 2015-12-18 18:27:12 +08:00
ibuler
4c002afde1 fix install bug 2015-12-18 18:14:12 +08:00
ibuler
caa0e29564 fix install bug 2015-12-18 18:02:46 +08:00
ibuler
0896c9ab3f fix install bug 2015-12-18 17:59:05 +08:00
ibuler
c56c44f8c0 fix install bug 2015-12-18 17:56:00 +08:00
ibuler
655bfc855e fix install bug 2015-12-18 17:49:59 +08:00
ibuler
439efa1c83 fix install bug 2015-12-18 17:42:25 +08:00
ibuler
59591c2a13 fix install bug 2015-12-18 17:39:22 +08:00
ibuler
e452c6d70a fix install bug 2015-12-18 16:52:50 +08:00
ibuler
12967bb6f9 fix install bug 2015-12-18 16:52:36 +08:00
广宏伟
6798dd8686 添加安装脚本 2015-12-18 16:26:17 +08:00
ibuler
d72a8ac5a9 修改 readme 2015-12-17 18:56:10 +08:00
ibuler
f38f809337 修改目录结构 2015-12-17 17:37:26 +08:00
ibuler
c78ab8edf7 fix 日志记录名称 2015-12-17 17:35:57 +08:00
ibuler
e24003df97 Update connect.py
修复 remote ip抓取问题
2015-12-17 17:12:26 +08:00
ibuler
f8213a1a2a user update password null 2015-12-17 11:05:43 +08:00
ibuler
da7cc102a3 fix null bug 2015-12-17 10:52:48 +08:00
ibuler
ea29305f8b Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-17 10:08:49 +08:00
ibuler
9fb71ade71 remove install wizzrd 2015-12-17 10:08:38 +08:00
ibuler
5740dec7b4 add install wizzrd 2015-12-17 10:04:19 +08:00
wangyong
7c742bf061 fix del idc failed 2015-12-16 22:24:29 +08:00
yumaojun
a30ec0c75e 修复 sudo 规则删除bug 2015-12-16 18:34:19 +08:00
yumaojun
b8abedc5b9 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-15 22:16:15 +08:00
ibuler
ef7f42cf6d reset password fix 2015-12-15 19:36:33 +08:00
ibuler
e817715da3 fix asset update bug 2015-12-15 17:35:02 +08:00
ibuler
9c0825ce70 fix more role open exec window width bug 2015-12-15 16:46:14 +08:00
ibuler
2e81f0cf95 fix nav active bug 2015-12-15 14:48:37 +08:00
ibuler
c4b099d2a5 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-15 14:45:41 +08:00
ibuler
f3606dfd96 add install wizzird 2015-12-15 14:45:37 +08:00
yumaojun
05f80f743b Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-14 20:28:39 +08:00
wangyong
f249509817 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-14 18:42:27 +08:00
wangyong
c6e0b2007d alert idc|group length 2015-12-14 18:42:17 +08:00
ibuler
2496f1c654 asset udpate url bug 2015-12-14 18:28:53 +08:00
ibuler
1a32fb5da1 fix del role url bug 2015-12-14 17:13:07 +08:00
ibuler
be2f0b2172 fix log kill and asset detail bug 2015-12-14 16:54:49 +08:00
ibuler
5e5aab7962 fix asset upload bug 2015-12-14 16:26:12 +08:00
ibuler
a8bdc37780 fix group list bug 2015-12-14 15:57:46 +08:00
广宏伟
3260584f90 修改jumpserver.conf注释 2015-12-14 14:52:35 +08:00
ibuler
b58ff14ed1 role fix to sys user 2015-12-14 14:36:42 +08:00
ibuler
db13b7a3e9 主机组列表编辑连接修改 2015-12-12 23:47:28 +08:00
ibuler
3150461d12 bug fix 2015-12-12 23:37:28 +08:00
ibuler
97bfbe24b8 bug fix 2015-12-12 23:09:58 +08:00
ibuler
30b5f74c51 bug fix 2015-12-12 23:01:59 +08:00
ibuler
69aba4643e bug fix 2015-12-12 22:57:42 +08:00
ibuler
f849ffef3e url modify 2015-12-12 19:30:39 +08:00
ibuler
6d5513c69e open in current window 2015-12-11 17:40:52 +08:00
ibuler
b27e2075ff bug fix 2015-12-11 17:28:01 +08:00
ibuler
9979fdf6de bugfix 2015-12-11 15:32:06 +08:00
yumaojun
b655b064df Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-11 14:38:24 +08:00
yumaojun
974619d1ce fixed rule and role detail page not id bug 2015-12-11 14:38:10 +08:00
ibuler
280560f286 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-11 14:03:12 +08:00
wangyong
7ce12af146 fix none bug 2015-12-11 14:02:41 +08:00
ibuler
b7bf6b4cc0 Merge pull request #23 from hailwind/master
add choose group to execute commands. 增加组执行命令功能
2015-12-11 12:05:15 +08:00
ibuler
ba955df493 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-11 11:45:25 +08:00
ibuler
34cbb13b8a bug fix 2015-12-11 11:45:19 +08:00
yumaojun
aa262d0430 fixed perm page 2015-12-10 22:58:04 +08:00
yumaojun
4294ecaf26 修复了rule 和 role 的detail 页面 2015-12-10 22:56:24 +08:00
ibuler
014d0935ba bug fix 2015-12-10 21:55:21 +08:00
ibuler
e65cad5074 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-10 17:51:23 +08:00
yumaojun
b0f2b346f9 修复了rule 和 role 的detail 页面 2015-12-10 17:44:45 +08:00
ibuler
affd9aadb5 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-10 14:42:03 +08:00
ibuler
23051a4a05 bug fix 2015-12-10 14:42:01 +08:00
yumaojun
e9fe871af3 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-10 14:40:45 +08:00
yumaojun
80b1bda51c update... 2015-12-10 14:40:29 +08:00
ibuler
e117cd003f Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-10 14:10:56 +08:00
ibuler
e03b4722b0 defend attack 2015-12-10 14:10:47 +08:00
yumaojun
b5a3fb44c3 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-10 01:15:46 +08:00
yumaojun
4903a17104 Merge branch 'map_perm' into dev
# Conflicts:
#	jperm/ansible_api.py
#	jperm/views.py
2015-12-10 01:15:25 +08:00
yumaojun
a068498561 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev
# Conflicts:
#	jperm/ansible_api.py
2015-12-10 00:17:01 +08:00
halcyon
1a3541e575 fix bugs 2015-12-10 00:13:50 +08:00
yumaojun
49267b57e4 1. 角色添加和角色修改, Server 端 输入验证
2. 日志打印
2015-12-10 00:10:39 +08:00
ibuler
d337b929ef perm edit fix 2015-12-09 17:27:13 +08:00
ibuler
f74b15c1bf perm edit fix 2015-12-09 16:42:48 +08:00
ibuler
d3fd9e05ca ansible api fix 2015-12-09 14:50:48 +08:00
ibuler
16b94c1089 bug fix 2015-12-09 11:49:30 +08:00
ibuler
d6b4c7c485 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-08 23:19:42 +08:00
ibuler
0309213ccc bug fix 2015-12-08 23:19:39 +08:00
ibuler
e408414631 bug fix 2015-12-08 19:25:11 +08:00
kelianchun_miller
80ffb9d762 update connect.py 2015-12-08 11:44:42 +08:00
ibuler
bd2a3e6119 bugfix 2015-12-08 11:32:27 +08:00
ibuler
95e8115045 bug fix 2015-12-07 23:29:19 +08:00
ibuler
b7cfac4d1f bug fix 2015-12-07 23:21:10 +08:00
ibuler
5be2633795 bug fix 2015-12-07 18:06:07 +08:00
ibuler
cb12b83e47 bug fix 2015-12-07 17:41:29 +08:00
ibuler
cd798daf0a bug fix 2015-12-07 17:30:57 +08:00
wangyong
7f6f46b662 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-06 23:48:46 +08:00
wangyong
e78d7b0219 cu asset page and sth 2015-12-06 23:48:39 +08:00
yumaojun
58082179fe 1. 用户的批量回收, 角色删除会回收推送的角色 2015-12-06 23:44:13 +08:00
ibuler
622611498c fix bug 2015-12-06 23:33:23 +08:00
ibuler
b346e1c480 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-06 22:00:55 +08:00
ibuler
bf23d6d7aa fix some bug 2015-12-06 22:00:44 +08:00
kelianchun_miller
3d0b8917fa update connect.py 2015-12-06 20:56:28 +08:00
yumaojun
8723d673d7 1. 计算该角色有哪些主机没推送时,使用交集计算(原来是差集)
2. 修改rule   detail页面 不计算,经返回rule 记录的信息
3. 修改role   detail页面 不计算,经返回rule 记录的信息
4. 添加了 推送主机上的用户回收功能
5. TODO:  页面的美观展示,与 实现 用户的批量回收。
2015-12-06 18:07:57 +08:00
ibuler
35c818f4a0 用户详情 2015-12-06 00:28:43 +08:00
ibuler
532646a431 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-05 17:55:49 +08:00
ibuler
0fd7b980de fix some bug 2015-12-05 17:55:45 +08:00
wangyong
2f0e91a538 fix bug 2015-12-05 16:57:47 +08:00
wangyong
0f6f3bdb9a Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-05 16:15:33 +08:00
wangyong
2c3e681942 fix bugs 2015-12-05 16:15:19 +08:00
ibuler
34ccaeb10f fix push role bug 2015-12-05 12:03:18 +08:00
wangyong
8f985ade97 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-12-05 11:09:41 +08:00
wangyong
9b7ef1139e fix bugs 2015-12-05 11:09:34 +08:00
ibuler
2829a7ad31 fix asset admin count 2015-12-04 18:49:17 +08:00
ibuler
b5325fd0ac bug fix for rule add check 2015-12-04 18:24:20 +08:00
ibuler
69bbdab450 完成上传下载 2015-12-04 13:42:05 +08:00
ibuler
6975acfc8a 文件上传日志 2015-12-03 23:24:34 +08:00
ibuler
9233fef63f exec log 2015-12-03 19:10:37 +08:00
ibuler
33663783cc 恢复错误修复 2015-12-03 18:49:04 +08:00
ibuler
6f4fd18c47 add 2015-12-03 18:38:06 +08:00
ibuler
7decfdc37f col-lg -> col-sm to 2015-12-03 18:37:18 +08:00
ibuler
267bb02417 修改exec 和 MyRUnner 2015-12-03 16:53:39 +08:00
ibuler
255e3a043a 修改支持选中执行 2015-12-03 10:38:10 +08:00
ibuler
6080a861db Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-02 23:50:31 +08:00
ibuler
4959073a33 web 批量执行命令 2015-12-02 23:50:20 +08:00
halcyon
f6dbec1436 day update 2015-12-02 23:39:17 +08:00
ibuler
88fbcabcbb exec-cmd tempalate 2015-12-02 19:17:12 +08:00
ibuler
1f26e49fb8 完成web批量命令执行 2015-12-02 19:16:05 +08:00
ibuler
104ee779e7 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-12-02 15:42:24 +08:00
ibuler
77da01d1ee 完成上传下载 2015-12-02 15:41:39 +08:00
ibuler
0e6fd89f0b 批量上传下载 2015-12-02 13:35:06 +08:00
halcyon
dd912e8958 asset list and add system_arch 2015-12-01 23:39:49 +08:00
ibuler
e95c47ff6a upload 2015-12-01 19:23:35 +08:00
ibuler
6b7937c639 普通用户页面 2015-12-01 13:21:42 +08:00
ibuler
f72c5753c9 添加推送 2015-12-01 11:58:11 +08:00
yumaojun
bf98aa5464 sudo push 2015-12-01 11:20:43 +08:00
yumaojun
f3102e3b5b erge laoguang. 2015-11-30 23:10:31 +08:00
yumaojun
e0aaba2cf5 no change... 2015-11-30 23:08:30 +08:00
ibuler
4b36fc540d role推送基本完成 2015-11-30 23:04:02 +08:00
yumaojun
7cafbde5b1 update sudo 2015-11-30 22:55:40 +08:00
ibuler
7106e915ef modify sudo 2015-11-30 19:51:34 +08:00
ibuler
f7c8ad6f38 修改推送用户 2015-11-30 19:06:25 +08:00
Alex Wang
3f451158f0 add choose group to execute commands. 2015-11-30 15:15:05 +08:00
ibuler
8dd4a9fce1 push role 更改 2015-11-29 19:02:13 +08:00
ibuler
52c4395b68 去掉runas 2015-11-29 16:56:39 +08:00
ibuler
49fbae4fad Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-29 16:38:48 +08:00
ibuler
2d91f1ab38 校验推送 2015-11-29 16:38:40 +08:00
yumaojun
4d844548c2 fixed merge... 2015-11-29 15:50:36 +08:00
ibuler
29e1090d2c sudo添加runas 2015-11-29 15:18:05 +08:00
ibuler
98f0655da4 fix rule and role bug 2015-11-29 11:33:19 +08:00
yumaojun
b241d6d148 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-11-28 23:00:40 +08:00
yumaojun
b7d9e41b43 1. 修复角色推送 step3 失败 2015-11-28 22:54:59 +08:00
ibuler
3f000b9d54 修改role添加显示 2015-11-28 22:53:27 +08:00
ibuler
4672884255 修改role添加显示 2015-11-28 22:45:40 +08:00
ibuler
a0ae7ff139 修改getresource 2015-11-28 22:08:47 +08:00
ibuler
8ac369b925 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-28 21:23:01 +08:00
ibuler
117f01e71f 中文播放bug fix 2015-11-28 21:13:44 +08:00
yumaojun
38416fbebb merge perm 2015-11-28 21:02:23 +08:00
yumaojun
39a0350e08 1. 完成Sudo 规则的 角色授权
2. 角色详情里面 新增 推送详情
3. 角色推送 支持计算与叠加
2015-11-28 19:33:21 +08:00
ibuler
a099d2a25a 中文播放bug 2015-11-27 18:51:15 +08:00
ibuler
bd885da179 recoard 特殊字符去掉 2015-11-27 17:53:11 +08:00
ibuler
35db337f79 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-27 16:16:47 +08:00
ibuler
c3f1e0e06e 批量执行命令记录日志 bug fix 2015-11-27 16:16:38 +08:00
ibuler
b64ab276fb 修改批量执行命令2 2015-11-27 13:24:57 +08:00
ibuler
66610fb3e7 修改批量执行命令 2015-11-27 12:20:08 +08:00
halcyon
09dcdfa318 fix some bugs and hehe 2015-11-26 23:42:58 +08:00
ibuler
c574bbcb96 fix date change bug 2015-11-26 23:26:11 +08:00
ibuler
61deed70ad merge with connect 2015-11-26 21:47:37 +08:00
ibuler
601747ac49 fix 2015-11-26 21:01:39 +08:00
ibuler
2afce31e95 删掉添加导航 2015-11-26 20:19:54 +08:00
ibuler
ba08602e20 添加登陆方式 2015-11-26 19:49:23 +08:00
ibuler
19dcf171e6 弹窗title修改 2015-11-26 19:06:17 +08:00
kelianchun_miller
1bbd685a23 update connect.py 2015-11-26 18:19:36 +08:00
ibuler
02c3bc75f3 connect.py 回滚 2015-11-26 17:42:03 +08:00
yumaojun
951467f8ca 1. 新增 PermPush表, 用于记录角色的推送记录
2. 角色权限 以来 sudo 完成。
2015-11-26 17:23:16 +08:00
ibuler
cdfea145d9 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-26 17:18:47 +08:00
kelianchun_miller
431ad2940b update connect.py 2015-11-26 17:17:37 +08:00
ibuler
72b8ac2a50 Merge branch 'bug' into dev 2015-11-26 17:10:25 +08:00
ibuler
d3153e9bb4 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-26 17:10:18 +08:00
ibuler
5045d66c1c fix 2015-11-26 17:10:09 +08:00
kelianchun_miller
e71bbd4122 update connect.py 2015-11-26 14:26:58 +08:00
kelianchun_miller
c4160e1d50 Accept Pull Request #2 : (kelianchun_miller:dev -> jumpserver:dev)
Pull Request: 提交transport和命令解析
Created By: @kelianchun_miller
Accepted By: @kelianchun_miller
URL: https://coding.net/u/jumpserver/p/jumpserver/git/pull/2
2015-11-26 14:25:07 +08:00
ibuler
46245ab4aa fix record bug 2015-11-26 13:21:05 +08:00
kelianchun_miller
8880b5ff4f update connect.py
增加transport连接方式,同时增加了替换符号的命令处理
2015-11-25 19:02:51 +08:00
ibuler
2c0d42e0da fix some bug 2015-11-25 18:59:12 +08:00
kelianchun_miller
1d70a23859 update connect.py 2015-11-25 18:52:18 +08:00
ibuler
0335bc26ca fix rule js bug 2015-11-25 16:37:17 +08:00
ibuler
60166ac008 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-25 16:06:30 +08:00
ibuler
f760df1e34 角色key问题修复 2015-11-25 16:01:07 +08:00
ibuler
6fe6342ca4 角色key问题修复 2015-11-25 14:59:57 +08:00
liuzheng712
175f2702d1 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into NormalUserPageLZ 2015-11-25 14:52:30 +08:00
ibuler
a7db713b1e Merge branch 'exec_cmd' into dev 2015-11-25 10:01:06 +08:00
yumaojun
1a0c9cd4e6 1. 新增 PermSudo表, 用于记录 sudo别名
2. 实现Sudo表对应的 添加,显示,更新,删除页面
3. 添加角色时,需要选择对应的 sudo别名
2015-11-24 22:03:58 +08:00
wangyong
742e56fc5f Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-11-24 19:04:28 +08:00
wangyong
0262d94dd3 fix disk detail bug 2015-11-24 19:04:16 +08:00
ibuler
32d036c2b0 修改setting字段 2015-11-24 17:38:27 +08:00
ibuler
1a63d32fe3 fix bug 2015-11-24 16:31:06 +08:00
ibuler
ec9b00e255 fix bug 2015-11-24 13:37:36 +08:00
ibuler
d7cb549eac Merge branch 'exec_cmd' into dev 2015-11-24 13:31:55 +08:00
ibuler
168157bfe1 fix 2015-11-24 13:31:48 +08:00
ibuler
7cbb7718eb fix bug 2015-11-24 12:03:38 +08:00
ibuler
2d65265fc6 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-24 12:01:02 +08:00
ibuler
30fe9f5236 fix websocket授权 2015-11-24 11:58:42 +08:00
wangyong
49821062fb Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-11-24 11:22:01 +08:00
wangyong
99439be04f add update all button 2015-11-24 11:20:01 +08:00
ibuler
17ccac92ee fix 加密bug 2015-11-24 11:01:54 +08:00
wangyong
dd4c243d7c Merge branch 'cmdb' of https://git.coding.net/jumpserver/jumpserver into cmdb 2015-11-24 09:53:50 +08:00
halcyon
34031bfd6b fix bugs 2015-11-23 23:55:19 +08:00
ibuler
a7a030fedd fix bug 2015-11-23 23:07:58 +08:00
ibuler
4c50551249 fix some bug 2015-11-23 19:15:52 +08:00
ibuler
483ca9677c 资产列表添加连接 2015-11-23 18:39:38 +08:00
ibuler
f00a2e003d Merge branch 'dev' into exec_cmd 2015-11-23 15:36:24 +08:00
ibuler
0b878216ed Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-23 15:34:34 +08:00
ibuler
f49a92e742 webscoket授权 2015-11-23 15:34:28 +08:00
kelianchun_miller
ee218a5fed update connect.py 2015-11-23 12:47:02 +08:00
wangyong
a9196ef149 merge cmdb | add asset update batch and crontab 2015-11-23 11:12:14 +08:00
wangyong
04bf37b52a Merge branch 'cmdb' into dev 2015-11-23 11:06:41 +08:00
wangyong
5a3c11f619 asset update batch and crontab 2015-11-22 23:53:25 +08:00
liuzheng712
c89d43d269 update, now Mac to develop will be all egg pain 2015-11-22 22:20:55 +08:00
ibuler
12f33176bf Merge branch 'dev' into exec_cmd 2015-11-22 21:59:18 +08:00
ibuler
eb779e5bf6 修改run_websocket 2015-11-22 21:59:07 +08:00
ibuler
47ace5d654 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-22 20:47:45 +08:00
ibuler
70db8c69d2 global SSH_FLAG to self.ssh_flag 2015-11-22 20:45:48 +08:00
liuzheng712
962d16172c Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into NormalUserPageLZ 2015-11-22 20:35:03 +08:00
kelianchun_miller
5f9e675d00 update connect.py 2015-11-22 20:29:35 +08:00
ibuler
4cdc7f33ce 添加注释 2015-11-22 20:20:32 +08:00
kelianchun_miller
c359d1e264 update connect.py 2015-11-22 20:20:04 +08:00
kelianchun_miller
0c42d039ff update connect.py 2015-11-22 20:18:33 +08:00
kelianchun_miller
55503c89e9 update connect.py 2015-11-22 19:15:58 +08:00
wangyong
b8cb6f4246 Merge branch 'dev' into cmdb 2015-11-22 18:58:31 +08:00
wangyong
d25e23623a fix bugs 2015-11-22 18:57:47 +08:00
ibuler
a143797ac9 修改gen_resource api 2015-11-22 17:56:38 +08:00
liuzheng712
09de12c02a index show assets, need discussion 2015-11-22 13:04:11 +08:00
liuzheng712
246e8770ac http://localhost:8000/juser/user_detail/?id=5001 fix 2015-11-21 22:40:28 +08:00
liuzheng712
ea059790a9 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into NormalUserPageLZ 2015-11-21 21:24:17 +08:00
liuzheng712
6ae4907520 update 2015-11-21 21:24:01 +08:00
ibuler
5f768444ac Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-21 21:07:39 +08:00
ibuler
93481a98db 完成登陆,批量执行命令流 2015-11-21 19:20:11 +08:00
wangyong
0ebb7c4f9a merge cmdb 2015-11-21 18:37:40 +08:00
wangyong
652ea98a2b alert ip -> hostname 2015-11-21 18:28:25 +08:00
ibuler
877383679c 添加api注释 2015-11-21 14:45:20 +08:00
ibuler
e041a49ad7 添加资产权限查询,添加生成resource文件api 2015-11-21 14:42:53 +08:00
ibuler
dc06426ada 完成授权查询api 2015-11-21 12:41:17 +08:00
ibuler
1478ac18fa 用户和组查询api完成 2015-11-21 11:53:36 +08:00
ibuler
558309599c 添加授权查询api 2015-11-21 00:42:54 +08:00
ibuler
40d1eb37dc Merge branch 'exec_cmd' into dev 2015-11-20 23:12:48 +08:00
ibuler
b8d6c5d007 删除遗留的model SysUser PermLog 2015-11-20 23:12:33 +08:00
ibuler
85a9da0e8a bug fix 2015-11-20 21:59:09 +08:00
ibuler
faa0275700 Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-20 21:48:58 +08:00
ibuler
eea56ea0e5 定义通用模块执行 2015-11-20 21:30:57 +08:00
ibuler
ab313aacd8 定义Command前 2015-11-20 18:42:44 +08:00
yumaojun
a88ee0725d 1. 在授权规则添加页面 通过js 给予用户输入提醒 2015-11-20 14:07:17 +08:00
yumaojun
e57c6a9d2e 1. 在授权规则添加页面 通过js 给予用户输入提醒 2015-11-20 14:03:05 +08:00
liuzheng712
f863f4b7ae 登陆web的密码(如不修改请留空) 2015-11-20 11:26:07 +08:00
liuzheng712
4bbae38150 confirm alert 2015-11-20 11:16:47 +08:00
liuzheng712
31807b674b Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into NormalUserPageLZ 2015-11-20 11:12:10 +08:00
liuzheng712
75fbd9e615 annotation the Asset 2015-11-20 11:08:39 +08:00
liuzheng712
42ec624a91 group add and remove fixed 2015-11-20 11:04:22 +08:00
halcyon
b4c13069c0 batch asset alert 2015-11-20 00:03:36 +08:00
ibuler
6b1b33481c 一些js, setting的KEY_DIR, 下载秘钥鉴定 2015-11-19 23:11:00 +08:00
halcyon
1471e0a247 merge cmdb and hehe 2015-11-19 22:06:12 +08:00
halcyon
a04bb100bf Merge branch 'cmdb' into dev 2015-11-19 22:01:38 +08:00
halcyon
f9b1d3059a fix bugs 2015-11-19 21:58:44 +08:00
ibuler
bddb689e86 merge with exec_cmd 2015-11-19 21:57:17 +08:00
yumaojun
757f7beeaf update merge conflict. 2015-11-19 13:20:27 +08:00
yumaojun
6582ee1624 1. 更新 和 添加 (role 和 rule )操作 以 msg 的方式 刷新页面 2015-11-18 22:32:21 +08:00
yumaojun
04e7073aca 1. fixed ansible api auto load local host file (/etc/ansible/hosts) bug with null list 2015-11-18 19:03:13 +08:00
yumaojun
2ccd072416 1. delete role filed : is_screty_key
2. rule edit page  add selected mark
3. role add page  consider user use_default_auth attribute
4. role password use jumpserver api CRYPTO to crypt
5. fixed ansible api auto load local host file (/etc/ansible/hosts) bug
6. ansible api command and task  interface add pattern  default argument( pattern='*')
2015-11-18 17:16:29 +08:00
ibuler
79ecbc83ae bug fix 2015-11-18 15:23:56 +08:00
ibuler
2a6051ae35 merge with dev 2015-11-18 15:22:26 +08:00
ibuler
cf8e366ae1 修改connect方法 2015-11-18 15:15:08 +08:00
halcyon
d42197db3a fix tower bugs 2015-11-17 23:34:13 +08:00
ibuler
8017b1b479 解决jperm key dir 和 ansible api问题 2015-11-17 23:32:24 +08:00
yumaojun
375a243131 Merge remote-tracking branch 'origin/map_perm' into dev 2015-11-17 22:18:17 +08:00
yumaojun
70e6904eb7 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into dev 2015-11-17 22:17:18 +08:00
ibuler
42745c52df Merge branch 'dev' of git.coding.net:jumpserver/jumpserver into dev 2015-11-17 21:41:31 +08:00
ibuler
8479989ea8 更换nav ico, 修复需要登陆,登陆后跳转到登陆前页面 2015-11-17 21:41:03 +08:00
liuzheng712
ee7675f7ae fix when ./keys/user/ didn't exist bug 2015-11-17 21:06:38 +08:00
liuzheng712
37b91c40b6 url 2015-11-17 20:27:38 +08:00
liuzheng712
4027a87e7f user delete with alert confirm 2015-11-17 20:25:15 +08:00
liuzheng712
84992746de juser/change_info/ fix password can be ignore 2015-11-17 20:06:25 +08:00
liuzheng712
4397819b44 user.update bug fix 2015-11-17 19:55:38 +08:00
liuzheng712
ee443361b9 bug of user.update 2015-11-17 19:51:16 +08:00
ibuler
c00a55619c Update connect.py
去掉compress
2015-11-17 16:43:33 +08:00
yumaojun
e5c1071073 Merge branch 'dev' into map_perm 2015-11-17 14:10:46 +08:00
yumaojun
8d941dc028 update role edit and rule edit 2015-11-17 13:55:13 +08:00
yumaojun
11f6939b85 1. update role and update rule complete. 2015-11-17 13:48:19 +08:00
liuzheng712
1c3b66c1a8 user.update 2015-11-17 11:13:52 +08:00
liuzheng712
a99f024dfc user.update 2015-11-17 11:07:40 +08:00
ibuler
d58ba82388 添加ignore 2015-11-17 10:48:18 +08:00
liuzheng712
738c6353ef user.update 2015-11-17 10:44:34 +08:00
ibuler
dc547de592 修正文件目录 2015-11-17 10:27:41 +08:00
liuzheng712
adf20f188e user.update 2015-11-17 10:16:51 +08:00
liuzheng712
b9b965753b Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into NormalUserPageLZ 2015-11-17 09:53:48 +08:00
liuzheng712
036873e129 merge_dev 2015-11-17 09:53:43 +08:00
yumaojun
9d36dc9e39 1. push role bug , because the password push is mandatory, so just the push key is option. 2015-11-16 23:44:53 +08:00
ibuler
ce02d430ba deal_command添加到静态方法中 2015-11-16 23:33:44 +08:00
ibuler
4abf2b06d8 添加jumpserver.conf 2015-11-16 23:11:37 +08:00
ibuler
2d27e3fee0 恢复修改前 2015-11-16 22:46:36 +08:00
ibuler
67771105ae key目录变化 2015-11-16 22:45:41 +08:00
liuzheng712
de9ce6dd19 select all 2015-11-16 22:28:02 +08:00
ibuler
71ef4b079a Merge branch 'dev' of git.coding.net:jumpserver/Jumpserver into dev 2015-11-16 18:35:31 +08:00
ibuler
f0d901e136 修复分页bug 2015-11-16 18:34:51 +08:00
liuzheng712
d3dd9d94d3 update 2015-11-16 14:59:26 +08:00
liuzheng712
2938f7e506 update 2015-11-16 14:30:10 +08:00
liuzheng712
1f5fa9a9bd merge 2015-11-16 14:21:21 +08:00
liuzheng712
96ac65b346 udpate 2015-11-16 14:09:02 +08:00
yumaojun
c00e4c24a3 app jperm role and rule bug fixed... 2015-11-16 13:49:39 +08:00
yumaojun
844fe2c250 add asset ok ,pull 2015-11-15 23:43:19 +08:00
yumaojun
6da97c5403 merge dev ... 2015-11-15 23:30:37 +08:00
wangyong
1e41b79611 fix merge bug 2015-11-15 23:29:31 +08:00
ibuler
5d33493233 asset js 2015-11-15 23:21:59 +08:00
ibuler
38c65dbea8 暂时去掉普通用户的get.asset 2015-11-15 23:19:50 +08:00
yumaojun
218ba0d189 merge ... 2015-11-15 22:20:19 +08:00
yumaojun
a36294a529 new map 2015-11-15 22:12:28 +08:00
广宏伟
333ee713d4 解决分页bug,和random_pass 2015-11-15 18:20:34 +08:00
广宏伟
b8ae0ed565 some bug fix 2015-11-15 17:01:02 +08:00
ibuler
3b07198b8a merge with cmdb 2015-11-15 19:57:25 +08:00
yumaojun
8b94833ea0 1. role push function use password and public key completed 2015-11-15 12:38:57 +08:00
yumaojun
0862ffef98 merge map 2015-11-15 08:39:43 +08:00
yumaojun
95dc12a71b update models 2015-11-14 23:17:05 +08:00
wangyong
0f29745bfa asset add batch 2015-11-14 23:09:13 +08:00
yumaojun
012950cb68 merge update... 2015-11-14 23:07:08 +08:00
ibuler
f9c06c22ae 修改变量命名 2015-11-14 22:57:34 +08:00
yumaojun
83c2704d53 1. update role push 2015-11-14 22:54:29 +08:00
yumaojun
74b6b4dea2 1. rule push page completed 2015-11-14 21:52:09 +08:00
yumaojun
f6bc03324f 1. rule operations list add delete edit info page compeleted
2. rule operations list add delete edit info page compeleted
2015-11-14 21:13:02 +08:00
kelianchun_miller
3d4443e1b0 update connect.py
命令处理进一步处理
2015-11-14 11:45:56 +08:00
kelianchun_miller
366a5d5737 update connect.py 2015-11-14 11:24:31 +08:00
yumaojun
6d5d279f61 1. 增加授权规则的添加,删除,编辑,详情页面。
2. 修改nav.html中关于授权部分页面。
3. 修改Jasset APP 下的 view,使得数据库中存储的密码是明文。
2015-11-14 10:16:48 +08:00
ibuler
20970db404 修复环境变量大小写,修改terminal类 2015-11-13 21:15:41 +08:00
yumaojun
1eff4ab4ff add edit, detail page 2015-11-13 17:17:22 +08:00
yumaojun
1aed3b4d91 modify add rule html 2015-11-13 13:21:57 +08:00
yumaojun
9379bc1f6e merge failed, update.... 2015-11-13 13:06:17 +08:00
yumaojun
9ec2b9ff1d merge filed, update files... 2015-11-13 12:50:21 +08:00
yumaojun
4bfe326868 ansible api add get_host_info in Class Tasks 2015-11-13 00:34:32 +08:00
yumaojun
6074bb033d ansible api add get_host_info in Class Tasks 2015-11-13 00:31:27 +08:00
halcyon
ec7b543bf2 Merge branch 'cmdb' of https://git.coding.net/jumpserver/jumpserver into cmdb 2015-11-13 00:06:15 +08:00
halcyon
b7c3cc5532 add idc 2015-11-13 00:03:51 +08:00
Zi Chuanxiu
1c3d642be2 fixed ansible command variables bug. 2015-11-10 19:55:12 +08:00
Zi Chuanxiu
a2f84e943a update ansible api 2015-11-10 17:46:44 +08:00
ibuler
4ae36d319c 修复用户信息显示bug 2015-11-10 16:14:32 +08:00
ibuler
7fe0bb21b2 修改无日志记录提示 2015-11-10 16:00:05 +08:00
ibuler
0174da6c77 修改index页面 2015-11-10 15:50:35 +08:00
root
3d6d714495 asset alert history 2015-11-10 00:11:54 +08:00
ibuler
adc3703fba 添加绘图 2015-11-10 00:02:56 +08:00
wangyong
6de253df58 delete xlsx 2015-11-09 21:04:47 +08:00
ibuler
f31bea2c70 使用echart 2015-11-09 19:19:28 +08:00
liuzheng712
b61286891f update 2015-11-09 17:12:57 +08:00
liuzheng712
6db7642331 Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into NormalUserPageLZ 2015-11-09 16:58:55 +08:00
ibuler
91b5d039cc 修改邮件settings 2015-11-09 16:28:10 +08:00
ibuler
5692e9dc86 添加资产的默认设置 2015-11-09 11:56:31 +08:00
ibuler
7849ff2b92 解决搜索分页问题 2015-11-09 10:53:15 +08:00
halcyon
e77ec102d9 just do it 2015-11-08 22:39:30 +08:00
ibuler
7ea23e0fcc 修复无法终结web进程的bug 2015-11-08 12:01:08 +08:00
ibuler
e60a3a697e 添加测试web terminal按钮 2015-11-07 17:41:16 +08:00
ibuler
d899360c34 增加websocket认证 2015-11-07 17:32:32 +08:00
ibuler
98c4d9bdba web terminal kill方法 2015-11-07 15:27:49 +08:00
ibuler
24730ebd0f web terminal记录日志 2015-11-07 13:38:50 +08:00
liuzheng712
cab346686d update 2015-11-07 10:27:55 +08:00
liuzheng712
d369d4b50f Merge branch 'jlog' of https://git.coding.net/jumpserver/jumpserver into NormalUserPageLZ
# Conflicts:
#	jumpserver/views.py
#	juser/models.py
#	juser/views.py
#	templates/jperm/perm_apply.html
2015-11-07 09:37:10 +08:00
liuzheng712
6897d063c2 error = '用户未激活' 2015-11-07 09:09:36 +08:00
liuzheng712
4ddddc134a 禁用 change to 启用 2015-11-06 23:13:02 +08:00
liuzheng712
44a330ac02 download page: waiting... 2015-11-06 23:04:09 +08:00
liuzheng712
f220ea367e upload file with user id path 2015-11-06 22:26:19 +08:00
ibuler
43c0770770 使用原生select 2015-11-06 12:09:23 +08:00
Zi Chuanxiu
82286ea7ed fix set host vars and add set group vars 2015-11-06 11:32:59 +08:00
ibuler
01d6f751b1 解决实时监控特殊字符,使用term.js 2015-11-06 10:42:10 +08:00
liuzheng712
7a25f348e4 upload file: save a copy in ./upload/%Y/%M/%D/. TODO: distinguish userID 2015-11-06 00:56:16 +08:00
liuzheng712
12a0a35adf upload page: need to fix click problem, want to show the list of machines, TODO 2015-11-06 00:21:59 +08:00
Zi Chuanxiu
0f8abb6026 update 2015-11-05 22:53:19 +08:00
Zi Chuanxiu
8e2f3fdecd update 2015-11-05 22:52:02 +08:00
Zi Chuanxiu
26e3634814 mapping model 2015-11-05 22:47:45 +08:00
ibuler
9a897e0cf4 修正导入select错误 2015-11-05 20:07:21 +08:00
ibuler
1bc15e57a6 完成webtermial demo 2015-11-05 18:31:00 +08:00
liuzheng712
09087a4d8f set user password , if you don't want to change the password , leave password empty 2015-11-05 14:30:59 +08:00
liuzheng712
6934380b9c jperm/perm_apply.html 2015-11-05 13:16:23 +08:00
ibuler
618aed3278 移动api中关于tty到connect.py 2015-11-04 17:04:25 +08:00
ibuler
c8c0061244 添加权限鉴定 2015-11-04 16:24:52 +08:00
ibuler
ad4b68a390 Merge branch 'jlog' of git.coding.net:jumpserver/Jumpserver into jlog 2015-11-04 15:21:44 +08:00
kelianchun_miller
a95e313733 update api.py 2015-11-04 15:20:28 +08:00
ibuler
8b25d3e32e Merge branch 'jlog' of git.coding.net:jumpserver/Jumpserver into jlog 2015-11-04 15:15:03 +08:00
ibuler
a0a7623743 修复log kill和在线查看命令统计 2015-11-04 15:11:14 +08:00
kelianchun_miller
5e20ac0454 update api.py 2015-11-04 14:56:50 +08:00
kelianchun_miller
d182736bd7 update api.py 2015-11-04 14:50:47 +08:00
root
159398b391 fix bugs 2015-11-03 23:53:12 +08:00
ibuler
e4ccb1c43f 修复日志打印的异常bug 2015-11-03 23:21:33 +08:00
ibuler
9d75ad6cea 多线程修复监控阻塞bug 2015-11-03 23:03:31 +08:00
ibuler
b30697ea20 基本完成 2015-11-03 19:12:15 +08:00
wangyong
0c0f05b6d9 jasset base 2015-11-03 17:07:46 +08:00
ibuler
50d21fcdca for log monitor 2015-11-02 23:20:40 +08:00
Zi Chuanxiu
c49a02d1c5 update ansible_api, and update perm_list_user view 2015-11-02 23:07:04 +08:00
Zi Chuanxiu
c26594a3ec update ansible_api, and update perm_list_user view 2015-11-02 23:05:19 +08:00
Zi Chuanxiu
6572e6f10e update ansible_api, and update perm_list_user view 2015-11-02 23:03:41 +08:00
liuzheng712
5144907ec0 there is no need to set the password value, very change user info needs password, make sure this is legal 2015-11-02 16:00:34 +08:00
liuzheng712
ba8ed23292 add the @login_required(login_url='/login') 2015-11-02 15:51:18 +08:00
liuzheng712
6583b0f530 change the login response redirect 2015-11-02 15:50:46 +08:00
liuzheng712
a3bea76994 juser/urls.py format 2015-11-02 15:49:05 +08:00
ibuler@qq.com
ebe8ce7109 some 2015-11-02 11:18:06 +08:00
Zi Chuanxiu
df9d879f22 ansible api base complete... 2015-10-31 11:55:19 +08:00
halcyon
46b1aca5f1 model 2015-10-31 09:23:10 +08:00
Zi Chuanxiu
dd4ac4e6d6 Task add method push_key 2015-10-30 23:14:45 +08:00
root
fe23e61036 Task add method push_key 2015-10-30 23:08:45 +08:00
root
b88c4211b2 update ansible_api.py 2015-10-30 08:25:22 +08:00
root
9e0d1a7285 add ansible_api module 2015-10-29 16:32:02 +08:00
广宏伟
73f94fecb5 fix import some bug 2015-10-29 12:01:03 +08:00
ibuler@qq.com
0e24ebdb26 merge with dev 2015-10-29 11:11:05 +08:00
广宏伟
d5bd2143e2 命令搜素完成 2015-10-28 22:32:16 +08:00
root
7d412e4c18 update configure file 2015-10-28 22:30:34 +08:00
liuzheng712
ac5ac5e06b change role finished , but need more think 2015-10-28 21:03:54 +08:00
ibuler@qq.com
53e4dc7acb search detail 2015-10-28 19:24:02 +08:00
liuzheng712
4d3e7d694b lots 2015-10-28 10:55:25 +08:00
liuzheng712
ca271900e6 remove request.session user_id and role_id, about role_id need more think, now is dirty 2015-10-27 23:57:37 +08:00
liuzheng712
f8c8c3deff update 2015-10-27 23:34:38 +08:00
ibuler@qq.com
76ad67307b search ok 2015-10-27 23:18:26 +08:00
ibuler@qq.com
ffab7ae697 some 2015-10-27 20:25:18 +08:00
wangyong
8909386d0c models 2015-10-27 20:13:23 +08:00
liuzheng712
8e9f22537f reuse asset_list for host_list 2015-10-27 17:40:53 +08:00
广宏伟
9366003f7b jlog 2015-10-26 22:17:16 +08:00
蓝枫
9018536651 Merge pull request #21 from shadowzey/master
页面错误修复
2015-10-26 11:42:08 +08:00
zyan
ec8ef4d1d7 Update idc_detail.html
修复IDC详情页面显示错误
2015-10-26 10:35:50 +08:00
ibuler@qq.com
72a18d6abf use map 2015-10-24 23:52:06 +08:00
ibuler@qq.com
79e81340dc modify log 2015-10-21 22:39:53 +08:00
ibuler@qq.com
4baffed481 base commit 2015-10-21 21:19:18 +08:00
广宏伟
77131a39d4 recovery playboo_run 2015-10-21 20:53:07 +08:00
广宏伟
40d00f7cbd lost playboo_run 2015-10-21 20:44:28 +08:00
ibuler@qq.com
fe1f825fdf perm edit 2015-10-19 23:40:16 +08:00
shadowzey
64973e43de 修复从查看部门页面进入主机列表点击详情404错误 2015-10-13 17:19:47 +08:00
蓝枫
e284584506 Merge pull request #20 from shadowzey/master
捕获添加用户邮箱填写错误时邮件发送失败的异常
2015-10-13 16:55:13 +08:00
严泽
0667067c0c 捕获添加用户邮箱填写错误时邮件发送失败的异常 2015-10-13 16:36:16 +08:00
ibuler@qq.com
50d2bfb272 someday 2015-10-12 09:58:38 +08:00
ibuler@qq.com
06eedff49f fix common 2015-10-07 20:14:07 +08:00
ibuler@qq.com
afbbad1604 授权管理 2015-10-07 17:16:20 +08:00
liuzheng712
9d5c4dbb33 juser/user_list change user password fix 2015-10-07 12:36:20 +08:00
liuzheng712
ce90472624 juser/user_list change user password fix 2015-10-07 12:31:40 +08:00
liuzheng712
85dcc8ba63 WARNINGS:
jlog.Log.pid: (fields.W122) 'max_length' is ignored when used with IntegerField
        HINT: Remove 'max_length' from field
2015-10-07 12:20:59 +08:00
liuzheng712
c9e192fae4 recovery User's function 2015-10-07 12:17:20 +08:00
liuzheng712
cee8b2d787 rollback jumpserver/views.py 54 : user = get_object() part and delete useless 'class CustomUser' 2015-10-07 12:01:14 +08:00
ibuler@qq.com
d3465be672 修改Ignore 2015-10-06 23:48:15 +08:00
ibuler@qq.com
e99b33c51e 修改使用新表结构 2015-10-06 23:47:53 +08:00
Administrator
43fe985143 添加组授权 2015-10-06 18:51:49 +08:00
Administrator
699046dad5 修改settings 2015-10-05 23:48:03 +08:00
guanghongwei
6482a5e214 add ignore 2015-10-04 21:51:23 +08:00
guanghongwei
fef3879c85 rm tmpfile 2015-10-04 21:50:51 +08:00
guanghongwei
9f7b066ca6 shouquanxiugai 2015-10-04 21:50:29 +08:00
liuzheng712
02218e624a lots 2015-10-04 19:07:42 +08:00
liuzheng712
5a5928483f lots 2015-10-04 00:53:01 +08:00
liuzheng712
11b3cee346 gitignore 2015-10-03 22:50:05 +08:00
蓝枫
949065be2c Update connect.py
修正vim颜色
2015-10-01 16:25:17 +08:00
蓝枫
6168ab270f Merge pull request #19 from IYism/master
bugfix:connect.py log_online.html
2015-09-25 17:20:48 +08:00
IYism
667862223c bugfix
修复chrome浏览器有时候不能阻断的bug
2015-09-25 16:33:11 +08:00
IYism
2f5cf429ed bugfix ip_list
bugfix ip_list
2015-09-25 16:30:15 +08:00
liuzheng712
7a94724dbc initial_data_test 2015-09-24 09:43:28 +08:00
liuzheng712
79c79432f5 usermodle 2015-09-15 23:38:06 +08:00
ibuler
d32ea9f9a1 授权管理 2015-09-11 00:04:07 +08:00
ibuler
907c2c7e97 资产修改基本完成 2015-09-10 22:51:42 +08:00
ibuler
960e45d0fa 添加asset_api 2015-09-09 00:19:36 +08:00
ibuler
8bf9103fcf 修改资产管理 2015-09-09 00:19:17 +08:00
ibuler
4eb78e151e 用户模块修改告一段落 2015-09-06 21:37:22 +08:00
ibuler
3efd810fe1 修改修改用户bug 2015-09-02 21:42:31 +08:00
ibuler
c21cdc2131 添加忘记密码 2015-08-31 23:04:53 +08:00
蓝枫
a4ac98332b Merge pull request #15 from xiaopeng163/master
Delete .DS_Store file
2015-08-31 10:32:06 +08:00
Peng Xiao
073e7b36fa Delete .DS_Store file
.DS_Store is the name of a file in the Apple OS X operating system for storing custom attributes of a folder such as the position of icons or the choice of a background image.
2015-08-31 10:28:54 +08:00
ibuler
44c69ded78 干掉ldap前 2015-08-30 14:03:10 +08:00
root
1e170714c0 修改用户添加视图 2015-08-29 00:09:36 +08:00
ibuler
f47cddbd5c 修改cpu占用问题 2015-08-28 10:04:07 +08:00
ibuler
1387e29591 解决cpu占用过大问题 2015-08-28 09:58:20 +08:00
ibuler
10d96a9767 修改用户组视图 2015-08-28 00:33:54 +08:00
ibuler
fd5041965b 分离juser方法 2015-08-27 00:08:45 +08:00
ibuler
33c624c76f 删除部门后 2015-08-27 00:08:20 +08:00
ibuler
913f93b91f 删除部门前 2015-08-26 23:31:32 +08:00
蓝枫
d34ec00a3a Merge pull request #14 from pengyao/master
exact match, thanks for pengyao
2015-08-26 16:12:36 +08:00
pengyao
e9c6924530 exact match 2015-08-26 16:06:22 +08:00
ibuler
c1facb939e 优化connect.py排序 2015-08-22 00:01:54 +08:00
ibuler
ad16d8b532 优化connect.py 和 api.py 2015-08-21 23:45:41 +08:00
Guang
9f0620f97e 调整User,UserGroup类 2015-08-20 23:42:27 +08:00
蓝枫
a040b1c181 Update connect.py
fix cpu used 100%
2015-07-21 10:26:49 +08:00
蓝枫
8121e4942b Merge pull request #13 from ljjjustin/master
fix error url in host search page
2015-07-08 19:20:00 +08:00
Jiajun Liu
f5e57da106 fix line break bug on add multiple hosts 2015-07-07 18:12:25 +08:00
Jiajun Liu
b8dfb26a3a fix error url in host search page 2015-07-07 17:44:12 +08:00
蓝枫
079338f89d Merge pull request #12 from ljjjustin/master
fix user can not get login logs bug
2015-07-07 17:13:18 +08:00
Jiajun Liu
627d627995 fix user can not get login logs bug 2015-07-07 16:59:24 +08:00
Jiajun Liu
19343540b9 fix line break bug
some system user '\n\r' as line break, if we split commands by '\n',
then '\r' will be considered as part of commands which will break sudo
authentication. we can use splitlines function to avoid the problem.
2015-07-07 16:59:24 +08:00
Jiajun Liu
915adb2fd3 fix user can not get permission applies bug 2015-07-07 16:59:21 +08:00
ibuler
c25cd3c005 Merge remote-tracking branch 'remotes/github/master' 2015-07-03 21:29:25 +08:00
ibuler
32ab051bbc modify cmd_group num bug 2015-07-03 21:27:20 +08:00
ibuler
f7e70e56e3 modify sudo conn timeout bug 2015-07-03 21:09:17 +08:00
ibuler
9e52e6a320 modify some 2015-07-03 20:45:45 +08:00
ibuler
f3a0c390b1 connect.py base ok 2015-06-16 09:21:11 +08:00
ibuler
bb32c0480c dev 2015-06-15 23:00:19 +08:00
ibuler
8d167baf46 modify some 2015-06-15 19:20:05 +08:00
蓝枫
acfa0171ca Update log_offline.html
a small bug
2015-06-15 16:06:12 +08:00
ibuler
fdcaa358e5 modify some api.py bug 2015-06-13 00:36:10 +08:00
ibuler
ce8e1e0ae3 Merge remote-tracking branch 'remotes/github/master' 2015-06-11 14:05:16 +08:00
ibuler
7cb4ff97ea modify cmd_edit bug 2015-06-11 14:01:49 +08:00
ibuler
5d16836b05 modify connect.py 2015-06-10 23:16:24 +08:00
ibuler
fc22677f3f modify some 2015-06-09 23:06:32 +08:00
蓝枫
787a2591c4 Update layer.min.js
update url
2015-06-09 16:30:59 +08:00
ibuler
95cc2830c8 resolve kill process bug 2015-06-09 09:49:31 +08:00
ibuler
5bae8245bd modify source ip bug 2015-06-09 09:32:35 +08:00
ibuler
e979c2753b modify 1 2015-06-08 23:46:40 +08:00
ibuler
dcfd4e05ec modify sudo cmd bug 2015-06-04 10:15:41 +08:00
ibuler
1662269153 websocket auth add 2015-05-28 17:00:03 +08:00
ibuler
ce99bf2266 placeholder 2015-05-25 18:35:32 +08:00
ibuler
1952d1ca23 modify sudo show 2015-05-25 18:27:57 +08:00
ibuler
bf80799fb6 modify port type 2015-05-25 17:13:08 +08:00
ibuler
38f89042ac modify single user login bug 2015-05-25 14:16:08 +08:00
ibuler
67b2467bc9 Merge branch 'guanghongwei' 2015-05-25 10:10:49 +08:00
ibuler
345be469fa Merge branch 'wangyong' 2015-05-25 10:07:25 +08:00
halcyon
04522c0b80 修改port字段 2015-05-25 10:03:55 +08:00
蓝枫
4a9e002440 Merge pull request #6 from losswei/master
修复当用户使用Ctrl+C结束进程时,没有正确退出
2015-05-22 17:24:46 +08:00
何威
6998036bdc 修复当用户使用Ctrl+C结束进程时,没有正确退出 2015-05-22 17:18:37 +08:00
ibuler
e09cb10439 modify a bug with 10.0.0.1 10.0.0.11 10.0.0.12 match problem 2015-05-18 17:22:26 +08:00
ibuler
caa318b808 modify a bug with 10.0.0.1 10.0.0.11 10.0.0.12 match problem 2015-05-18 16:40:36 +08:00
ibuler
58fd4374c7 Merge branch 'wangyong' 2015-05-15 12:01:51 +08:00
ibuler
f89d444ddf modify requirements.txt 2015-05-15 11:53:31 +08:00
root
49bee0c3fd 修改主机添加或者修改没添加进ALL组bug 2015-05-14 18:02:20 +08:00
ibuler
00f7346578 resolve connect.py string start with g bug 2015-04-28 16:54:58 +08:00
ibuler
b1add204b6 ޸ʾ 2015-04-28 15:08:28 +08:00
ibuler
6d34bd45d2 modify nav_bar_header.html 2015-04-24 20:42:15 +08:00
ibuler
992947ac99 modify service.sh bug 2015-04-24 20:39:44 +08:00
ibuler
ba55cdde87 modify service.sh bug 2015-04-24 19:12:14 +08:00
ibuler
c01a489dce modify service.sh bug 2015-04-24 18:19:43 +08:00
ibuler
0beb683c40 Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver 2015-04-23 11:23:05 +08:00
root
b134c90bfd 解决阻断报错问题 2015-04-23 11:20:12 +08:00
ibuler
6c10cf1a5a Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver 2015-04-22 18:58:26 +08:00
ibuler
311b65da00 ޸bug 2015-04-22 18:57:55 +08:00
halcyon
8a8f68d908 使用username 去掉log_ha里的print 2015-04-22 18:04:23 +08:00
halcyon
b7aa1ab3dc jperm问题 2015-04-22 17:50:46 +08:00
halcyon
27d6df7a38 解决django低版本不支持first()问题 2015-04-21 14:45:38 +08:00
ibuler
8f7e1bfc38 modify readme 2015-04-20 22:55:26 +08:00
ibuler
7accf70e17 ӽű 2015-04-20 21:17:16 +08:00
ibuler
e2ac212fc3 resolve confilict 2015-04-20 20:56:26 +08:00
ibuler
09d3763a02 fix a bug 2015-04-20 20:54:10 +08:00
ibuler
ea37374ea5 django 1.6 2015-04-20 18:56:30 +08:00
ibuler
a203b89ad4 Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver 2015-04-20 15:57:33 +08:00
ibuler
0a8198b2ca ޸Ƴbug 2015-04-20 15:57:10 +08:00
ibuler
d84ff97019 ޸Ƴbug 2015-04-20 15:56:49 +08:00
ibuler
412dadce76 version 2.0.0 beta 2015-04-20 10:12:11 +08:00
halcyon
b65f620ff7 hehe 2015-04-19 23:14:51 +08:00
ibuler
8b50e5252f merge with wangyong 2015-04-19 18:45:07 +08:00
ibuler
76b1bf2c39 Խűȥע 2015-04-19 18:39:15 +08:00
halcyon
86e334e4fa last bug? 2015-04-19 18:36:41 +08:00
ibuler
17e89bb55b ޸һbug 2015-04-19 18:26:38 +08:00
ibuler
d5fba23d73 ȨҳûҳӵȨб 2015-04-19 00:23:35 +08:00
ibuler
e96053ba20 ޸ 2015-04-18 19:15:53 +08:00
ibuler
c8d91884c8 Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver
Conflicts:
	jumpserver/api.py
2015-04-18 18:06:17 +08:00
halcyon
bd2d7ce007 hehe 2015-04-18 18:04:03 +08:00
ibuler
6d6e9d97b5 ޸ 2015-04-18 18:04:01 +08:00
ibuler
9ab855fd92 merge 2015-04-18 17:00:03 +08:00
ibuler
c1d8de4558 ϲ 2015-04-18 16:58:16 +08:00
halcyon
f19b274fcc bug 2015-04-18 16:58:15 +08:00
ibuler
0873211d13 Merge branches 'guanghongwei' and 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei 2015-04-18 14:02:57 +08:00
ibuler
bcc5774365 ӳɹҳ 2015-04-18 13:52:28 +08:00
halcyon
84929840d0 bug 2015-04-18 13:51:47 +08:00
ibuler
d6171f7fe7 merge 2015-04-18 12:37:55 +08:00
ibuler
9acba2ddf0 ɾûõ 2015-04-18 12:36:16 +08:00
halcyon
75e1ea7f7d bug 2015-04-18 12:30:45 +08:00
ibuler
4f1b4f1947 ޸bug 2015-04-17 22:22:21 +08:00
halcyon
a269c43d1c 优化 2015-04-16 19:03:02 +08:00
ibuler
83938e10b2 Merge branches 'guanghongwei' and 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei 2015-04-16 15:13:45 +08:00
ibuler
0d1d64e83c ޸ļ 2015-04-16 15:13:22 +08:00
halcyon
75c8e44575 bugs 2015-04-16 15:10:46 +08:00
halcyon
29d196410e Merge branch 'master' into wangyong 2015-04-16 14:34:49 +08:00
ibuler
e2e131146d Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver 2015-04-16 14:33:55 +08:00
ibuler
60cb5561f0 ޸move 2015-04-16 14:32:51 +08:00
halcyon
55c5230eb2 hehe 2015-04-16 14:32:48 +08:00
halcyon
da4d6b85fc bugs 2015-04-15 18:47:02 +08:00
guanghongwei
c08cee8052 û 2015-04-15 17:32:30 +08:00
guanghongwei
3424bef5d0 ޸bug 2015-04-15 12:07:59 +08:00
halcyon
e72e30bc4e bug 2015-04-14 21:06:19 +08:00
halcyon
99293cc019 bug 2015-04-14 20:09:11 +08:00
halcyon
3bfe0e3c16 bugs 2015-04-14 17:25:56 +08:00
halcyon
4abf25ef13 hehe 2015-04-13 21:25:43 +08:00
halcyon
e385f3e09d Merge branch 'master' into wangyong 2015-04-11 19:57:20 +08:00
halcyon
a4bd352486 idc 2015-04-11 19:56:53 +08:00
guanghongwei
6a565d0a45 reslove 2015-04-11 17:49:41 +08:00
root
2e254af935 hehe 2015-04-11 17:45:49 +08:00
guanghongwei
12df8cf060 ޸ 2015-04-11 17:45:33 +08:00
guanghongwei
3c1af0e266 Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver 2015-04-11 12:53:22 +08:00
guanghongwei
3b00cfa97d ޸ĸbug 2015-04-11 12:52:17 +08:00
halcyon
9cfe6c569d hehe 2015-04-11 12:52:00 +08:00
guanghongwei
78f00e5c5f ϴļ 2015-04-09 23:49:21 +08:00
guanghongwei
30fd160079 upload and resove 2015-04-09 13:55:16 +08:00
halcyon
3842f7795b hehe 2015-04-09 11:48:53 +08:00
guanghongwei
419ee2660a Merge branches 'guanghongwei' and 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei
Conflicts:
	jumpserver/urls.py
	jumpserver/views.py
2015-04-09 11:32:32 +08:00
guanghongwei
ff77cc28fa ϴ 2015-04-09 11:27:36 +08:00
halcyon
d28d72c42d bugs 2015-04-09 11:09:18 +08:00
guanghongwei
2b14fefb5c ޸ҳ 2015-04-08 18:08:39 +08:00
guanghongwei
25ce24a17d Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver
Conflicts:
	jasset/views.py
	jumpserver/views.py
2015-04-08 17:39:00 +08:00
guanghongwei
b840db12a6 Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver
Conflicts:
	jasset/views.py
	jumpserver/views.py
2015-04-08 17:38:30 +08:00
guanghongwei
2035a49c40 ޸Կkey, ͨûҳ 2015-04-08 17:32:56 +08:00
halcyon
bb94cfc7a1 完善 2015-04-08 17:31:07 +08:00
halcyon
ef63fce7c4 修改bug,实时搜索完成 2015-04-07 19:15:45 +08:00
guanghongwei
bd0fd90e2d ûͨû 2015-04-06 23:04:31 +08:00
halcyon
7de943c6e4 管理员仪表盘基本完成 2015-04-05 22:52:37 +08:00
halcyon
17be0bb39e dashboard and api 2015-04-05 17:52:46 +08:00
guanghongwei
7e53228359 Merge branches 'guanghongwei' and 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei 2015-04-04 12:48:56 +08:00
guanghongwei
afcc784797 ޸û 2015-04-04 12:48:26 +08:00
halcyon
6e976b0583 0406 2015-04-04 12:47:07 +08:00
guanghongwei
8f66de365e merge with wangyong 2015-04-02 20:40:54 +08:00
halcyon
b35f1e6174 权限申请 2015-04-02 18:32:43 +08:00
guanghongwei
a998de5973 ޸û 2015-04-01 22:54:10 +08:00
halcyon
e1b9134d7f 0402 2015-04-01 18:58:10 +08:00
蓝枫
544bc10997 Update views.py
修改查看权限列表和添加权限列表不一致的bug
2015-03-31 21:07:50 +08:00
guanghongwei
2e5b22417d л 2015-03-30 21:31:02 +08:00
guanghongwei
38445a1dd2 Ұ 2015-03-27 18:37:10 +08:00
guanghongwei
340aaf42de ˢ 2015-03-27 16:34:00 +08:00
halcyon
359f70b9f9 apply 2015-03-26 18:42:52 +08:00
halcyon
408e4a54d8 bugs 2015-03-25 19:02:14 +08:00
guanghongwei
59414dadfc ˢsudosudoûȨ 2015-03-25 18:45:55 +08:00
halcyon
e3b2be0261 bugs 2015-03-24 18:34:00 +08:00
halcyon
6816f941d9 Merge branch 'guanghongwei' into wangyong 2015-03-24 17:05:17 +08:00
halcyon
1dddd98741 bug 2015-03-24 17:04:25 +08:00
guanghongwei
0c31968e3c 2015-03-23 22:57:19 +08:00
guanghongwei
2f7e7b0072 ޸nav.html 2015-03-21 15:08:16 +08:00
guanghongwei
d8a6eba2f3 Merge branches 'guanghongwei' and 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei
Conflicts:
	connect.py
	jumpserver.conf
	jumpserver/api.py
2015-03-21 13:10:38 +08:00
guanghongwei
18b6e25cf3 ɾûõ 2015-03-21 13:00:12 +08:00
halcyon
df2c2fc7d5 zhoumo 2015-03-21 12:58:29 +08:00
guanghongwei
e717fad762 ȵ 2015-03-19 23:57:08 +08:00
halcyon
fef224459c 鉴权 2015-03-19 18:32:10 +08:00
halcyon
9348a0deb7 鉴权 2015-03-18 18:05:46 +08:00
root
fa0ec1e7d7 connect 2015-03-17 23:20:25 +08:00
halcyon
98dfebc3aa jlog 2015-03-17 17:18:41 +08:00
halcyon
92ccd3dc78 jlog 2015-03-17 16:25:32 +08:00
halcyon
a9a0b4ee49 bugs 2015-03-17 15:40:52 +08:00
halcyon
5668794171 bugs 2015-03-17 15:31:23 +08:00
halcyon
6759146426 bugs 2015-03-17 15:28:48 +08:00
halcyon
d24cfeeabc bugs 2015-03-17 14:22:35 +08:00
halcyon
a36c8599e7 bugs 2015-03-17 14:12:49 +08:00
halcyon
9e1dd270ae bugs 2015-03-17 13:56:43 +08:00
guanghongwei
386d6a1cb2 2015-03-16 22:38:42 +08:00
guanghongwei
a2ede31ae6 Ȩʼ 2015-03-15 23:23:20 +08:00
guanghongwei
f3ae7f00a0 ʱ 2015-03-14 23:57:53 +08:00
guanghongwei
56df1f6963 merge 2015-03-14 17:57:26 +08:00
halcyon
78dc6e5154 bugs 2015-03-14 17:54:27 +08:00
guanghongwei
026836ebc5 2015-03-14 17:54:17 +08:00
guanghongwei
d926cbdef2 merge with wangyong 2015-03-14 13:20:53 +08:00
guanghongwei
d1f19a5cad ޸IJʾ 2015-03-14 13:15:33 +08:00
halcyon
ce6494ba64 bugs 2015-03-14 13:13:46 +08:00
guanghongwei
b2c72221f7 2015-03-13 23:46:38 +08:00
guanghongwei
5749276812 Ȩ޹ 2015-03-13 18:36:35 +08:00
guanghongwei
a7800b9a7a Ȩ޹ 2015-03-13 00:09:18 +08:00
halcyon
691271c74f bugs 2015-03-12 18:54:26 +08:00
guanghongwei
475501595e ҳ 2015-03-12 18:43:17 +08:00
halcyon
fd490bd685 bugs 2015-03-12 11:03:53 +08:00
guanghongwei
546393d9c3 Ȩ޸ 2015-03-11 23:46:35 +08:00
halcyon
75f06f9b62 bugs 2015-03-11 18:29:47 +08:00
guanghongwei
80d4272ee5 Merge remote-tracking branch 'origin/guanghongwei' into guanghongwei
Conflicts:
	jperm/models.py
2015-03-11 18:00:55 +08:00
guanghongwei
ae0c28ef8f 2015-03-11 17:59:15 +08:00
guanghongwei
5c54128f8d ޸ĺܶ, 2015-03-11 10:18:20 +08:00
halcyon
10bcae7cf0 dashboard 2015-03-10 18:27:47 +08:00
guanghongwei
d72d55c965 没怎么修改 2015-03-08 22:48:50 +08:00
guanghongwei
6c10b06d5a Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver 2015-03-07 18:38:29 +08:00
halcyon
95bb96ebbf 各种bug修改 2015-03-07 18:37:23 +08:00
guanghongwei
8f163eb634 统一分页 2015-03-07 18:25:31 +08:00
guanghongwei
de358099cf Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver 2015-03-07 18:07:04 +08:00
guanghongwei
cbf8dac5cc 修改显示分页 2015-03-07 18:06:50 +08:00
halcyon
e81eefcf62 修改各种bug 2015-03-07 18:06:26 +08:00
guanghongwei
c0eec734a1 Merge branches 'guanghongwei' and 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei 2015-03-07 17:51:08 +08:00
halcyon
6c9c560b86 修改各种bug 2015-03-07 17:50:17 +08:00
guanghongwei
c9928fc1f9 Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver
Conflicts:
	docs/AddUserAsset.py
2015-03-07 17:39:10 +08:00
halcyon
5bf66ca92e 修改各种bug 2015-03-07 17:37:40 +08:00
guanghongwei
9a638bc856 修改一些bug 2015-03-07 17:37:26 +08:00
guanghongwei
67f9aad1b9 Merge branches 'guanghongwei' and 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei
Conflicts:
	docs/AddUserAsset.py
2015-03-07 15:33:06 +08:00
halcyon
60729c49df bug 2015-03-07 15:29:49 +08:00
guanghongwei
ac92498832 修改 权限修改为 submit 2015-03-07 15:28:49 +08:00
guanghongwei
a94c050fd9 完工,睡觉 2015-03-07 00:12:38 +08:00
guanghongwei
07b0e2980e 今天到此为止 2015-03-06 00:24:17 +08:00
halcyon
d0600662ba dashboard and bugs 2015-03-05 18:46:12 +08:00
guanghongwei
8bc40dbea1 基本完成用户管理 2015-03-05 00:20:24 +08:00
root
e086a03692 bug 2015-03-04 23:14:07 +08:00
halcyon
bbe5b588c0 修改bug 2015-03-04 18:33:38 +08:00
guanghongwei
d32026013f ޸ĺܶ 2015-03-04 18:20:03 +08:00
guanghongwei
50fcac67c3 修改 删除等 2015-03-03 22:44:00 +08:00
guanghongwei
fc007e96d7 ޸ĺܶ 2015-03-03 18:42:06 +08:00
guanghongwei
ad2a4d2d5d 修改 用户添加 和 组添加 2015-03-02 23:32:34 +08:00
guanghongwei
d90b59191f ع1 2015-03-02 18:27:48 +08:00
guanghongwei
458ca42f22 未完成 2015-03-01 23:34:00 +08:00
guanghongwei
a50d3ba692 头像大小导致 nav颜色中间差 2015-03-01 22:46:19 +08:00
guanghongwei
fb1c17dc51 修改bug 2015-03-01 15:01:15 +08:00
guanghongwei
da1beef94d Merge branch 'guanghongwei'
Conflicts:
	jumpserver/views.py
	static/js/base.js
	templates/head_script.html
2015-03-01 12:26:52 +08:00
guanghongwei
32ab6311ae 合并分支 2015-03-01 12:23:26 +08:00
halcyon
08410820ab 03-01 2015-03-01 12:16:14 +08:00
halcyon
3c70512d8e dashboard 2015-03-01 12:09:33 +08:00
guanghongwei
1e26543f99 添加头像 2015-02-28 23:24:10 +08:00
guanghongwei
1c96443e73 修改头像 2015-02-28 23:22:52 +08:00
guanghongwei
9bab7bf1e7 Merge branch 'guanghongwei' of gitcafe.com:ibuler/jumpserver into guanghongwei
Conflicts:
	jperm/views.py
	jumpserver/views.py
2015-02-28 21:26:23 +08:00
root
cf8af114fe dashboard 2015-02-27 23:18:40 +08:00
guanghongwei
f0cd064195 修改 用户左侧显示 2015-02-27 22:14:09 +08:00
halcyon
9d44bc1593 dashboard con 2015-02-27 18:48:24 +08:00
root
67c1f12086 dashboard 2015-02-26 18:02:39 +08:00
guanghongwei
56f8f5d09b ޸ķҳ 2015-02-15 10:06:02 +08:00
guanghongwei
b7acef8cb0 授权收尾工作 2015-02-13 00:00:07 +08:00
root
a746cab21c bug 2015-02-12 23:17:07 +08:00
halcyon
b1e6699330 每日一更? 2015-02-12 18:54:40 +08:00
guanghongwei
4190b19450 修改授权详情 2015-02-11 23:32:24 +08:00
guanghongwei
f050866d94 Ȩ 2015-02-11 18:38:56 +08:00
halcyon
db86daf86d dashboard等 2015-02-11 17:53:17 +08:00
guanghongwei
97038aab37 sudoȨ 2015-02-10 21:52:59 +08:00
halcyon
a42d053cbb 新弹窗等 2015-02-10 18:57:43 +08:00
guanghongwei
50208c0088 sudoȨ 2015-02-10 18:53:01 +08:00
guanghongwei
8a5e494cfe 添加sudo权限删除,修改和详情 2015-02-10 00:21:08 +08:00
halcyon
5f2e2a808e 添加搜索功能 2015-02-09 19:03:18 +08:00
halcyon
c84f124511 bug 2015-02-09 19:02:25 +08:00
guanghongwei
d7de3edcf4 sudo޸Ȩ 2015-02-09 18:50:21 +08:00
guanghongwei
b9e2c9aa95 修改sudo授权 2015-02-09 08:40:54 +08:00
guanghongwei
75979e3999 修改sudo授权 2015-02-07 00:07:07 +08:00
guanghongwei
c113035d3d sudo perm 2015-02-06 18:39:20 +08:00
halcyon
433974d77d 改bug 2015-02-05 18:53:57 +08:00
guanghongwei
121b76284a Merge branches 'guanghongwei' and 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei
Conflicts:
	static/js/base.js
	templates/head_script.html
2015-02-03 23:15:22 +08:00
guanghongwei
46cc593a9e Ȩ֧ 2015-02-03 23:03:51 +08:00
halcyon
de58e92df9 添加组修改,组内删除主机并不删除真实机 2015-02-03 22:45:51 +08:00
蓝枫
0acc90a691 修改用户分页的bug
修改用户分页的bug
2015-02-02 11:29:32 +08:00
guanghongwei
70fe42f359 ޸scriptλ 2015-02-01 23:33:38 +08:00
guanghongwei
3d1df73a99 merge with wangyong 2015-02-01 23:12:57 +08:00
guanghongwei
0336bfa906 group_addʹajax 2015-02-01 23:03:28 +08:00
halcyon
6c70d5bf03 批量添加删除功能实现,修改资产添加修改等 2015-02-01 23:00:23 +08:00
halcyon
0560332768 change view 2015-01-31 13:46:55 +08:00
guanghongwei
7adbf52aeb ޸jsλ 2015-01-31 13:45:58 +08:00
root
795183c7ab remove node module from repo 2015-01-31 13:09:29 +08:00
root
4e0cd4cddf modify ignore 2015-01-31 13:06:48 +08:00
root
f187a368e4 add ignore 2015-01-31 13:06:02 +08:00
root
2a645747de Merge in 20150131 2015-01-31 13:03:58 +08:00
guanghongwei
deb55d3bb2 logo 2015-01-31 12:56:32 +08:00
halcyon
a8991bfb14 资产修改功能强化,日志功能添加 2015-01-31 12:55:10 +08:00
guanghongwei
c1fb72f393 ޸ĵ½˳ 2015-01-30 23:30:16 +08:00
guanghongwei
35d9be5c10 connect.py޸ 2015-01-30 16:53:06 +08:00
guanghongwei
c1686d52e9 Ȩ༭Ͳ鿴޸ 2015-01-30 16:39:34 +08:00
guanghongwei
c09d1d25b2 Ȩ༭޸ok 2015-01-30 14:54:45 +08:00
guanghongwei
d25a3ce17c û޸ 2015-01-30 11:18:30 +08:00
蓝枫
263aeeee9b Merge pull request #2 from xxrenzhe/patch-1
Update runserver
2015-01-29 11:11:08 +08:00
guanghongwei
b4006d3d36 perm edit޸ 2015-01-29 00:53:15 +08:00
xxrenzhe
8c9b53419d Update runserver
add sudo to start runserver, avoid starting runserver failed
2015-01-28 19:04:48 +08:00
guanghongwei
b62bc9d161 û޸ĸһ 2015-01-28 18:00:09 +08:00
guanghongwei
6a8db89614 ޸һbug 2015-01-28 17:35:06 +08:00
guanghongwei
5cd09a6503 ޸ʱӳԱ 2015-01-28 15:08:16 +08:00
guanghongwei
5d38a1996c Կȥ 2015-01-28 11:17:29 +08:00
guanghongwei
2254e82bf0 ʾĬϵgroup 2015-01-27 18:53:37 +08:00
guanghongwei
308379406a ʾĬϵgroup 2015-01-27 18:05:53 +08:00
guanghongwei
c04237ac76 ʾĬϵgroup 2015-01-27 18:02:51 +08:00
guanghongwei
047dda5ab3 ʾĬϵgroup 2015-01-27 17:56:51 +08:00
guanghongwei
3c8a9bab0c ޸ɾû 2015-01-27 17:30:20 +08:00
guanghongwei
c782b46f32 û߼޸ 2015-01-27 17:24:33 +08:00
guanghongwei
2acc715ebe x޸js 2015-01-27 16:43:37 +08:00
guanghongwei
5ddcdf99c1 ޸Ϣ 2015-01-27 15:01:09 +08:00
ibuler
c4196e7d5a 修改组方面授权 2015-01-27 00:14:50 +08:00
halcyon
173f520929 添加idc和主机组合并 2015-01-26 23:32:52 +08:00
guanghongwei
ca3d4de819 ޸js bug 2015-01-26 11:51:12 +08:00
ibuler
c460323c5b 修改授权web
映射去掉 user_common 和 password_common ===
2015-01-25 23:38:58 +08:00
halcyon
d1f6ed4a55 增加日志查看功能 2015-01-25 22:20:07 +08:00
ibuler
569e12e83c 修改授权移动 2015-01-25 21:46:19 +08:00
ibuler
caff3e5d0c Merge branches 'guanghongwei' and 'master' of gitcafe.com:ibuler/jumpserver into guanghongwei 2015-01-25 12:20:57 +08:00
guanghongwei
20fb5d6699 ޸bug 2015-01-24 16:51:39 +08:00
guanghongwei
00ec6c9034 ˫ 2015-01-24 16:50:38 +08:00
guanghongwei
0b79f8e345 ˫ 2015-01-24 16:49:47 +08:00
guanghongwei
373e417729 ޸bug 2015-01-24 16:29:19 +08:00
guanghongwei
3903eedc1a ޸Ȩ 2015-01-24 16:27:29 +08:00
guanghongwei
de175eb3cd tab 2015-01-24 16:06:07 +08:00
guanghongwei
8738b517cc ޸bug 2015-01-24 15:07:14 +08:00
guanghongwei
34b78825d2 ޸Permssion --> Perm 2015-01-24 15:05:02 +08:00
guanghongwei
d7d988b067 ޸ 2015-01-24 15:04:02 +08:00
guanghongwei
ecbba5ea61 ޸perm 2015-01-24 15:02:50 +08:00
guanghongwei
90f078a0f8 ޸bug 2015-01-24 14:53:18 +08:00
guanghongwei
3f0e8fcc2d ޸tag perm_total -> perm_count 2015-01-24 14:50:21 +08:00
guanghongwei
aa7e8c0ed4 ޸tag perm_total -> perm_count 2015-01-24 14:49:38 +08:00
guanghongwei
df82c17c1c ޸nav perm_host 2015-01-24 14:48:29 +08:00
guanghongwei
96738976fb ޸jpermistion --> jperm 2015-01-24 14:46:35 +08:00
guanghongwei
1ea63bf3d0 ޸Ȩweb 2015-01-24 14:36:58 +08:00
root
3a9f0566b6 Merge branch 'wangyong' of gitcafe.com:ibuler/jumpserver 2015-01-24 13:58:31 +08:00
guanghongwei
81f80b4b0c Merge branches 'guanghongwei' and 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei 2015-01-24 13:55:07 +08:00
halcyon
1a266f0b19 菜单active bug 2015-01-24 13:54:08 +08:00
guanghongwei
95fbdce957 ޸bug 2015-01-24 13:49:52 +08:00
guanghongwei
7b0cea02bb ޸bug 2015-01-24 13:42:56 +08:00
guanghongwei
d2669c2de0 ޸group edit 2015-01-24 13:34:36 +08:00
guanghongwei
08d42f1c2c ޸user_edit group_edit 2015-01-24 13:20:52 +08:00
guanghongwei
b836a28e77 ޸bug 2015-01-24 12:55:20 +08:00
guanghongwei
6d545565f6 鿴޸ 2015-01-24 12:54:25 +08:00
halcyon
449bde4b03 菜单active 2015-01-24 12:13:49 +08:00
ibuler
dc8f6d4d01 修改bug 2015-01-24 00:20:29 +08:00
ibuler
ab4dab85cd 修改bug 2015-01-24 00:15:42 +08:00
ibuler
c55c77e349 修改bug 2015-01-23 23:45:55 +08:00
ibuler
54d659edb6 修改bug 2015-01-23 23:40:37 +08:00
ibuler
2de8930034 修改bug 2015-01-23 23:37:15 +08:00
ibuler
16a051f4a0 修改bug 2015-01-23 23:27:06 +08:00
ibuler
3dca51d23c 修改用户信息 2015-01-23 22:44:29 +08:00
ibuler
d5cf3935d8 修改bug 2015-01-23 00:46:35 +08:00
ibuler
327f3d6db1 修改bug 2015-01-23 00:45:45 +08:00
ibuler
49dcdf3be0 添加修改页面 2015-01-23 00:41:17 +08:00
ibuler
f951471f1d 修改bug 2015-01-23 00:08:39 +08:00
ibuler
6b2310ff38 添加删除用户 2015-01-23 00:07:44 +08:00
ibuler
7e41f28864 修改bug 2015-01-23 00:00:29 +08:00
ibuler
68f67aecce 添加显示详情 2015-01-22 23:57:18 +08:00
ibuler
c54bc85b5c 修改显示 2015-01-22 23:24:13 +08:00
ibuler
43cea075dd 修改bug 2015-01-22 23:15:50 +08:00
ibuler
be051afce9 修改对齐 2015-01-22 23:10:22 +08:00
ibuler
c25e05b746 修改bug 2015-01-22 23:05:25 +08:00
ibuler
8543e885b7 修改bug 2015-01-22 23:04:59 +08:00
halcyon
f335e35ba4 修改资产更改页面无法提交bug 2015-01-22 23:02:44 +08:00
ibuler
3cf352ee56 修改bug 2015-01-22 22:49:34 +08:00
ibuler
4f25124d92 修改分页 2015-01-22 22:46:48 +08:00
ibuler
cc72d59965 修改bug 2015-01-22 22:26:13 +08:00
ibuler
9dc7e953c9 修改错误 2015-01-22 22:16:32 +08:00
ibuler
984a04972f 修改错误 2015-01-22 22:14:21 +08:00
ibuler
cc425116a1 修改页面展示 2015-01-22 22:12:41 +08:00
ibuler
98061f9dce 修改bug 2015-01-22 00:17:12 +08:00
ibuler
81f7507bf2 添加查看授权页面 2015-01-22 00:16:28 +08:00
ibuler
736c58ce05 修改bug 2015-01-22 00:01:30 +08:00
ibuler
a8ce9e9952 添加授权 2015-01-21 23:56:18 +08:00
ibuler
8bc7485c88 修改bug 2015-01-21 23:46:51 +08:00
ibuler
393871e214 修改bug 2015-01-21 23:45:28 +08:00
ibuler
53c3767b1b 添加授权页面 2015-01-21 23:44:14 +08:00
ibuler
234f378e3f 修改bug 2015-01-21 23:28:56 +08:00
ibuler
5957286d57 查看授权用户 2015-01-21 23:27:56 +08:00
ibuler
f73f349153 修改nav.html 2015-01-21 23:23:44 +08:00
ibuler
59d034ce6e 添加查看权限用户 2015-01-21 23:22:21 +08:00
root
244d0d2ba4 Merge branch 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei
Conflicts:
	jumpserver/templatetags/mytags.py
	juser/views.py
2015-01-21 23:05:42 +08:00
ibuler
d878bb197f bug消除 2015-01-21 22:41:57 +08:00
ibuler
6bd0ed4344 修改bug 2015-01-21 22:40:50 +08:00
ibuler
6635ccb603 修改bug 2015-01-21 22:38:55 +08:00
ibuler
a0688274b6 查看实例 2015-01-21 22:33:31 +08:00
ibuler
c569afb5da 修改bug 2015-01-21 22:23:57 +08:00
ibuler
b01964618d 获得role tag 2015-01-21 22:23:05 +08:00
halcyon
9b194946c3 修改添加组不选没有提示bug 2015-01-21 18:54:31 +08:00
蓝枫
c3bbefc259 Update requirements.txt
pip install readline
2015-01-20 13:23:36 +08:00
halcyon
7863a6853c 资产管理页面基本完成,尚有部分小bug 2015-01-19 10:09:16 +08:00
蓝枫
cff27200fa Update jumpserver.py
update import readline
2015-01-18 21:33:37 +08:00
ibuler
46720dcf0f 修改bug 2015-01-14 23:58:25 +08:00
ibuler
f592e46442 添加用户列表 2015-01-14 23:51:30 +08:00
ibuler
2200783de7 添加用户列表 2015-01-14 23:30:20 +08:00
ibuler
8a1e5376f7 修改添加用户bug 2015-01-14 23:08:29 +08:00
halcyon
1925cf4033 增加js判断 2015-01-14 19:19:56 +08:00
halcyon
6b95c7ed6f 资产详情弹窗 2015-01-14 16:39:57 +08:00
ibuler
7435d602dd 修改添加用户bug 2015-01-13 23:15:40 +08:00
ibuler
2b6c2cd6fc 修改bug 2015-01-13 22:57:27 +08:00
ibuler
84a48d3aec 修改bug 2015-01-13 22:44:58 +08:00
ibuler
14da0f18ab 添加用户完成 2015-01-13 22:14:50 +08:00
ibuler
bc5b32bcea 添加useradd的函数 2015-01-12 23:52:41 +08:00
蓝枫
3f7f1a8cdb Update jumpserver.py
修改PS1显示
2015-01-12 13:31:20 +08:00
halcyon
acf508f074 资产管理页面基本完成. 2015-01-11 19:27:21 +08:00
ibuler
f45398e20b 修改默认 2015-01-10 23:39:43 +08:00
ibuler
9304a911ea 添加自定义tag 2015-01-10 23:31:32 +08:00
guanghongwei
fbde8d42fe ޸bug 2015-01-10 16:48:34 +08:00
guanghongwei
8875cb2f9e ޸bug 2015-01-10 16:28:09 +08:00
guanghongwei
8c9e763f74 Ĭֵ 2015-01-10 16:24:44 +08:00
guanghongwei
97dcb4ca91 Locals 2015-01-10 15:54:09 +08:00
guanghongwei
95fb1bfd1c ޸bug 2015-01-10 15:24:16 +08:00
guanghongwei
8b91d5774f ޸bug 2015-01-10 15:15:49 +08:00
guanghongwei
ae227aad77 ޸bug 2015-01-10 15:07:56 +08:00
guanghongwei
3a3c5701b7 ޸vbug 2015-01-10 15:04:34 +08:00
guanghongwei
56fe39d346 ޸vbug 2015-01-10 14:58:34 +08:00
guanghongwei
b3444d2398 ޸bug 2015-01-10 14:57:27 +08:00
guanghongwei
f7a54e13c3 ݿû 2015-01-10 14:52:35 +08:00
guanghongwei
796533b7a9 ޸bug 2015-01-10 14:07:06 +08:00
guanghongwei
f9abf7af1d Merge branch 'master' into guanghongwei 2015-01-10 14:00:02 +08:00
guanghongwei
e5fe13337b ޸jasset 2015-01-10 13:57:37 +08:00
root
94beae5282 a new branch 2015-01-10 13:52:39 +08:00
guanghongwei
65b29cb68d ޸ 2015-01-10 13:50:59 +08:00
guanghongwei
c6e0429584 ޸model 2015-01-10 13:35:56 +08:00
guanghongwei
30cfa8a5f4 ޸asset models 2015-01-10 13:30:01 +08:00
guanghongwei
67074fa895 ޸bug 2015-01-10 13:11:50 +08:00
guanghongwei
609b0160f7 ޸user_add.html 2015-01-10 13:10:44 +08:00
guanghongwei
0c30e8fd53 ѡ 2015-01-10 12:30:21 +08:00
guanghongwei
662c48ed37 group_list޸ 2015-01-10 12:07:15 +08:00
ibuler
a63f2304fe 修改icheck 2015-01-09 23:15:28 +08:00
ibuler
4af80d2b61 查看iCheck 2015-01-09 22:51:46 +08:00
ibuler
113054c92c 修改bug 2015-01-09 22:21:19 +08:00
ibuler
53d8f7fad7 修改checkbox样式 2015-01-09 22:19:05 +08:00
ibuler
fb525728c0 添加查看属组.html 2015-01-09 22:10:38 +08:00
ibuler
9e32964382 修改bug and 睡觉 2015-01-08 00:07:00 +08:00
ibuler
f524d2605a 修改 group_add bug 2015-01-08 00:01:41 +08:00
ibuler
fac7fe3281 添加 group add view 2015-01-07 23:56:36 +08:00
ibuler
2aea864fbe 添加group_add url 2015-01-07 23:22:47 +08:00
ibuler
9652460ba5 Merge remote-tracking branch 'origin/master' 2015-01-07 23:21:11 +08:00
ibuler
fde3d19a9d 添加分组template 2015-01-07 23:20:48 +08:00
halcyon
0ed0853489 完善资产添加和查看资产页面 2015-01-07 18:35:09 +08:00
ibuler
bafbacc18a 修改nav字体颜色 2015-01-06 23:45:40 +08:00
ibuler
cd7aa37a72 添加虚线 2015-01-06 23:36:11 +08:00
ibuler
e79aaff750 修改bug 2015-01-06 23:33:49 +08:00
ibuler
de226a9249 测试查看 user_add.html 2015-01-06 23:21:07 +08:00
ibuler
fc162f1429 测试查看 2015-01-06 23:10:13 +08:00
ibuler
6175f4eb29 长度再修改 2015-01-05 23:58:51 +08:00
ibuler
e74438f54d 修改长度 2015-01-05 23:57:49 +08:00
ibuler
64c155bede 修改添加用户 2015-01-05 23:55:05 +08:00
ibuler
c8828f40ba 测试修改Path 2015-01-05 23:52:25 +08:00
ibuler
ee3336de9e 修改长度 2015-01-05 23:46:13 +08:00
ibuler
f9a5907762 修改长度 2015-01-05 23:07:20 +08:00
ibuler
67c94265b1 修改长度 2015-01-05 23:03:46 +08:00
ibuler
ba704d61b6 修改长度 2015-01-05 22:57:36 +08:00
ibuler
a1973c2a89 修改长度 2015-01-05 22:51:15 +08:00
ibuler
3735136009 修改长度 2015-01-05 22:50:05 +08:00
ibuler
3ed3f3e830 修改长度 2015-01-05 22:45:10 +08:00
ibuler
3f54828114 修改title 2015-01-05 22:44:05 +08:00
ibuler
1c648d6396 添加 skin_config.html 2015-01-05 22:39:14 +08:00
ibuler
296302a236 添加/base/ 2015-01-05 22:37:03 +08:00
ibuler
f497003948 修改content 2015-01-05 22:35:25 +08:00
ibuler
ba5757e377 修改bug 2015-01-05 21:29:49 +08:00
ibuler
02ef9c687c Merge remote-tracking branch 'origin/master'
Conflicts:
	jumpserver/urls.py
	templates/nav.html
2015-01-05 21:25:14 +08:00
ibuler
a184ae9888 添加测试 useradd 2015-01-05 21:20:09 +08:00
halcyon
7a86ba0b51 资产管理页面开始,增加添加资产页面,修改base页面等 2015-01-05 18:21:34 +08:00
蓝枫
8ad37c6ce3 Update views.py
修改bug
2015-01-05 16:24:55 +08:00
halcyon
ccb4876d88 修改bug 2015-01-04 11:12:38 +08:00
ibuler
a4b3a07885 修改已出bug 2015-01-03 23:11:15 +08:00
ibuler
9087b41352 修改 文平提交 2015-01-03 23:10:09 +08:00
ibuler
8682d7c6ec 基于文平修改 2015-01-03 22:42:46 +08:00
ibuler
dde0b75d17 使用 陈文平的html 2015-01-03 22:24:34 +08:00
ibuler
a6642ab004 修改base.html 2015-01-03 20:42:20 +08:00
ibuler
caabc04ffe 添加支持readline 2015-01-03 09:52:52 +08:00
ibuler
f552babde6 添加facio 2015-01-02 22:08:49 +08:00
root
d51287fa8b 修改base.html 2015-01-02 22:06:35 +08:00
root
2cf845ceac Merge branch 'master' of gitcafe.com:ibuler/jumpserver 2015-01-02 20:53:31 +08:00
root
55c3b06d0f 简单定制base 2015-01-02 20:53:20 +08:00
ibuler
2a2e169da5 禁用google fonts 2015-01-02 20:52:52 +08:00
ibuler
6d32e6a1a7 添加Demo皮肤设置 2015-01-02 17:43:28 +08:00
ibuler
542873159b 添加Demo皮肤设置 2015-01-02 17:40:34 +08:00
ibuler
19a9e5aa2c 添加Demo皮肤设置 2015-01-02 17:26:11 +08:00
ibuler
9c1e313472 添加Demo皮肤设置 2015-01-02 17:24:56 +08:00
ibuler
d17c0bceb2 添加Demo皮肤设置 2015-01-02 17:23:59 +08:00
ibuler
8f95f11f35 添加Demo皮肤设置 2015-01-02 17:14:57 +08:00
ibuler
cd9a62f40b 删除没用的css 2015-01-02 16:59:37 +08:00
ibuler
bbc407660d 修改bug 2015-01-01 09:15:01 +08:00
ibuler
d1358b3d4f 修改bug 2015-01-01 08:44:46 +08:00
ibuler
2eaf6d7d81 修改bug 2014-12-31 23:02:03 +08:00
ibuler
73da287c6c 优化代码 2014-12-31 22:58:37 +08:00
ibuler
9ba7ad147a 修改multi拼写错误 2014-12-31 00:11:12 +08:00
root
b1e0a24184 Merge branch 'ssh_key'
Conflicts:
	connect.py
2014-12-30 23:59:27 +08:00
ibuler
894911126b 添加异常处理 2014-12-30 23:51:00 +08:00
ibuler
0b97c19862 修改bug 2014-12-30 23:22:57 +08:00
ibuler
89e2133341 serve active and user active 2014-12-30 22:52:39 +08:00
ibuler
3f4a7225b1 修改bug,增加ssh_key和普通密码登陆 2014-12-30 22:48:39 +08:00
halcyon
bd9049deb6 增加批量执行命令功能 2014-12-30 22:48:18 +08:00
ibuler
d316b08b6d 修改bug 2014-12-30 00:05:03 +08:00
ibuler
6c2b782964 支持ssh-key 2014-12-29 23:50:56 +08:00
ibuler
cefc175790 测试固定Footer 2014-12-29 21:26:09 +08:00
ibuler
d7df0fb48b 修改皮肤颜色 2014-12-29 21:23:34 +08:00
ibuler
c0d1ae6afc t图片bug 2014-12-29 21:20:10 +08:00
ibuler
c8c34dca29 修改地址 2014-12-29 21:16:43 +08:00
ibuler
588545c3f9 添加静态资源css,js 2014-12-28 21:52:23 +08:00
ibuler
7bfad09c49 修改bug 2014-12-28 21:49:35 +08:00
ibuler
2860f4a343 添加测试页面 2014-12-28 21:48:26 +08:00
ibuler
731196094b 添加解密时异常处理 2014-12-28 19:57:48 +08:00
root
c71e685913 修改.gitigonre 2014-12-28 00:42:21 +08:00
ibuler
fead462124 修改登录名和记录日志不一样的问题 2014-12-28 00:34:05 +08:00
ibuler
42d14ee1d6 修改bug 2014-12-28 00:14:10 +08:00
ibuler
1e78b65cd7 修改bug 2014-12-28 00:04:00 +08:00
root
37893bb394 修改配置文件 2014-12-27 23:57:40 +08:00
root
0744007701 添加测试 test.py 2014-12-27 23:56:16 +08:00
ibuler
8677b0d18d 修改bug 2014-12-27 23:54:37 +08:00
ibuler
7a73bd98d3 添加测试用户 2014-12-27 17:01:08 +08:00
ibuler
aa4c02cfcd 添加测试用户 2014-12-27 16:52:31 +08:00
ibuler
19bd6652af 修改bug 2014-12-26 23:59:12 +08:00
ibuler
0d48884e19 记录日志 2014-12-26 23:58:11 +08:00
ibuler
5e8605981b 增加开发者文档 2014-12-26 23:13:01 +08:00
ibuler
bcf3281a10 添加log models
添加 docs目录
2014-12-26 22:54:37 +08:00
root
37fe5dc4e3 add jlog 2014-12-26 21:57:10 +08:00
ibuler
9609bad31c 修改import 的序列 2014-12-26 21:55:56 +08:00
ibuler
f73ba9cc4a 显示id 2014-12-26 21:39:05 +08:00
ibuler
4eec31e42d 修改显示1 2014-12-26 00:11:13 +08:00
ibuler
8d7ab7b1b0 修改bug 2014-12-25 23:52:52 +08:00
root
284d5c79b0 chmod +x connect.py 2014-12-25 23:49:34 +08:00
ibuler
bc78331d5b 基本完成 2014-12-25 23:49:08 +08:00
ibuler
ab87420c9d 睡觉去了 2014-12-24 23:40:52 +08:00
ibuler
1f15f13aac 修改bUg 2014-12-24 23:17:51 +08:00
ibuler
fe70ca80e6 修改bUg 2014-12-24 22:56:29 +08:00
ibuler
17ef381d7c 改名,修改bug 2014-12-24 22:42:47 +08:00
ibuler
ac875d3961 简单修改 2014-12-24 22:29:36 +08:00
root
3c42240227 修改权限 2014-12-24 22:22:39 +08:00
ibuler
d7b2631410 修改名称 2014-12-24 22:21:46 +08:00
ibuler
e66b1b4192 修改bug 2014-12-24 22:20:38 +08:00
ibuler
803dc9c576 准备完工 2014-12-24 00:21:47 +08:00
root
5426116ed4 add a test file. 2014-12-23 22:48:43 +08:00
ibuler
c715c8ec02 修改bug, 添加测试文件 2014-12-23 22:27:45 +08:00
ibuler
a05e4147a3 修改bug 2014-12-22 23:46:00 +08:00
ibuler
0e76d52322 修改bug 2014-12-22 23:44:48 +08:00
ibuler
353bae0f13 修改bug 2014-12-22 23:43:03 +08:00
ibuler
39b4266458 修改bug 2014-12-22 23:42:11 +08:00
ibuler
bc5422821d 添加jpermssion models 2014-12-22 23:36:32 +08:00
ibuler
b24ad2854c 添加static, templates 2014-12-22 23:20:47 +08:00
root
a9af0598e7 add jpermssion app 2014-12-22 23:17:28 +08:00
ibuler
ef0c9fdd16 添加model 2014-12-22 23:14:29 +08:00
guanghongwei
99f95af74e modified settings.py set option 2014-12-22 18:34:08 +08:00
root
6a2e6709b9 add new app juser,jasset 2014-12-22 17:18:51 +08:00
guanghongwei
1e8d930ef0 del import module 2014-12-22 17:01:37 +08:00
guanghongwei
e4c6823ee2 alert_print fuction 2014-12-22 16:55:49 +08:00
guanghongwei
e2e32b4b37 add color print fuction 2014-12-22 16:38:10 +08:00
guanghongwei
7806db1d3f catch excepition 2014-12-22 16:22:04 +08:00
guanghongwei
3382b67bb8 Merge branch 'master' of gitcafe.com:ibuler/jumpserver 2014-12-22 15:58:07 +08:00
guanghongwei
b6866ac518 overite 2014-12-22 15:57:26 +08:00
root
f06422d5fa modify PS1 2014-12-22 15:56:19 +08:00
guanghongwei
e0a0c1c641 Merge branch 'master' of gitcafe.com:ibuler/jumpserver 2014-12-22 15:32:25 +08:00
guanghongwei
8baff2c72d set PS1 2014-12-22 15:31:48 +08:00
root
4805d18fe9 modify connect.py mode 2014-12-22 14:54:43 +08:00
guanghongwei
988991a0ad rename jumpserver.py --> connect.py and add connect fucntion 2014-12-22 14:52:31 +08:00
ibuler
917a24e858 Add postfix_shell function. Add jumpserver.conf file. 2014-12-21 23:10:59 +08:00
root
0b2a77fce4 Init project add LICENSE file 2014-12-21 22:13:04 +08:00
ibuler
23d2b2a1cf Initial commit 2014-12-21 22:04:16 +08:00
ibuler
aba3a2222d Merge branch 'master' of https://github.com/xxrenzhe/jumpserver 2014-12-07 21:09:03 +08:00
xxrenzhe
a49b944e29 Adjust a equal judgement 2014-12-07 20:43:13 +08:00
guanghongwei
333e2a20ff 修改了初始连接屏幕大小的bug 2014-11-20 14:43:38 +08:00
蓝枫
59c770a3bf Update README.md 2014-11-15 14:39:26 +08:00
蓝枫
df5227d48a Update README.md 2014-11-15 14:37:57 +08:00
蓝枫
8d0bf4c625 Update README.md 2014-11-15 14:23:52 +08:00
蓝枫
d1238efb6f Update README.md 2014-11-15 14:23:11 +08:00
蓝枫
8fcccbb8bc Update README.md 2014-11-15 14:21:36 +08:00
蓝枫
313a20d189 Update README.md 2014-11-15 14:17:30 +08:00
蓝枫
9c4fb88b7a Update README.md 2014-11-15 14:10:04 +08:00
蓝枫
3c1b1b18e4 Update README.md
update
2014-11-15 14:07:19 +08:00
蓝枫
0d7f65db1c Update README.md
删除原来的README.md
2014-11-14 17:07:29 +08:00
guanghongwei
ea39dfb415 delete conf from jumpserver.py 2014-11-13 14:59:05 +08:00
guanghongwei
9f9b08f6bc rm pyc file 2014-11-13 11:40:04 +08:00
guanghongwei
52a98b11e7 bugfix 2014-11-13 10:38:18 +08:00
root
f6d414d903 fix bug 2014-11-12 11:00:47 +08:00
ibuler
eae5535b42 bugfix 2014-11-12 23:44:17 +08:00
ibuler
d9d3f25dfd bugfix 2014-11-12 21:53:03 +08:00
guanghongwei
d6b6e745b2 fixbug 2014-11-12 19:10:23 +08:00
guanghongwei
f903750d58 fixbug 2014-11-12 18:54:30 +08:00
guanghongwei
61ac985e09 修改bug 2014-11-12 18:45:26 +08:00
guanghongwei
22c7cb6c7d Merge branch 'dev' of ssh://172.10.10.9:2001/opt/jumpserver into dev 2014-11-12 18:28:00 +08:00
guanghongwei
24415f5b24 bugfix 2014-11-12 18:25:09 +08:00
宿召阳
931ac3dd1f bug fix 2014-11-12 18:21:34 +08:00
guanghongwei
99313cd2db bugfix 2014-11-12 18:11:43 +08:00
guanghongwei
7e6a4621c5 bugfix 2014-11-12 17:56:56 +08:00
guanghongwei
fa2358d22b bugfix 2014-11-12 17:54:04 +08:00
guanghongwei
0f63eadfc1 bugfix 2014-11-12 17:52:56 +08:00
宿召阳
4844f7861b bug fix 2014-11-12 17:41:14 +08:00
guanghongwei
9ad9a8812f 删除tsst 2014-11-12 15:55:44 +08:00
guanghongwei
d036ef7f0a Merge branch 'dev' of ssh://172.10.10.9:2001/opt/jumpserver into dev 2014-11-12 15:54:53 +08:00
ibuler
b211856394 abc 2014-11-12 15:54:18 +08:00
ibuler
71299df131 add websocket 2014-11-12 15:50:04 +08:00
ibuler
6bacda6a9a add websocket 2014-11-12 15:48:33 +08:00
ibuler
dc782ca5b5 add websocket 2014-11-12 15:38:26 +08:00
ibuler
4a9923db4b bug fix 2014-11-11 23:40:26 +08:00
ibuler
9d7641ad8a 删除没用的模块 2014-11-11 21:35:26 +08:00
ibuler
a7904a8d57 修改一些bug 2014-11-11 17:29:11 +08:00
ibuler
a4e6fef2a6 修改名称 2014-11-11 14:17:03 +08:00
ibuler
6c762b865a bugfix 2014-11-11 00:05:50 +08:00
ibuler
c424cad244 bugfix 2014-11-10 23:46:20 +08:00
ibuler
16ec34c463 bugfix 2014-11-10 23:42:45 +08:00
ibuler
44ef066ede bugfix 2014-11-10 23:41:38 +08:00
ibuler
f947a753db bugfix 2014-11-10 23:36:52 +08:00
ibuler
532cefe338 bug fix 2014-11-10 23:35:12 +08:00
ibuler
62bc814a44 bug fix 2014-11-10 23:31:43 +08:00
ibuler
dc11f34585 添加IDC的支持 2014-11-10 23:28:44 +08:00
ibuler
a5c3048a89 1. 支持绝对路径
2. 支持分页
2014-11-09 22:25:55 +08:00
宿召阳
41b7110554 bug fix 2014-11-07 16:12:45 +08:00
宿召阳
d38a963dbd bug fix 2014-11-07 15:50:37 +08:00
宿召阳
b1aff5c997 bug fix 2014-11-07 15:44:50 +08:00
宿召阳
f5b02265a4 bug fix 2014-11-07 15:38:19 +08:00
宿召阳
21ab6cbe1e bug fix 2014-11-07 15:36:25 +08:00
宿召阳
0560ccaf17 bug fix' 2014-11-07 15:33:41 +08:00
宿召阳
0e3c79fb79 bug fix 2014-11-07 15:18:52 +08:00
宿召阳
1c9359bb4c bug fix 2014-11-07 14:27:05 +08:00
宿召阳
1c4adc1e38 bug fix 2014-11-07 14:12:17 +08:00
宿召阳
a5abd9d620 del 2014-11-07 11:26:38 +08:00
guanghongwei
2ca299a31f 添加忽略文件 2014-11-07 11:00:53 +08:00
宿召阳
1c930b31d9 bug fix 2014-11-07 10:52:08 +08:00
guanghongwei
331f029096 Merge branch 'dev' of ssh://172.10.10.9:2001/opt/jumpserver into dev 2014-11-07 10:50:18 +08:00
guanghongwei
586e2602db 修改bug 2014-11-07 10:48:04 +08:00
宿召阳
83ac653637 merge 2014-11-07 10:30:13 +08:00
宿召阳
d1ea2a6dd1 add ignore 2014-11-07 10:29:35 +08:00
宿召阳
4f2bc9d402 add socket 2014-11-07 10:27:59 +08:00
ibuler
3bee29338c 删除没用的 2014-11-06 23:20:06 +08:00
ibuler
26c31feb4a 修改记录日志bug 2014-11-06 22:56:36 +08:00
guanghongwei
d8e4efe7cc 修改 批量命令记录日志,上传下载记录日志 2014-11-06 18:48:13 +08:00
guanghongwei
fc3d13a4b1 logfile 2014-11-06 17:35:02 +08:00
guanghongwei
d134b2279b 修改 monitor 2014-11-06 17:32:43 +08:00
guanghongwei
f3efa9b914 删除view echo 2014-11-06 13:56:31 +08:00
guanghongwei
9cdd62b62d 删除 django-websocket
添加 requirements.txt
2014-11-06 13:53:12 +08:00
ibuler
271b80991a ok 2014-11-05 00:31:05 +08:00
ibuler
5f302866ca ok 2014-11-05 00:29:04 +08:00
ibuler
cce2bb5590 bug 2014-11-05 00:23:34 +08:00
ibuler
a01c1a40b9 s 2014-11-05 00:21:27 +08:00
ibuler
c82b8f1128 sokcet 2014-11-05 00:15:29 +08:00
ibuler
862cec316f websocket 2014-11-05 00:12:31 +08:00
ibuler
5445e5eaa1 test websocket 2014-11-05 00:11:04 +08:00
ibuler
22bcda23dc websocket 2014-11-04 23:58:20 +08:00
ibuler
fcabb66f2e test websocket 2014-11-04 23:52:06 +08:00
ibuler
5b2911a5ed test websocket 2014-11-04 23:51:16 +08:00
ibuler
969d54050f 修改模板 2014-11-04 21:56:39 +08:00
ibuler
92188f1c77 修改bug 2014-11-04 21:48:34 +08:00
ibuler
c18290c667 kill session 2014-11-04 21:46:19 +08:00
guanghongwei
19b94655fb 删除没用的 2014-11-04 18:46:34 +08:00
guanghongwei
825adba39c bug 2014-11-04 17:25:08 +08:00
guanghongwei
2d28a7a0c4 bug 2014-11-04 17:22:47 +08:00
guanghongwei
4a09ce32e6 修改bug 2014-11-04 17:20:23 +08:00
guanghongwei
0ccb808b3f 修改 2014-11-04 17:18:27 +08:00
guanghongwei
08c30e462c 日志汇总查看 2014-11-04 16:37:48 +08:00
ibuler
654c27490d 添加删除pid条目 2014-11-04 00:22:52 +08:00
ibuler
06e788782b chmod +x log_handler.py 2014-11-04 00:14:19 +08:00
ibuler
7d868c5195 修改位置 2014-11-04 00:12:40 +08:00
ibuler
2212cf24b4 日志处理系统 2014-11-04 00:10:01 +08:00
guanghongwei
d728c06851 修改bug 2014-11-03 10:57:23 +08:00
guanghongwei
b52420708e 修改 mytags位置 2014-11-03 10:45:43 +08:00
ibuler
5bc67ebad9 修改错误 2014-11-02 23:50:19 +08:00
ibuler
a57adf9b2e 更改过滤标签 2014-11-02 23:11:44 +08:00
ibuler
aa9139c642 分页显示 2014-11-02 23:01:36 +08:00
ibuler
efbcacbec6 加入日志审计 2014-11-02 22:54:26 +08:00
ibuler
e5121fe7ea 记录 子pid 2014-11-02 16:25:20 +08:00
ibuler
ac926b5fb4 增加进程pid 2014-11-02 15:23:45 +08:00
ibuler
44166e2653 闹心的 password和ldap_password 2014-11-02 14:36:19 +08:00
ibuler
e38fb5992f sql使用mysql models来完成 2014-11-02 13:36:14 +08:00
ibuler
765ac5e714 记录日志 2014-11-02 00:01:56 +08:00
ibuler
f766ba340f 配置文件修改 2014-11-01 23:12:27 +08:00
ibuler
5b060a768a 修改bug 2014-11-01 22:51:18 +08:00
ibuler
54da30d93b 修改配置文件为相对路径,不用再指定目录了 2014-11-01 22:46:41 +08:00
ibuler
838b10d3b6 Merge branch 'dev' of ssh://172.10.10.9:2001/opt/jumpserver into dev 2014-11-01 16:18:27 +08:00
ibuler
cd84f0d5c6 修改拖动窗口关闭的bug 2014-11-01 16:16:31 +08:00
guanghongwei
641b72f3d1 修改 foo.setwinsize() 2014-10-31 18:42:55 +08:00
guanghongwei
63065f5c33 使用pxssh 2014-10-31 14:35:33 +08:00
ibuler
de2837229c modify logdir , asset beizhu 2014-10-31 00:07:33 +08:00
ibuler
596573293f modify connect_one view 2014-10-30 22:11:45 +08:00
ibuler
93bd02017c add downFile url 2014-10-30 21:42:42 +08:00
ibuler
2e1c7d2fb8 修改模板显示
修改jumpserver.py   1.2 1.21
修改下载大文件
2014-10-30 21:39:03 +08:00
guanghongwei
78b55f981c ok 2014-10-12 21:13:27 +08:00
guanghongwei
fb8b800fd7 上传 2014-10-09 23:12:20 +08:00
guanghongwei
67b0cd5522 上传 2014-10-09 22:55:03 +08:00
guanghongwei
68e8c4ba0f 删除没用的代码,添加上传文件 2014-10-09 22:31:47 +08:00
guanghongwei
1b08c6ea88 修改 2014-10-09 11:26:15 +08:00
guanghongwei
6ae84b3334 修改chgSudo.py 2014-10-09 10:51:01 +08:00
guanghongwei
6418033e51 修改 chgsudo 2014-10-09 10:21:36 +08:00
guanghongwei
f48dd46898 修改chgsudo 2014-10-08 22:42:43 +08:00
guanghongwei
9020c11bd2 修改chgSudo的view 2014-10-08 22:19:53 +08:00
guanghongwei
50b7d00683 修改button属性 2014-10-08 17:59:38 +08:00
guanghongwei
e3078d2ac6 chgSudo修改 2014-10-08 17:56:41 +08:00
guanghongwei
582418797d 修改chgSudo.html 2014-10-08 12:20:31 +08:00
guanghongwei
031b92bf03 修改chgSudo.html 2014-10-08 12:03:10 +08:00
guanghongwei
1a529a7d7f 修改 2014-10-07 19:18:13 +08:00
guanghongwei
f4591e3aad 修改url 2014-10-07 19:08:17 +08:00
guanghongwei
14c48bc1bf sudo显示 2014-10-07 19:04:57 +08:00
guanghongwei
30cbf15b57 sudo ldap时出错 2014-10-07 18:29:04 +08:00
guanghongwei
41dbfbb335 修改一点点 2014-10-07 18:06:36 +08:00
guanghongwei
9191d3b6e5 修改bug 2014-10-03 23:06:28 +08:00
guanghongwei
d0a5274214 is_admin_role 2014-10-03 22:47:41 +08:00
guanghongwei
7f132e100f 各种修改bug 2014-10-03 22:32:49 +08:00
guanghongwei
61fcfb80a8 还是修改bug 2014-10-03 22:18:26 +08:00
guanghongwei
046d4da45c 修改bug 2014-10-03 22:16:51 +08:00
guanghongwei
94830a79a3 修改bug 2014-10-03 22:14:43 +08:00
guanghongwei
bb0a023380 修改group 2014-10-03 22:11:59 +08:00
guanghongwei
c8444ef73a 增加分组 2014-10-03 22:04:36 +08:00
guanghongwei
7c5f2d216f 修改密码 2014-10-01 21:17:54 +08:00
guanghongwei
201ef814f9 修改bug 2014-10-01 21:15:19 +08:00
guanghongwei
00f6984929 修改小错误 2014-10-01 21:12:30 +08:00
guanghongwei
f2e39f24c8 密码没有默认 2014-10-01 21:09:50 +08:00
guanghongwei
cd3f787aef 更改chgKey函数 2014-10-01 21:00:17 +08:00
guanghongwei
86a9c46643 我都想吐了 2014-09-29 20:43:59 +08:00
guanghongwei
d639801f3c 更改 2014-09-29 18:20:41 +08:00
guanghongwei
4517ec0629 修改 2014-09-29 17:32:35 +08:00
guanghongwei
9601476077 maybe车次好了 2014-09-29 17:05:03 +08:00
guanghongwei
e2e067139c 应该是可以修改成功的 2014-09-29 16:53:52 +08:00
guanghongwei
42d130d5c2 bug越来越多 2014-09-29 16:22:30 +08:00
guanghongwei
632b863cf7 太他妈闹心了 2014-09-29 16:16:23 +08:00
guanghongwei
83f8f5a150 最后一次? 2014-09-29 16:07:59 +08:00
guanghongwei
1f272aa03c 一天修改10变 2014-09-29 16:05:53 +08:00
guanghongwei
222162eaa7 继续他妈修改 2014-09-29 16:04:05 +08:00
guanghongwei
102e832a58 我擦 2014-09-29 15:58:25 +08:00
guanghongwei
e8ab3e45f3 尼玛修改文件 2014-09-29 15:55:32 +08:00
guanghongwei
ec4a9e92bf 修改bug 2014-09-29 15:35:05 +08:00
guanghongwei
16a2d3803a 修改chgUser.html 2014-09-29 15:27:17 +08:00
guanghongwei
4d58d9ef0e 修改用户信息 2014-09-29 09:30:57 +08:00
guanghongwei
a263e50b3e jm忘记加参数了 2014-09-28 16:32:55 +08:00
guanghongwei
6e2ebd5c79 修改 修改用户信息 2014-09-28 16:28:04 +08:00
guanghongwei
86b8124bec 修改 “修改用户”的一出bug 2014-09-28 12:03:59 +08:00
guanghongwei
c588aaea3a 添加修改用户信息 2014-09-28 11:57:20 +08:00
guanghongwei
52e567b157 修改授权问题 2014-09-27 20:58:50 +08:00
guanghongwei
5fd15478a8 修改vies 2014-09-27 20:20:45 +08:00
guanghongwei
5ccffe6c1d 添加install 2014-09-27 20:16:10 +08:00
guanghongwei
7d32a9a9e9 修改login 2014-09-27 19:44:46 +08:00
guanghongwei
0d5ff30acf 整理一遍 2014-09-27 19:26:33 +08:00
guanghongwei
a68454f7a4 修改 删除用户权限 2014-09-24 15:42:44 +08:00
guanghongwei
d4f40feebf 修改bug 2014-09-23 21:56:59 +08:00
guanghongwei
a25b2df453 修改一个bug 2014-09-23 21:49:22 +08:00
guanghongwei
a6f53fc99d 修改 登录和删除 2014-09-23 21:41:36 +08:00
guanghongwei
35e74f3c10 修改删除用户 2014-09-23 14:27:51 +08:00
guanghongwei
1ea85c3b19 更改显示 2014-09-18 19:42:09 +08:00
guanghongwei
8756172b9b 修改添加的类型 2014-09-18 15:53:43 +08:00
guanghongwei
d4ef81edc6 修改用户添加流程,抛弃shell操作 2014-09-18 14:39:00 +08:00
guanghongwei
0f18e702e8 修改保存 2014-09-16 18:23:56 +08:00
guanghongwei
63cdef4218 修改添加用户 2014-09-16 17:26:49 +08:00
guanghongwei
8596bc4997 修改adduser function 2014-09-16 16:58:09 +08:00
guanghongwei
e72aba98e6 修改单词拼写 2014-09-16 16:23:30 +08:00
guanghongwei
8b13967570 修改views的form引用 2014-09-16 16:22:00 +08:00
guanghongwei
0d842fe3ec 修改bug 2014-09-16 16:18:00 +08:00
guanghongwei
73d61e09ed 添加forms 2014-09-16 16:14:14 +08:00
guanghongwei
45b874fcd8 修改models顺序 2014-09-16 12:14:33 +08:00
guanghongwei
538b8c8a35 修改model表结构 2014-09-16 12:11:44 +08:00
guanghongwei
78d7255190 delete vpn comment 2014-09-16 10:35:51 +08:00
guanghongwei
07ee63f04c 删除runcommand目录 2014-09-15 21:19:07 +08:00
590 changed files with 89900 additions and 14522 deletions

16
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,16 @@
[简述你的问题]
##### 使用版本
[请提供你使用的Jumpserver版本 0.3.2 或 0.4.0]
##### 问题复现步骤
1. [步骤1]
2. [步骤2]
##### 具体表现[截图可能会更好些,最好能截全]
##### 其他
[注:] 完成后请关闭 issue

26
.gitignore vendored Normal file
View File

@@ -0,0 +1,26 @@
.DS_Store
*.pyc
*.pyo
*.swp
.env
env
env*
dist
build
*.egg
*.egg-info
_mailinglist
dump.rdb
.tox
.cache/
.idea/
db.sqlite3
config.py
migrations/
*.log
host_rsa_key
*.bat
tags
jumpserver.iml
.python-version
tmp/*

1
.python-version Normal file
View File

@@ -0,0 +1 @@
system

22
Dockerfile Normal file
View File

@@ -0,0 +1,22 @@
FROM jumpserver/python:v3.6.1
LABEL MAINTAINER Jumpserver Team <ibuler@qq.com>
COPY . /opt/jumpserver
WORKDIR /opt/jumpserver
RUN yum -y install epel-release && yum clean all -y
RUN cd requirements && yum -y install $(cat rpm_requirements.txt) && yum clean all -y
RUN cd requirements && pip install -r requirements.txt
RUN rm -f data/db.sqlite3
RUN rm -r .git
RUN rm -f config.py
VOLUME /opt/jumpserver/data
VOLUME /opt/jumpserver/logs
RUN cp config_docker.py config.py
EXPOSE 8080
CMD cd utils && sh make_migrations.sh && sh init_db.sh && cd .. && python run_server.py

16
Dockerfile-py3 Normal file
View File

@@ -0,0 +1,16 @@
FROM centos:centos6
LABEL MAINTAINER Jumpserver Team <ibuler@qq.com>
WORKDIR /tmp
RUN yum -y install wget sqlite-devel xz gcc automake zlib-devel openssl-devel; yum clean all
# Install Python
RUN wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tar.xz && \
tar xvf Python-3.6.1.tar.xz && cd Python-3.6.1 && ./configure && make && make install && \
rm -rf /tmp/{Python-3.6.1.tar.xz,Python-3.6.1}
RUN mv /usr/bin/python /usr/bin/python2
RUN ln -s /usr/local/bin/python3 /usr/bin/python && ln -s /usr/local/bin/pip3 /usr/bin/pip
RUN sed -i 's@/usr/bin/python@/usr/bin/python2@g' /usr/bin/yum

339
LICENSE Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

117
README.md
View File

@@ -1,36 +1,113 @@
开源运维堡垒机(跳板机)系统
==============================
## Jumpserver
介绍和文档:
--------------
介绍和部署: [我的博客](http://laoguang.blog.51cto.com/6013350/1540080)
[![Python3](https://img.shields.io/badge/python-3.6-green.svg?style=plastic)](https://www.python.org/)
[![Django](https://img.shields.io/badge/django-1.11-brightgreen.svg?style=plastic)](https://www.djangoproject.com/)
[![Ansible](https://img.shields.io/badge/ansible-2.2.2.0-blue.svg?style=plastic)](https://www.ansible.com/)
[![Paramiko](https://img.shields.io/badge/paramiko-2.1.2-green.svg?style=plastic)](http://www.paramiko.org/)
Jumpserver is a open source proxy server, developed by `Python` and `Django`, aim to help
companies to efficiently user, assets, authority and audit management
Jumpserver是一款使用Python, Django开发的开源跳板机系统, 助力互联网企业高效 用户、资产、权限、审计 管理
### Feature 功能
- Auth 统一认证
- CMDB 资产管理
- Perm 统一授权
- Audit 审计
- LDAP AUTH 支持LDAP认证
- Web terminal
- SSH Server
截图:
-------------
![登录](https://github.com/ibuler/static/blob/master/jumpserver/1.png)
### Environment 环境
* Python 3.6
* Django 1.11
![界面](https://github.com/ibuler/static/blob/master/jumpserver/web1.png)
### Install 安装
Using docker compose to setup it
![界面2](https://github.com/ibuler/static/blob/master/jumpserver/web2.png)
使用docker compose 安装一键完成docker compose 安装见 docker官方
![界面3](https://github.com/ibuler/static/blob/master/jumpserver/web3.png)
  $ docker-compose up
![添加用户](https://github.com/ibuler/static/blob/master/jumpserver/2.png)
### Usage 使用
  1. Visit http://$HOST:8080 (访问 http://你的主机IP:8080 来访问 Jumpserver)
  2. Click left navigation visit Applications-Terminal and accept coco and luna register
(点击左侧 应用程序接受 Coco和Luna的注册)
  3. Click Assets-Admin user, Create admin user
(添加 管理用户)
4. Click Assets-System user, Create system user
(添加 系统用户)
  5. Click Assets-Asset, Add a asset
(添加 资产)
  6. Click Perms-Asset permission, Add a perm rule
(添加授权规则授权给admin)
  7. Connect ssh server coco (连接 ssh server coco)
ssh -p2222 $USER@$Host
  8. Visit web terminal server Luna, click server test connection
(访问 访问Luna点击左侧服务器连接测试)
http://$HOST:5000
### Snapshot 截图
![添加host](https://github.com/ibuler/static/blob/master/jumpserver/add_host.png)
https://github.com/jumpserver/jumpserver/issues/438
![添加权限](https://github.com/ibuler/static/blob/master/jumpserver/addperm.png)
![跳板机](https://github.com/ibuler/static/blob/master/jumpserver/view1.png)
### Demo
![跳板机1](https://github.com/ibuler/static/blob/master/jumpserver/view2.png)
demo使用了开发者模式并发只能为1
![跳板机2](https://github.com/ibuler/static/blob/master/jumpserver/view3.png)
- Jumpserver: [访问](http://demo.jumpserver.org:8080) 账号: admin 密码: admin
![跳板机3](https://github.com/ibuler/static/blob/master/jumpserver/view4.png)
- Luna: [访问](http://demo.jumpserver.org:5000) 同Jumpserver认证
![跳板机4](https://github.com/ibuler/static/blob/master/jumpserver/view5.png)
- Coco: ssh -p 2222 admin@demo.jumpserver.org 密码: admin
![跳板机6](https://github.com/ibuler/static/blob/master/jumpserver/view6.png)
### ROADMAP
参见 https://github.com/jumpserver/jumpserver/milestone/2
### Docs 开发者文档
* [Project structure 项目结构描述](https://github.com/jumpserver/jumpserver/blob/dev/docs/project_structure.md)
* [Code style Python代码规范](https://github.com/jumpserver/jumpserver/blob/dev/docs/python_style_guide.md)
* [Api style API设计规范](https://github.com/jumpserver/jumpserver/blob/dev/docs/api_style_guide.md)
### Contributor 贡献者
#### 0.4.0
- ibuler <广宏伟>
- 小彧 <李磊> Django资深开发者为users模块贡献了很多代码
- sofia <周小侠> 资深前端工程师, luna前端代码贡献者和现在维护者
- liuz <刘正> 全栈工程师, 编写了luna大部分代码
- jiaxiangkong <陈尚委> Jumpserver测试运营
#### 0.3.2
- halcyon <王墉> DevOps 资深开发者, 0.3.2 核心开发者之一
- yumaojun03 <喻茂峻> DevOps 资深开发者jperm开发者擅长Python, Go以及PAAS平台开发
- kelianchun <柯连春> DevOps 资产开发者fix了很多connect.py bug
### 开发者群
如果你为Jumpserver贡献过代码请加一下群 需要验证一下你的github id
群号: 489385245
### License & Copyright
Copyright (c) 2014-2017 Beijing Duizhan Tech, Inc., All rights reserved.
Licensed under The GNU General Public License version 2 (GPLv2) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
https://www.gnu.org/licenses/gpl-2.0.html
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

7
apps/__init__.py Normal file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
if __name__ == '__main__':
pass

103
apps/applications/api.py Normal file
View File

@@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
#
from collections import OrderedDict
import copy
from rest_framework.generics import ListCreateAPIView
from rest_framework import viewsets
from rest_framework.views import APIView, Response
from rest_framework.permissions import AllowAny
from django.shortcuts import get_object_or_404
from rest_framework.decorators import api_view
from .models import Terminal, TerminalHeatbeat
from .serializers import TerminalSerializer, TerminalHeatbeatSerializer
from .hands import IsSuperUserOrAppUser, IsAppUser, ProxyLog, \
IsSuperUserOrAppUserOrUserReadonly
from common.utils import get_object_or_none
class TerminalRegisterView(ListCreateAPIView):
queryset = Terminal.objects.all()
serializer_class = TerminalSerializer
permission_classes = (AllowAny,)
def create(self, request, *args, **kwargs):
name = request.data.get('name', '')
remote_addr = request.META.get('X-Real-IP') or \
request.META.get('REMOTE_ADDR')
serializer = self.serializer_class(
data={'name': name, 'remote_addr': remote_addr})
if get_object_or_none(Terminal, name=name):
return Response({'msg': 'Already register, Need '
'administrator active it'}, status=200)
if serializer.is_valid():
terminal = serializer.save()
app_user, access_key = terminal.create_related_app_user()
data = OrderedDict()
data['terminal'] = copy.deepcopy(serializer.data)
data['user'] = app_user.to_json()
data['access_key_id'] = access_key.id
data['access_key_secret'] = access_key.secret
return Response(data, status=201)
else:
data = {'msg': 'Not valid', 'detail': ';'.join(serializer.errors)}
return Response(data, status=400)
def list(self, request, *args, **kwargs):
return Response('', status=404)
class TerminalViewSet(viewsets.ModelViewSet):
queryset = Terminal.objects.all()
serializer_class = TerminalSerializer
permission_classes = (IsSuperUserOrAppUserOrUserReadonly,)
def create(self, request, *args, **kwargs):
return Response({'msg': 'Use register view except that'}, status=404)
# def destroy(self, request, *args, **kwargs):
# instance = self.get_object()
# if instance.user is not None:
# instance.user.delete()
# return super(TerminalViewSet, self).destroy(request, *args, **kwargs)
tasks = OrderedDict()
# tasks = {1: [{'name': 'kill_proxy', 'proxy_log_id': 23}]}
class TerminalHeatbeatViewSet(viewsets.ModelViewSet):
queryset = TerminalHeatbeat.objects.all()
serializer_class = TerminalHeatbeatSerializer
permission_classes = (IsAppUser,)
def create(self, request, *args, **kwargs):
terminal = request.user.terminal
TerminalHeatbeat.objects.create(terminal=terminal)
task = tasks.get(terminal.name)
tasks[terminal.name] = []
return Response({'msg': 'Success',
'tasks': task},
status=201)
class TerminateConnectionView(APIView):
def post(self, request, *args, **kwargs):
if isinstance(request.data, dict):
data = [request.data]
else:
data = request.data
for d in data:
proxy_log_id = d.get('proxy_log_id')
proxy_log = get_object_or_404(ProxyLog, id=proxy_log_id)
terminal_id = proxy_log.terminal
if terminal_id in tasks:
tasks[terminal_id].append({'name': 'kill_proxy',
'proxy_log_id': proxy_log_id})
else:
tasks[terminal_id] = [{'name': 'kill_proxy',
'proxy_log_id': proxy_log_id}]
return Response({'msg': 'get it'})

View File

@@ -0,0 +1,7 @@
from __future__ import unicode_literals
from django.apps import AppConfig
class ApplicationsConfig(AppConfig):
name = 'applications'

View File

@@ -0,0 +1,18 @@
# ~*~ coding: utf-8 ~*~
#
from django import forms
from .models import Terminal
class TerminalForm(forms.ModelForm):
class Meta:
model = Terminal
fields = ['name', 'remote_addr', 'type', 'url', 'comment']
help_texts = {
'url': 'Example: ssh://192.168.1.1:22 or http://jms.jumpserver.org, that user login'
}
widgets = {
'name': forms.TextInput(attrs={'readonly': 'readonly'})
}

View File

@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
#
from users.models import User
from users.permissions import IsSuperUserOrAppUser, IsAppUser, \
IsSuperUserOrAppUserOrUserReadonly
from audits.models import ProxyLog
from users.utils import AdminUserRequiredMixin

View File

@@ -0,0 +1,62 @@
from __future__ import unicode_literals
from django.db import models
from django.utils.translation import ugettext_lazy as _
from users.models import User
class Terminal(models.Model):
TYPE_CHOICES = (
('SSH', 'SSH Terminal'),
('Web', 'Web Terminal')
)
name = models.CharField(max_length=30, unique=True, verbose_name=_('Name'))
remote_addr = models.GenericIPAddressField(verbose_name=_('Remote address'), blank=True, null=True)
type = models.CharField(choices=TYPE_CHOICES, max_length=3, blank=True, verbose_name=_('Terminal type'))
user = models.OneToOneField(User, related_name='terminal', verbose_name='Application user',
null=True, on_delete=models.CASCADE)
url = models.CharField(max_length=100, blank=True, verbose_name=_('URL to login'))
is_accepted = models.BooleanField(default=False, verbose_name='Is Accepted')
date_created = models.DateTimeField(auto_now_add=True)
comment = models.TextField(blank=True, verbose_name=_('Comment'))
@property
def is_active(self):
if self.user and self.user.is_active:
return True
return False
@is_active.setter
def is_active(self, active):
if self.user:
self.user.is_active = active
self.user.save()
def create_related_app_user(self):
user, access_key = User.create_app_user(name=self.name, comment=self.comment)
self.user = user
self.save()
return user, access_key
def delete(self, using=None, keep_parents=False):
if self.user:
self.user.delete()
return super(Terminal, self).delete(using=using, keep_parents=keep_parents)
def __unicode__(self):
active = 'Active' if self.user and self.user.is_active else 'Disabled'
return '%s: %s' % (self.name, active)
__str__ = __unicode__
class Meta:
ordering = ('is_accepted',)
class TerminalHeatbeat(models.Model):
terminal = models.ForeignKey(Terminal, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'terminal_heatbeat'

View File

@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
#
from django.utils import timezone
from rest_framework import serializers
from .models import Terminal, TerminalHeatbeat
from .hands import ProxyLog
class TerminalSerializer(serializers.ModelSerializer):
proxy_online = serializers.SerializerMethodField()
is_alive = serializers.SerializerMethodField()
class Meta:
model = Terminal
fields = ['id', 'name', 'remote_addr', 'type', 'url', 'comment',
'is_accepted', 'is_active', 'get_type_display',
'proxy_online', 'is_alive']
@staticmethod
def get_proxy_online(obj):
return ProxyLog.objects.filter(terminal=obj.name, is_finished=False).count()
@staticmethod
def get_is_alive(obj):
log = obj.terminalheatbeat_set.last()
if log and timezone.now() - log.date_created < timezone.timedelta(seconds=600):
return True
else:
return False
class TerminalHeatbeatSerializer(serializers.ModelSerializer):
date_start = serializers.DateTimeField
class Meta:
model = TerminalHeatbeat
if __name__ == '__main__':
pass

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#

View File

@@ -0,0 +1,77 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active">
<a href="" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Terminal detail' %} </a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'applications:terminal-update' pk=terminal.id %}"><i class="fa fa-edit"></i>Update</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label"><b>{{ terminal.name }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="20%">{% trans 'Name' %}:</td>
<td><b>{{ terminal.name }}</b></td>
</tr>
<tr>
<td>{% trans 'Remote address' %}:</td>
<td><b>{{ terminal.remote_addr }}</b></td>
</tr>
<tr>
<td>{% trans 'URL to login' %}:</td>
<td><b>{{ terminal.url }}</b></td>
</tr>
<tr>
<td>{% trans 'Terminal type' %}:</td>
<td><b>{{ terminal.get_type_display }}</b></td>
</tr>
<tr>
<td>{% trans 'Date created' %}:</td>
<td><b>{{ terminal.date_created }}</b></td>
</tr>
<tr>
<td>{% trans 'Comment' %}:</td>
<td><b>{{ asset.comment }}</b></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,149 @@
{% extends '_base_list.html' %}
{% load i18n static %}
{% block custom_head_css_js %}
{{ block.super }}
<style>
div.dataTables_wrapper div.dataTables_filter,
.dataTables_length {
float: right !important;
}
div.dataTables_wrapper div.dataTables_filter {
margin-left: 15px;
}
#modal .modal-body { max-height: 200px; }
</style>
{% endblock %}
{% block table_search %}{% endblock %}
{% block table_container %}
{#<div class="uc pull-left m-l-5 m-r-5"><a href="{% url "users:user-create" %}" class="btn btn-sm btn-primary"> {% trans "Create user" %} </a></div>#}
<table class="table table-striped table-bordered table-hover " id="terminal_list_table" >
<thead>
<tr>
<th class="text-center">
<div class="checkbox checkbox-default">
<input type="checkbox" class="ipt_check_all">
</div>
</th>
<th class="text-center">{% trans 'Name' %}</th>
<th class="text-center">{% trans 'IP' %}</th>
<th class="text-center">{% trans 'Type' %}</th>
<th class="text-center">{% trans 'Session online' %}</th>
<th class="text-center">{% trans 'Active' %}</th>
<th class="text-center">{% trans 'Alive' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
{% include 'applications/terminal_modal_accept.html' %}
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<script>
$(document).ready(function(){
var options = {
ele: $('#terminal_list_table'),
buttons: [],
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "applications:terminal-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 5, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 6, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-circle text-danger"></i>')
} else {
$(td).html('<i class="fa fa-circle text-navy"></i>')
}
}},
{targets: 7, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "applications:terminal-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
.replace('99991937', cellData);
var delete_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-del" data-id="99991937" data-name="99991938">{% trans "Delete" %}</a>'
.replace('99991937', cellData)
.replace('99991938', rowData.name);
var accept_btn = '<a class="btn btn-xs btn-primary btn-accept" data-id="99991937">{% trans "Accept" %}</a> '
.replace('99991937', cellData);
var reject_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-del" data-id="99991937" data-name="99991938">{% trans "Reject" %}</a>'
.replace('99991937', cellData)
.replace('99991938', rowData.name);
var connect_btn = '<a href="{% url "applications:terminal-connect" pk=99991937 %}"" class="btn btn-xs btn-warning btn-connect" >{% trans "Connect" %}</a> '
.replace('99991937', cellData);
if (rowData.is_accepted) {
{% if user.is_superuser %}
$(td).html(connect_btn + update_btn + delete_btn);
{% else %}
$(td).html(connect_btn);
{% endif %}
} else {
{% if user.is_superuser %}
$(td).html(accept_btn + reject_btn);
{% endif %}
}
}}
],
ajax_url: '{% url "api-applications:terminal-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "remote_addr" }, {data: "get_type_display" },
{data: "proxy_online"}, {data: "is_active" }, {data: 'is_active'}, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
$('#btn_terminal_accept').click(function () {
var $form = $('#form_terminal_accept');
function success(data, textStatus, jqXHR) {
if (data.success === true) {
window.location.reload()
} else {
$('#modal-error').html(data.msg).css('display', 'block');
}
}
$form.ajaxSubmit({success: success});
})
}).on('click', '.btn-del', function(){
var $this = $(this);
var id = $this.data('id');
var name = $(this).data('name');
var the_url = '{% url "api-applications:terminal-detail" pk=99991937 %}'.replace('99991937', id);
objectDelete($this, name, the_url)
}).on('click', '.btn-accept', function () {
var $this = $(this);
var terminal_id = $this.data('id');
var the_url = "{% url 'api-applications:terminal-detail' pk=99991937 %}".replace('99991937', terminal_id);
var post_url = $('#form_terminal_accept').attr('action').replace('99991937', terminal_id);
console.log(post_url);
$.ajax({
url: the_url,
method: 'GET',
success: function (data) {
$('#id_name').val(data.name);
$('#id_remote_addr').val(data.remote_addr);
$('#id_type').val(data.type);
$('#id_url').val(data.url);
$('#id_comment').val(data.comment);
$('#form_terminal_accept').attr('action', post_url)
}
});
$('#modal_terminal_accept').modal({
show: true
});
}).on('click', '.btn-connect', function () {
var $this = $(this);
var id = $this.data('id');
console.log(id)
})
</script>
{% endblock %}

View File

@@ -0,0 +1,19 @@
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}modal_terminal_accept{% endblock %}
{% block modal_class %}modal-lg{% endblock %}
{% block modal_title%}{% trans "Accept terminal registration" %}{% endblock %}
{% block modal_body %}
{% load bootstrap3 %}
<form action="{% url 'applications:terminal-modal-accept' pk="99991937" %}" method="post" class="form-horizontal" id="form_terminal_accept" enctype="multipart/form-data">
{% csrf_token %}
<p class="alert alert-danger" id="modal-error" style="display: none"></p>
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.type layout="horizontal" %}
{% bootstrap_field form.url layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
</form>
{% endblock %}
{% block modal_confirm_id %}btn_terminal_accept{% endblock %}

View File

@@ -0,0 +1,5 @@
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>

View File

@@ -0,0 +1,72 @@
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
<link href="{% static "css/plugins/datepicker/datepicker3.css" %}" rel="stylesheet">
{% 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="ibox-title">
<h5>{{ action }}</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form method="post" class="form-horizontal" action="" enctype="multipart/form-data">
{% csrf_token %}
<h3>{% trans 'Info' %}</h3>
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.type layout="horizontal" %}
{% bootstrap_field form.url layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Other' %}</h3>
{% bootstrap_field form.comment layout="horizontal" %}
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script>
$(document).ready(function () {
$('.select2').select2();
$('.input-group.date').datepicker({
format: "yyyy-mm-dd",
todayBtn: "linked",
keyboardNavigation: false,
forceParse: false,
calendarWeeks: true,
autoclose: true
});
})
</script>
{% endblock %}

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from django.conf.urls import url
from rest_framework import routers
from .. import api
app_name = 'applications'
router = routers.DefaultRouter()
router.register(r'v1/terminal/heatbeat', api.TerminalHeatbeatViewSet, 'terminal-heatbeat')
router.register(r'v1/terminal', api.TerminalViewSet, 'terminal')
urlpatterns = [
url(r'^v1/terminal/register/$', api.TerminalRegisterView.as_view(),
name='terminal-register'),
url(r'^v1/terminate/connection/$', api.TerminateConnectionView.as_view(),
name='terminate-connection')
# url(r'^v1/terminal/heatbeat/$', api.TestHeatbeat.as_view())
]
urlpatterns += router.urls

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from django.conf.urls import url
from .. import views
app_name = 'applications'
urlpatterns = [
url(r'^terminal/$', views.TerminalListView.as_view(), name='terminal-list'),
url(r'^terminal/(?P<pk>\d+)/$', views.TerminalDetailView.as_view(),
name='terminal-detail'),
url(r'^terminal/(?P<pk>\d+)/connect/$', views.TerminalConnectView.as_view(),
name='terminal-connect'),
url(r'^terminal/(?P<pk>\d+)/update$', views.TerminalUpdateView.as_view(),
name='terminal-update'),
url(r'^terminal/(?P<pk>\d+)/modal/accept$', views.TerminalModelAccept.as_view(),
name='terminal-modal-accept'),
]

115
apps/applications/views.py Normal file
View File

@@ -0,0 +1,115 @@
# ~*~ coding: utf-8 ~*~
#
from django.views.generic import ListView, UpdateView, DeleteView, \
DetailView, TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.translation import ugettext as _
from django.urls import reverse_lazy, reverse
from common.mixins import JSONResponseMixin
from .models import Terminal
from .forms import TerminalForm
from .hands import AdminUserRequiredMixin
class TerminalListView(LoginRequiredMixin, ListView):
model = Terminal
template_name = 'applications/terminal_list.html'
form_class = TerminalForm
def get_context_data(self, **kwargs):
context = super(TerminalListView, self).get_context_data(**kwargs)
context.update({
'app': _('Terminal'),
'action': _('Terminal list'),
'form': self.form_class()
})
return context
class TerminalUpdateView(AdminUserRequiredMixin, UpdateView):
model = Terminal
form_class = TerminalForm
template_name = 'applications/terminal_update.html'
success_url = reverse_lazy('applications:terminal-list')
def get_context_data(self, **kwargs):
context = super(TerminalUpdateView, self).get_context_data(**kwargs)
context.update({'app': _('Applications'), 'action': _('Update terminal')})
return context
class TerminalDetailView(LoginRequiredMixin, DetailView):
model = Terminal
template_name = 'applications/terminal_detail.html'
context_object_name = 'terminal'
def get_context_data(self, **kwargs):
context = super(TerminalDetailView, self).get_context_data(**kwargs)
context.update({
'app': _('Applications'),
'action': _('Terminal detail')
})
return context
class TerminalDeleteView(AdminUserRequiredMixin, DeleteView):
model = Terminal
template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('applications:applications-list')
class TerminalModelAccept(AdminUserRequiredMixin, JSONResponseMixin, UpdateView):
model = Terminal
form_class = TerminalForm
template_name = 'applications/terminal_modal_test.html'
def post(self, request, *args, **kwargs):
print(request.POST)
return super(TerminalModelAccept, self).post(request, *args, **kwargs)
def form_valid(self, form):
terminal = form.save()
terminal.is_accepted = True
terminal.is_active = True
terminal.save()
data = {
'success': True,
'msg': 'success'
}
return self.render_json_response(data)
def form_invalid(self, form):
print('form.data')
data = {
'success': False,
'msg': str(form.errors),
}
return self.render_json_response(data)
class TerminalConnectView(LoginRequiredMixin, DetailView):
template_name = 'flash_message_standalone.html'
model = Terminal
def get_context_data(self, **kwargs):
if self.object.type == 'Web':
context = {
'title': _('Redirect to web terminal'),
'messages': _('Redirect to web terminal') + self.object.url,
'auto_redirect': True,
'interval': 3,
'redirect_url': self.object.url
}
else:
context = {
'title': _('Connect ssh terminal'),
'messages': _('You should use your ssh client tools '
'connect terminal: {} <br /> <br />'
'{}'.format(self.object.name, self.object.url)),
'redirect_url': reverse('applications:terminal-list')
}
kwargs.update(context)
return super(TerminalConnectView, self).get_context_data(**kwargs)

220
apps/assets/api.py Normal file
View File

@@ -0,0 +1,220 @@
# ~*~ coding: utf-8 ~*~
# Copyright (C) 2014-2017 Beijing DuiZhan Technology Co.,Ltd. All Rights Reserved.
#
# Licensed under the GNU General Public License v2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.gnu.org/licenses/gpl-2.0.html
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from rest_framework import generics
from rest_framework.response import Response
from rest_framework_bulk import BulkModelViewSet
from rest_framework_bulk import ListBulkCreateUpdateDestroyAPIView
from django.shortcuts import get_object_or_404
from common.mixins import IDInFilterMixin
from common.utils import get_object_or_none
from .hands import IsSuperUser, IsAppUser, IsValidUser, \
get_user_granted_assets, push_users
from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser
from . import serializers
from .tasks import update_assets_hardware_info
from .utils import test_admin_user_connective_manual
class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
"""API endpoint that allows Asset to be viewed or edited."""
queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer
permission_classes = (IsValidUser,)
def get_queryset(self):
if self.request.user.is_superuser:
queryset = super(AssetViewSet, self).get_queryset()
else:
queryset = get_user_granted_assets(self.request.user)
idc_id = self.request.query_params.get('idc_id', '')
system_users_id = self.request.query_params.get('system_user_id', '')
asset_group_id = self.request.query_params.get('asset_group_id', '')
admin_user_id = self.request.query_params.get('admin_user_id', '')
if idc_id:
queryset = queryset.filter(idc__id=idc_id)
if system_users_id:
queryset = queryset.filter(system_users__id=system_users_id)
if admin_user_id:
queryset = queryset.filter(admin_user__id=admin_user_id)
if asset_group_id:
queryset = queryset.filter(groups__id=asset_group_id)
return queryset
class AssetGroupViewSet(IDInFilterMixin, BulkModelViewSet):
"""Asset group api set, for add,delete,update,list,retrieve resource"""
queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupSerializer
permission_classes = (IsSuperUser,)
class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
"""Asset update it's group api"""
queryset = Asset.objects.all()
serializer_class = serializers.AssetUpdateGroupSerializer
permission_classes = (IsSuperUser,)
class AssetGroupUpdateApi(generics.RetrieveUpdateAPIView):
"""Asset group, update it's asset member"""
queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupUpdateSerializer
permission_classes = (IsSuperUser,)
class AssetGroupUpdateSystemUserApi(generics.RetrieveUpdateAPIView):
"""Asset group push system user"""
queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupUpdateSystemUserSerializer
permission_classes = (IsSuperUser,)
class IDCUpdateAssetsApi(generics.RetrieveUpdateAPIView):
"""IDC update asset member"""
queryset = IDC.objects.all()
serializer_class = serializers.IDCUpdateAssetsSerializer
permission_classes = (IsSuperUser,)
class IDCViewSet(IDInFilterMixin, BulkModelViewSet):
"""IDC api set, for add,delete,update,list,retrieve resource"""
queryset = IDC.objects.all()
serializer_class = serializers.IDCSerializer
permission_classes = (IsSuperUser,)
class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
"""Admin user api set, for add,delete,update,list,retrieve resource"""
queryset = AdminUser.objects.all()
serializer_class = serializers.AdminUserSerializer
permission_classes = (IsSuperUser,)
class SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
"""System user api set, for add,delete,update,list,retrieve resource"""
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserSerializer
permission_classes = (IsSuperUser,)
class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
"""Asset update it's system user
when update then push system user to asset.
"""
queryset = Asset.objects.all()
serializer_class = serializers.AssetUpdateSystemUserSerializer
permission_classes = (IsSuperUser,)
def patch(self, request, *args, **kwargs):
asset = self.get_object()
old_system_users = set(asset.system_users.all())
response = super(SystemUserUpdateApi, self).patch(request, *args, **kwargs)
system_users_new = set(asset.system_users.all())
system_users = system_users_new - old_system_users
system_users = [system_user._to_secret_json() for system_user in system_users]
push_users.delay([asset._to_secret_json()], system_users)
return response
class SystemUserUpdateAssetsApi(generics.RetrieveUpdateAPIView):
"""System user update it's assets"""
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserUpdateAssetsSerializer
permission_classes = (IsSuperUser,)
class SystemUserUpdateAssetGroupApi(generics.RetrieveUpdateAPIView):
"""System user update asset group"""
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserUpdateAssetGroupSerializer
permission_classes = (IsSuperUser,)
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
"""Asset bulk update api"""
queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer
permission_classes = (IsSuperUser,)
class SystemUserAuthInfoApi(generics.RetrieveAPIView):
"""Get system user auth info"""
queryset = SystemUser.objects.all()
permission_classes = (IsAppUser,)
def retrieve(self, request, *args, **kwargs):
system_user = self.get_object()
data = {
'id': system_user.id,
'name': system_user.name,
'username': system_user.username,
'password': system_user.password,
'private_key': system_user.private_key,
'auth_method': system_user.auth_method,
}
return Response(data)
class AssetRefreshHardwareView(generics.RetrieveAPIView):
"""Refresh asset hardware info"""
queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer
permission_classes = (IsSuperUser,)
def retrieve(self, request, *args, **kwargs):
asset_id = kwargs.get('pk')
asset = get_object_or_404(Asset, pk=asset_id)
summary = update_assets_hardware_info([asset])
if len(summary['failed']) == 0:
return super(AssetRefreshHardwareView, self).retrieve(request, *args, **kwargs)
else:
return Response('', status=502)
class AssetAdminUserTestView(AssetRefreshHardwareView):
"""Test asset admin user connectivity"""
queryset = Asset.objects.all()
permission_classes = (IsSuperUser,)
def retrieve(self, request, *args, **kwargs):
asset_id = kwargs.get('pk')
asset = get_object_or_404(Asset, pk=asset_id)
result = test_admin_user_connective_manual([asset])
if result:
return Response('1')
else:
return Response('0', status=502)
class AssetGroupPushSystemUserView(generics.UpdateAPIView):
"""Asset group push system user api"""
queryset = AssetGroup.objects.all()
permission_classes = (IsSuperUser,)
serializer_class = serializers.AssetSerializer
def patch(self, request, *args, **kwargs):
asset_group = self.get_object()
assets = asset_group.assets.all()
system_user_id = self.request.data['system_user']
system_user = get_object_or_none(SystemUser, id=system_user_id)
if not assets or not system_user:
return Response('Invalid system user id or asset group id', status=404)
task = push_users.delay([asset._to_secret_json() for asset in assets],
system_user._to_secret_json())
return Response(task.id)

7
apps/assets/apps.py Normal file
View File

@@ -0,0 +1,7 @@
from __future__ import unicode_literals
from django.apps import AppConfig
class AssetsConfig(AppConfig):
name = 'assets'

361
apps/assets/forms.py Normal file
View File

@@ -0,0 +1,361 @@
# coding:utf-8
from django import forms
from django.utils.translation import gettext_lazy as _
from .models import IDC, Asset, AssetGroup, AdminUser, SystemUser
from common.utils import validate_ssh_private_key, ssh_pubkey_gen, ssh_key_gen, get_logger
logger = get_logger(__file__)
class AssetCreateForm(forms.ModelForm):
class Meta:
model = Asset
fields = [
'hostname', 'ip', 'public_ip', 'port', 'type', 'comment',
'admin_user', 'idc', 'groups', 'status', 'env', 'is_active'
]
widgets = {
'groups': forms.SelectMultiple(
attrs={'class': 'select2',
'data-placeholder': _('Select asset groups')}),
'admin_user': forms.Select(
attrs={'class': 'select2',
'data-placeholder': _('Select asset admin user')}),
}
help_texts = {
'hostname': '* required',
'ip': '* required',
'system_users': _('System user will be granted for user to login '
'assets (using ansible create automatic)'),
'admin_user': _('Admin user should be exist on asset already, '
'And have sudo ALL permission'),
}
def clean_admin_user(self):
if not self.cleaned_data['admin_user']:
raise forms.ValidationError(_('Select admin user'))
return self.cleaned_data['admin_user']
class AssetUpdateForm(forms.ModelForm):
class Meta:
model = Asset
fields = [
'hostname', 'ip', 'port', 'groups', 'admin_user', 'idc', 'is_active',
'type', 'env', 'status', 'public_ip', 'remote_card_ip', 'cabinet_no',
'cabinet_pos', 'number', 'comment'
]
widgets = {
'groups': forms.SelectMultiple(
attrs={'class': 'select2',
'data-placeholder': _('Select asset groups')}),
'admin_user': forms.Select(
attrs={'class': 'select2',
'data-placeholder': _('Select asset admin user')}),
}
help_texts = {
'hostname': '* required',
'ip': '* required',
'system_users': _('System user will be granted for user '
'to login assets (using ansible create automatic)'),
'admin_user': _('Admin user should be exist on asset '
'already, And have sudo ALL permission'),
}
class AssetBulkUpdateForm(forms.ModelForm):
assets = forms.MultipleChoiceField(
required=True,
help_text='* required',
label=_('Select assets'),
widget=forms.SelectMultiple(
attrs={
'class': 'select2',
'data-placeholder': _('Select assets')
}
)
)
port = forms.IntegerField(min_value=1, max_value=65535,
required=False, label=_('Port'))
class Meta:
model = Asset
fields = [
'assets', 'port', 'groups', 'admin_user', 'idc',
'type', 'env', 'status',
]
widgets = {
'groups': forms.SelectMultiple(
attrs={'class': 'select2',
'data-placeholder': _('Select asset groups')}),
'admin_user': forms.Select(
attrs={'class': 'select2',
'data-placeholder': _('Select asset admin user')}),
}
def save(self, commit=True):
cleaned_data = {k: v for k, v in self.cleaned_data.items() if v is not None}
assets_id = cleaned_data.pop('assets')
groups = cleaned_data.pop('groups')
assets = Asset.objects.filter(id__in=assets_id)
assets.update(**cleaned_data)
if groups:
for asset in assets:
asset.groups.set(groups)
return assets
class AssetGroupForm(forms.ModelForm):
# See AdminUserForm comment same it
assets = forms.ModelMultipleChoiceField(
queryset=Asset.objects.all(),
label=_('Asset'),
required=False,
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
)
def __init__(self, *args, **kwargs):
if kwargs.get('instance', None):
initial = kwargs.get('initial', {})
initial['assets'] = kwargs['instance'].assets.all()
super(AssetGroupForm, self).__init__(*args, **kwargs)
def _save_m2m(self):
super(AssetGroupForm, self)._save_m2m()
assets = self.cleaned_data['assets']
self.instance.assets.clear()
self.instance.assets.add(*tuple(assets))
class Meta:
model = AssetGroup
fields = [
"name", "comment",
]
help_texts = {
'name': '* required',
}
class IDCForm(forms.ModelForm):
# See AdminUserForm comment same it
assets = forms.ModelMultipleChoiceField(
queryset=Asset.objects.all(),
label=_('Asset'),
required=False,
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
)
def __init__(self, *args, **kwargs):
if kwargs.get('instance'):
initial = kwargs.get('initial', {})
initial['assets'] = kwargs['instance'].assets.all()
super(IDCForm, self).__init__(*args, **kwargs)
def _save_m2m(self):
super(IDCForm, self)._save_m2m()
assets = self.cleaned_data['assets']
self.instance.assets.clear()
self.instance.assets.add(*tuple(assets))
class Meta:
model = IDC
fields = ['name', "bandwidth", "operator", 'contact',
'phone', 'address', 'intranet', 'extranet', 'comment']
widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'intranet': forms.Textarea(
attrs={'placeholder': 'IP段之间用逗号隔开192.168.1.0/24,192.168.1.0/24'}),
'extranet': forms.Textarea(
attrs={'placeholder': 'IP段之间用逗号隔开201.1.32.1/24,202.2.32.1/24'})
}
help_texts = {
'name': '* required'
}
class AdminUserForm(forms.ModelForm):
# Form field name can not start with `_`, so redefine it,
password = forms.CharField(
widget=forms.PasswordInput, max_length=100,
strip=True, required=False,
help_text=_('If also set private key, use that first'),
)
# Need use upload private key file except paste private key content
private_key_file = forms.FileField(required=False)
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
admin_user = super(AdminUserForm, self).save(commit=commit)
password = self.cleaned_data['password']
private_key = self.cleaned_data['private_key_file']
if password:
admin_user.password = password
if private_key:
public_key = ssh_pubkey_gen(private_key)
admin_user.private_key = private_key
admin_user.public_key = public_key
admin_user.save()
return admin_user
def clean_private_key_file(self):
private_key_file = self.cleaned_data['private_key_file']
if private_key_file:
private_key = private_key_file.read()
if not validate_ssh_private_key(private_key):
raise forms.ValidationError(_('Invalid private key'))
return private_key
return private_key_file
def clean(self):
password = self.cleaned_data['password']
private_key_file = self.cleaned_data.get('private_key_file', '')
if not self.instance and not (password or private_key_file):
raise forms.ValidationError(
_('Password and private key file must be input one'))
class Meta:
model = AdminUser
fields = ['name', 'username', 'password',
'private_key_file', 'comment']
widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
}
help_texts = {
'name': '* required',
'username': '* required',
}
class SystemUserForm(forms.ModelForm):
# Admin user assets define, let user select, save it in form not in view
auto_generate_key = forms.BooleanField(initial=True, required=False)
# Form field name can not start with `_`, so redefine it,
password = forms.CharField(widget=forms.PasswordInput, required=False,
max_length=100, strip=True)
# Need use upload private key file except paste private key content
private_key_file = forms.FileField(required=False)
def __init__(self, *args, **kwargs):
super(SystemUserForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
system_user = super(SystemUserForm, self).save(commit=commit)
password = self.cleaned_data['password']
private_key_file = self.cleaned_data.get('private_key_file')
if system_user.auth_method == 'P':
if password:
system_user.password = password
elif system_user.auth_method == 'K':
if self.cleaned_data['auto_generate_key']:
private_key, public_key = ssh_key_gen(username=system_user.name)
logger.info('Generate private key and public key')
else:
private_key = private_key_file.read().strip()
public_key = ssh_pubkey_gen(private_key=private_key)
system_user.private_key = private_key
system_user.public_key = public_key
system_user.save()
return self.instance
def clean_private_key_file(self):
if self.data['auth_method'] == 'K' and \
not self.cleaned_data['auto_generate_key']:
if not self.cleaned_data['private_key_file']:
raise forms.ValidationError(_('Private key required'))
else:
key_string = self.cleaned_data['private_key_file'].read()
self.cleaned_data['private_key_file'].seek(0)
if not validate_ssh_private_key(key_string):
raise forms.ValidationError(_('Invalid private key'))
return self.cleaned_data['private_key_file']
def clean_password(self):
if self.data['auth_method'] == 'P':
if not self.cleaned_data.get('password'):
raise forms.ValidationError(_('Password required'))
return self.cleaned_data['password']
class Meta:
model = SystemUser
fields = [
'name', 'username', 'protocol', 'auto_generate_key', 'password',
'private_key_file', 'auth_method', 'auto_push', 'sudo',
'comment', 'shell'
]
widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
}
help_texts = {
'name': '* required',
'username': '* required',
'auto_push': 'Auto push system user to asset',
}
class SystemUserUpdateForm(forms.ModelForm):
# Admin user assets define, let user select, save it in form not in view
auto_generate_key = forms.BooleanField(initial=False, required=False)
# Form field name can not start with `_`, so redefine it,
password = forms.CharField(widget=forms.PasswordInput, required=False,
max_length=100, strip=True)
# Need use upload private key file except paste private key content
private_key_file = forms.FileField(required=False)
def __init__(self, *args, **kwargs):
super(SystemUserUpdateForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
system_user = super(SystemUserUpdateForm, self).save(commit=commit)
password = self.cleaned_data['password']
private_key_file = self.cleaned_data.get('private_key_file')
if system_user.auth_method == 'P' and password:
system_user.password = password
elif system_user.auth_method == 'K' and private_key_file:
private_key = private_key_file.read().strip()
public_key = ssh_pubkey_gen(private_key=private_key)
system_user.private_key = private_key
system_user.public_key = public_key
system_user.save()
return self.instance
def clean_private_key_file(self):
if self.data['auth_method'] == 'K' and self.cleaned_data['private_key_file']:
key_string = self.cleaned_data['private_key_file'].read()
self.cleaned_data['private_key_file'].seek(0)
if not validate_ssh_private_key(key_string):
raise forms.ValidationError(_('Invalid private key'))
return self.cleaned_data['private_key_file']
class Meta:
model = SystemUser
fields = [
'name', 'username', 'protocol', 'auto_generate_key', 'password',
'private_key_file', 'auth_method', 'auto_push', 'sudo',
'comment', 'shell'
]
widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
}
help_texts = {
'name': '* required',
'username': '* required',
'auto_push': 'Auto push system user to asset',
}
class FileForm(forms.Form):
file = forms.FileField()

18
apps/assets/hands.py Normal file
View File

@@ -0,0 +1,18 @@
"""
jumpserver.__app__.hands.py
~~~~~~~~~~~~~~~~~
This app depends other apps api, function .. should be import or write mack here.
Other module of this app shouldn't connect with other app.
:copyright: (c) 2014-2017 by Jumpserver Team.
:license: GPL v2, see LICENSE for more details.
"""
from users.utils import AdminUserRequiredMixin
from users.permissions import IsAppUser, IsSuperUser, IsValidUser
from users.models import User, UserGroup
from perms.utils import get_user_granted_assets
from perms.tasks import push_users

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from .idc import *
from .user import *
from .group import *
from .asset import *
from .utils import *

156
apps/assets/models/asset.py Normal file
View File

@@ -0,0 +1,156 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
from django.db import models
import logging
from django.utils.translation import ugettext_lazy as _
from . import IDC, AssetGroup, AdminUser, SystemUser
__all__ = ['Asset']
logger = logging.getLogger(__name__)
def get_default_idc():
return IDC.initial()
class Asset(models.Model):
STATUS_CHOICES = (
('In use', _('In use')),
('Out of use', _('Out of use')),
)
TYPE_CHOICES = (
('Server', _('Server')),
('VM', _('VM')),
('Switch', _('Switch')),
('Router', _('Router')),
('Firewall', _('Firewall')),
('Storage', _("Storage")),
)
ENV_CHOICES = (
('Prod', 'Production'),
('Dev', 'Development'),
('Test', 'Testing'),
)
# Important
ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True)
hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname'))
port = models.IntegerField(default=22, verbose_name=_('Port'))
groups = models.ManyToManyField(AssetGroup, blank=True, related_name='assets',
verbose_name=_('Asset groups'))
admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets',
on_delete=models.SET_NULL, verbose_name=_("Admin user"))
system_users = models.ManyToManyField(SystemUser, blank=True,
related_name='assets',
verbose_name=_("System User"))
idc = models.ForeignKey(IDC, blank=True, null=True, related_name='assets',
on_delete=models.SET_NULL, verbose_name=_('IDC'),)
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
type = models.CharField(choices=TYPE_CHOICES, max_length=16, blank=True, null=True,
default='Server', verbose_name=_('Asset type'),)
env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True,
default='Prod', verbose_name=_('Asset environment'),)
status = models.CharField(choices=STATUS_CHOICES, max_length=12, null=True, blank=True,
default='In use', verbose_name=_('Asset status'))
# Some information
public_ip = models.GenericIPAddressField(max_length=32, blank=True,
null=True, verbose_name=_('Public IP'))
remote_card_ip = models.CharField(max_length=16, null=True, blank=True,
verbose_name=_('Remote control card IP'))
cabinet_no = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Cabinet number'))
cabinet_pos = models.IntegerField(null=True, blank=True, verbose_name=_('Cabinet position'))
number = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Asset number'))
# Collect
vendor = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Vendor'))
model = models.CharField(max_length=54, null=True, blank=True, verbose_name=_('Model'))
sn = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Serial number'))
cpu_model = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('CPU model'))
cpu_count = models.IntegerField(null=True, verbose_name=_('CPU count'))
cpu_cores = models.IntegerField(null=True, verbose_name=_('CPU cores'))
memory = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Memory'))
disk_total = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk total'))
disk_info = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk info'))
platform = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Platform'))
os = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('OS'))
os_version = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('OS version'))
os_arch = models.CharField(max_length=16, blank=True, null=True, verbose_name=_('OS arch'))
hostname_raw = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Hostname raw'))
created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by'))
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date created'))
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
def __unicode__(self):
return '%s <%s: %s>' % (self.hostname, self.ip, self.port)
__str__ = __unicode__
@property
def is_valid(self):
warning = ''
if not self.is_active:
warning += ' inactive'
else:
return True, ''
return False, warning
def to_json(self):
return {
'id': self.id,
'hostname': self.hostname,
'ip': self.ip,
'port': self.port,
}
def _to_secret_json(self):
"""Ansible use it create inventory"""
return {
'id': self.id,
'hostname': self.hostname,
'ip': self.ip,
'port': self.port,
'groups': [group.name for group in self.groups.all()],
'username': self.admin_user.username if self.admin_user else '',
'password': self.admin_user.password if self.admin_user else '',
'private_key': self.admin_user.private_key_file if self.admin_user else None,
'become': {
'method': self.admin_user.become_method,
'user': self.admin_user.become_user,
'pass': self.admin_user.become_pass,
} if self.admin_user and self.admin_user.become else {},
}
class Meta:
unique_together = ('ip', 'port')
@classmethod
def generate_fake(cls, count=100):
from random import seed, choice
import forgery_py
from django.db import IntegrityError
seed()
for i in range(count):
asset = cls(ip='%s.%s.%s.%s' % (i, i, i, i),
hostname=forgery_py.internet.user_name(True),
admin_user=choice(AdminUser.objects.all()),
idc=choice(IDC.objects.all()),
port=22,
created_by='Fake')
try:
asset.save()
asset.system_users = [choice(SystemUser.objects.all()) for i in range(3)]
asset.groups = [choice(AssetGroup.objects.all()) for i in range(3)]
logger.debug('Generate fake asset : %s' % asset.ip)
except IntegrityError:
print('Error continue')
continue

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
from django.db import models
import logging
from django.utils.translation import ugettext_lazy as _
from . import SystemUser
__all__ = ['AssetGroup']
logger = logging.getLogger(__name__)
class AssetGroup(models.Model):
name = models.CharField(max_length=64, unique=True, verbose_name=_('Name'))
system_users = models.ManyToManyField(SystemUser, related_name='asset_groups', blank=True)
created_by = models.CharField(max_length=32, blank=True, verbose_name=_('Created by'))
date_created = models.DateTimeField(auto_now_add=True, null=True, verbose_name=_('Date created'))
comment = models.TextField(blank=True, verbose_name=_('Comment'))
def __unicode__(self):
return self.name
__str__ = __unicode__
class Meta:
ordering = ['name']
@classmethod
def initial(cls):
asset_group = cls(name=_('Default'), comment=_('Default asset group'))
asset_group.save()
@classmethod
def generate_fake(cls, count=100):
from random import seed
import forgery_py
from django.db import IntegrityError
seed()
for i in range(count):
group = cls(name=forgery_py.name.full_name(),
comment=forgery_py.lorem_ipsum.sentence(),
created_by='Fake')
try:
group.save()
logger.debug('Generate fake asset group: %s' % group.name)
except IntegrityError:
print('Error continue')
continue

69
apps/assets/models/idc.py Normal file
View File

@@ -0,0 +1,69 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
import logging
from django.db import models
from django.utils.translation import ugettext_lazy as _
__all__ = ['IDC']
logger = logging.getLogger(__name__)
class IDC(models.Model):
name = models.CharField(max_length=32, verbose_name=_('Name'))
bandwidth = models.CharField(
max_length=32, blank=True, verbose_name=_('Bandwidth'))
contact = models.CharField(
max_length=128, blank=True, verbose_name=_('Contact'))
phone = models.CharField(max_length=32, blank=True,
verbose_name=_('Phone'))
address = models.CharField(
max_length=128, blank=True, verbose_name=_("Address"))
intranet = models.TextField(blank=True, verbose_name=_('Intranet'))
extranet = models.TextField(blank=True, verbose_name=_('Extranet'))
date_created = models.DateTimeField(
auto_now_add=True, null=True, verbose_name=_('Date created'))
operator = models.CharField(
max_length=32, blank=True, verbose_name=_('Operator'))
created_by = models.CharField(
max_length=32, blank=True, verbose_name=_('Created by'))
comment = models.TextField(blank=True, verbose_name=_('Comment'))
def __unicode__(self):
return self.name
__str__ = __unicode__
@classmethod
def initial(cls):
return cls.objects.get_or_create(name=_('Default'), created_by=_('System'), comment=_('Default IDC'))[0]
class Meta:
ordering = ['name']
@classmethod
def generate_fake(cls, count=5):
from random import seed, choice
import forgery_py
from django.db import IntegrityError
seed()
for i in range(count):
idc = cls(name=forgery_py.name.full_name(),
bandwidth='200M',
contact=forgery_py.name.full_name(),
phone=forgery_py.address.phone(),
address=forgery_py.address.city() + forgery_py.address.street_address(),
operator=choice(['北京联通', '北京电信', 'BGP全网通']),
comment=forgery_py.lorem_ipsum.sentence(),
created_by='Fake')
try:
idc.save()
logger.debug('Generate fake asset group: %s' % idc.name)
except IntegrityError:
print('Error continue')
continue

259
apps/assets/models/user.py Normal file
View File

@@ -0,0 +1,259 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
import os
import logging
from hashlib import md5
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from common.utils import signer, validate_ssh_private_key, ssh_key_string_to_obj
__all__ = ['AdminUser', 'SystemUser', 'private_key_validator']
logger = logging.getLogger(__name__)
def private_key_validator(value):
if not validate_ssh_private_key(value):
raise ValidationError(
_('%(value)s is not an even number'),
params={'value': value},
)
class AdminUser(models.Model):
BECOME_METHOD_CHOICES = (
('sudo', 'sudo'),
('su', 'su'),
)
name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
username = models.CharField(max_length=16, verbose_name=_('Username'))
_password = models.CharField(
max_length=256, blank=True, null=True, verbose_name=_('Password'))
_private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'),
validators=[private_key_validator,])
become = models.BooleanField(default=True)
become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4)
become_user = models.CharField(default='root', max_length=64)
become_pass = models.CharField(default='', max_length=128)
_public_key = models.TextField(
max_length=4096, blank=True, verbose_name=_('SSH public key'))
comment = models.TextField(blank=True, verbose_name=_('Comment'))
date_created = models.DateTimeField(auto_now_add=True, null=True)
created_by = models.CharField(
max_length=32, null=True, verbose_name=_('Created by'))
def __unicode__(self):
return self.name
__str__ = __unicode__
@property
def password(self):
if self._password:
return signer.unsign(self._password)
else:
return ''
@password.setter
def password(self, password_raw):
self._password = signer.sign(password_raw)
@property
def private_key(self):
if self._private_key:
key_str = signer.unsign(self._private_key)
return ssh_key_string_to_obj(key_str)
else:
return None
@private_key.setter
def private_key(self, private_key_raw):
self._private_key = signer.sign(private_key_raw)
@property
def private_key_file(self):
if not self.private_key:
return None
project_dir = settings.PROJECT_DIR
tmp_dir = os.path.join(project_dir, 'tmp')
key_name = md5(self._private_key.encode()).hexdigest()
key_path = os.path.join(tmp_dir, key_name)
if not os.path.exists(key_path):
self.private_key.write_private_key_file(key_path)
return key_path
@property
def public_key(self):
return signer.unsign(self._public_key)
@public_key.setter
def public_key(self, public_key_raw):
self._public_key = signer.sign(public_key_raw)
@property
def assets_amount(self):
return self.assets.count()
class Meta:
ordering = ['name']
@classmethod
def generate_fake(cls, count=10):
from random import seed
import forgery_py
from django.db import IntegrityError
seed()
for i in range(count):
obj = cls(name=forgery_py.name.full_name(),
username=forgery_py.internet.user_name(),
password=forgery_py.lorem_ipsum.word(),
comment=forgery_py.lorem_ipsum.sentence(),
created_by='Fake')
try:
obj.save()
logger.debug('Generate fake asset group: %s' % obj.name)
except IntegrityError:
print('Error continue')
continue
class SystemUser(models.Model):
PROTOCOL_CHOICES = (
('ssh', 'ssh'),
)
AUTH_METHOD_CHOICES = (
('P', 'Password'),
('K', 'Public key'),
)
name = models.CharField(max_length=128, unique=True,
verbose_name=_('Name'))
username = models.CharField(max_length=16, verbose_name=_('Username'))
_password = models.CharField(
max_length=256, blank=True, verbose_name=_('Password'))
protocol = models.CharField(
max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol'))
_private_key = models.TextField(
max_length=8192, blank=True, verbose_name=_('SSH private key'))
_public_key = models.TextField(
max_length=8192, blank=True, verbose_name=_('SSH public key'))
auth_method = models.CharField(choices=AUTH_METHOD_CHOICES, default='K',
max_length=1, verbose_name=_('Auth method'))
auto_push = models.BooleanField(default=True, verbose_name=_('Auto push'))
sudo = models.TextField(
max_length=4096, default='/sbin/ifconfig', verbose_name=_('Sudo'))
shell = models.CharField(
max_length=64, default='/bin/bash', verbose_name=_('Shell'))
date_created = models.DateTimeField(auto_now_add=True)
created_by = models.CharField(
max_length=32, blank=True, verbose_name=_('Created by'))
comment = models.TextField(
max_length=128, blank=True, verbose_name=_('Comment'))
def __unicode__(self):
return self.name
__str__ = __unicode__
@property
def password(self):
if self._password:
return signer.unsign(self._password)
return None
@password.setter
def password(self, password_raw):
self._password = signer.sign(password_raw)
@property
def private_key(self):
if self._private_key:
return signer.unsign(self._private_key)
return None
@private_key.setter
def private_key(self, private_key_raw):
self._private_key = signer.sign(private_key_raw)
@property
def public_key(self):
return signer.unsign(self._public_key)
@public_key.setter
def public_key(self, public_key_raw):
self._public_key = signer.sign(public_key_raw)
def get_assets_inherit_from_asset_groups(self):
assets = set()
asset_groups = self.asset_groups.all()
for asset_group in asset_groups:
for asset in asset_group.assets.all():
setattr(asset, 'is_inherit_from_asset_groups', True)
setattr(asset, 'inherit_from_asset_groups',
getattr(asset, 'inherit_from_asset_groups', set()).add(asset_group))
assets.add(asset)
return assets
def get_assets(self):
assets = set(self.assets.all()
) | self.get_assets_inherit_from_asset_groups()
return list(assets)
def _to_secret_json(self):
"""Push system user use it"""
return {
'name': self.name,
'username': self.username,
'shell': self.shell,
'sudo': self.sudo,
'password': self.password,
'public_key': self.public_key
}
@property
def assets_amount(self):
return self.assets.count()
@property
def asset_group_amount(self):
return self.asset_groups.count()
def to_json(self):
return {
'id': self.id,
'name': self.name,
'username': self.username,
'protocol': self.protocol,
'auth_method': self.auth_method,
'auto_push': self.auto_push,
}
class Meta:
ordering = ['name']
@classmethod
def generate_fake(cls, count=10):
from random import seed
import forgery_py
from django.db import IntegrityError
seed()
for i in range(count):
obj = cls(name=forgery_py.name.full_name(),
username=forgery_py.internet.user_name(),
password=forgery_py.lorem_ipsum.word(),
comment=forgery_py.lorem_ipsum.sentence(),
created_by='Fake')
try:
obj.save()
logger.debug('Generate fake asset group: %s' % obj.name)
except IntegrityError:
print('Error continue')
continue

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from . import IDC, SystemUser, AdminUser, AssetGroup, Asset
__all__ = ['init_model', 'generate_fake']
def init_model():
for cls in [IDC, SystemUser, AdminUser, AssetGroup, Asset]:
if hasattr(cls, 'initial'):
cls.initial()
def generate_fake():
for cls in [IDC, SystemUser, AdminUser, AssetGroup, Asset]:
if hasattr(cls, 'generate_fake'):
cls.generate_fake()
if __name__ == '__main__':
pass

189
apps/assets/serializers.py Normal file
View File

@@ -0,0 +1,189 @@
# -*- coding: utf-8 -*-
from django.utils.translation import ugettext_lazy as _
from django.core.cache import cache
from rest_framework import viewsets, serializers, generics
from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser
from common.mixins import IDInFilterMixin
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin
class AssetGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
assets_amount = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = AssetGroup
list_serializer_class = BulkListSerializer
fields = ['id', 'name', 'comment', 'assets_amount', 'assets']
@staticmethod
def get_assets_amount(obj):
return obj.assets.count()
class AssetUpdateGroupSerializer(serializers.ModelSerializer):
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
class Meta:
model = Asset
fields = ['id', 'groups']
class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
class Meta:
model = Asset
fields = ['id', 'system_users']
class AssetGroupUpdateSerializer(serializers.ModelSerializer):
"""update the asset group, and add or delete the asset to the group"""
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = AssetGroup
fields = ['id', 'assets']
class AssetGroupUpdateSystemUserSerializer(serializers.ModelSerializer):
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
class Meta:
model = AssetGroup
fields = ['id', 'system_users']
class IDCUpdateAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = IDC
fields = ['id', 'assets']
class AdminUserSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = AdminUser
fields = '__all__'
def get_field_names(self, declared_fields, info):
fields = super(AdminUserSerializer, self).get_field_names(declared_fields, info)
fields.append('assets_amount')
return fields
class SystemUserSerializer(serializers.ModelSerializer):
class Meta:
model = SystemUser
exclude = ('_password', '_private_key', '_public_key')
def get_field_names(self, declared_fields, info):
fields = super(SystemUserSerializer, self).get_field_names(declared_fields, info)
fields.extend(['assets_amount'])
return fields
class AssetSystemUserSerializer(serializers.ModelSerializer):
class Meta:
model = SystemUser
fields = ('id', 'name', 'username', 'protocol', 'auth_method', 'comment')
class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = SystemUser
fields = ['id', 'assets']
class SystemUserUpdateAssetGroupSerializer(serializers.ModelSerializer):
asset_groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
class Meta:
model = SystemUser
fields = ['id', 'asset_groups']
class SystemUserSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = SystemUser
fields = ('id', 'name', 'username')
class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
# system_users = SystemUserSerializer(many=True, read_only=True)
# admin_user = AdminUserSerializer(many=False, read_only=True)
hardware = serializers.SerializerMethodField()
is_online = serializers.SerializerMethodField()
class Meta(object):
model = Asset
list_serializer_class = BulkListSerializer
fields = '__all__'
@staticmethod
def get_hardware(obj):
if obj.cpu_count:
return '{} Core {} {}'.format(obj.cpu_count*obj.cpu_cores, obj.memory, obj.disk_total)
else:
return ''
@staticmethod
def get_is_online(obj):
hostname = obj.hostname
if cache.get(hostname) == '1':
return True
elif cache.get(hostname) == '0':
return False
else:
return 'Unknown'
def get_field_names(self, declared_fields, info):
fields = super(AssetSerializer, self).get_field_names(declared_fields, info)
fields.extend(['get_type_display', 'get_env_display'])
return fields
class AssetGrantedSerializer(serializers.ModelSerializer):
system_users_granted = AssetSystemUserSerializer(many=True, read_only=True)
is_inherited = serializers.SerializerMethodField()
system_users_join = serializers.SerializerMethodField()
class Meta(object):
model = Asset
fields = ("id", "hostname", "ip", "port", "system_users_granted", "is_inherited",
"is_active", "system_users_join", "comment")
@staticmethod
def get_is_inherited(obj):
if getattr(obj, 'inherited', ''):
return True
else:
return False
@staticmethod
def get_system_users_join(obj):
return ', '.join([system_user.username for system_user in obj.system_users_granted])
class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer):
assets_amount = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = IDC
fields = '__all__'
@staticmethod
def get_assets_amount(obj):
return obj.assets.count()
def get_field_names(self, declared_fields, info):
fields = super(IDCSerializer, self).get_field_names(declared_fields, info)
fields.append('assets_amount')
return fields

80
apps/assets/tasks.py Normal file
View File

@@ -0,0 +1,80 @@
# ~*~ coding: utf-8 ~*~
from celery import shared_task
import json
from django.core.cache import cache
from ops.tasks import run_AdHoc
from common.utils import get_object_or_none, capacity_convert, sum_capacity
from .models import Asset
@shared_task
def update_assets_hardware_info(assets):
task_tuple = (
('setup', ''),
)
summary, result = run_AdHoc(task_tuple, assets, record=False)
for hostname, info in result['contacted'].items():
if info:
info = info[0]['ansible_facts']
else:
continue
asset = get_object_or_none(Asset, hostname=hostname)
if not asset:
continue
___vendor = info['ansible_system_vendor']
___model = info['ansible_product_version']
___sn = info['ansible_product_serial']
for ___cpu_model in info['ansible_processor']:
if ___cpu_model.endswith('GHz'):
break
else:
___cpu_model = 'Unknown'
___cpu_count = info['ansible_processor_count']
___cpu_cores = info['ansible_processor_cores']
___memory = '%s %s' % capacity_convert('{} MB'.format(info['ansible_memtotal_mb']))
disk_info = {}
for dev, dev_info in info['ansible_devices'].items():
if dev_info['removable'] == '0':
disk_info[dev] = dev_info['size']
___disk_total = '%s %s' % sum_capacity(disk_info.values())
___disk_info = json.dumps(disk_info)
___platform = info['ansible_system']
___os = info['ansible_distribution']
___os_version = info['ansible_distribution_version']
___os_arch = info['ansible_architecture']
___hostname_raw = info['ansible_hostname']
for k, v in locals().items():
if k.startswith('___'):
setattr(asset, k.strip('_'), v)
asset.save()
return summary
@shared_task
def update_assets_hardware_period():
assets = Asset.objects.filter(type__in=['Server', 'VM'])
update_assets_hardware_info(assets)
@shared_task
def test_admin_user_connective_period():
assets = Asset.objects.filter(type__in=['Server', 'VM'])
task_tuple = (
('ping', ''),
)
summary, _ = run_AdHoc(task_tuple, assets, record=False)
for i in summary['success']:
cache.set(i, '1', 2*60*60*60)
for i, msg in summary['failed']:
cache.set(i, '0', 60*60*60)
return summary

View File

@@ -0,0 +1,42 @@
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}asset_group_bulk_update_modal{% endblock %}
{% block modal_class %}modal-lg{% endblock %}
{% block modal_title%}{% trans "Update Asset Group" %}{% endblock %}
{% block modal_body %}
{% load bootstrap3 %}
<p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p>
<form method="post" class="form-horizontal" action="" id="fm_asset_group_bulk_update">
<div class="form-group">
<label for="assets" class="col-sm-2 control-label">{% trans 'Assets' %}</label>
<div class="col-sm-9" id="select2-container">
<select name="assets" id="select2_groups" data-placeholder="{% trans 'Select Asset' %}" class="select2 form-control m-b" multiple>
{% for asset in assets %}
<option value="{{ asset.id }}">{{ asset.ip }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label for="system_users" class="col-sm-2 control-label">{% trans 'System users' %}</label>
<div class="col-sm-9" id="select2-container">
<select name="system_users" id="select2_groups" data-placeholder="{% trans 'Select System Users' %}" class="select2 form-control m-b" multiple>
{% for system_user in system_users %}
<option value="{{ system_user.id }}">{{ system_user.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-9 col-lg-9 col-sm-offset-2">
<div class="checkbox checkbox-success">
<input type="checkbox" name="enable_otp" checked id="id_enable_otp"><label for="id_enable_otp">{% trans 'Enable-OTP' %}</label>
</div>
</div>
</div>
</form>
{% endblock %}
{% block modal_confirm_id %}btn_asset_group_bulk_update{% endblock %}

View File

@@ -0,0 +1,29 @@
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}asset_import_modal{% endblock %}
{% block modal_title%}{% trans "Import asset" %}{% endblock %}
{% block modal_body %}
<form method="post" action="{% url 'assets:asset-import' %}" id="fm_asset_import" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label class="control-label" for="id_assets">{% trans "Template" %}</label>
<a href="{% url 'assets:asset-export' %}" style="display: block">{% trans 'Download' %}</a>
</div>
<div class="form-group">
<label class="control-label" for="id_users">{% trans "Asset csv file" %}</label>
<input id="id_assets" type="file" name="file" />
<span class="help-block red-fonts">
{% trans 'If set id, will use this id update asset existed' %}
</span>
</div>
</form>
<p>
<p class="text-success" id="id_created"></p>
<p id="id_created_detail"></p>
<p class="text-warning" id="id_updated"></p>
<p id="id_updated_detail"></p>
<p class="text-danger" id="id_failed"></p>
<p id="id_failed_detail"></p>
</p>
{% endblock %}
{% block modal_confirm_id %}btn_asset_import{% endblock %}

View File

@@ -0,0 +1,121 @@
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>{% trans 'Create system user' %}</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form enctype="multipart/form-data" method="post" class="form-horizontal" action="" >
{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">
{{ form.non_field_errors }}
</div>
{% endif %}
<h3>{% trans 'Basic' %}</h3>
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.username layout="horizontal" %}
{% bootstrap_field form.protocol layout="horizontal" %}
<h3>{% trans 'Auth' %}</h3>
{% bootstrap_field form.auth_method layout="horizontal" %}
{% block auth %}
<div class="password-auth hidden">
{% bootstrap_field form.password layout="horizontal" %}
</div>
<div class="public-key-auth">
<div class="form-group">
<label for="{{ form.auto_generate_key.id_for_label }}" class="col-sm-2 control-label">{% trans 'Auto generate key' %}</label>
<div class="col-sm-8">
{{ form.auto_generate_key}}
</div>
</div>
<div>
{% bootstrap_field form.private_key_file layout="horizontal" %}
</div>
</div>
{% endblock %}
<div class="form-group">
<label for="{{ form.as_push.id_for_label }}" class="col-sm-2 control-label">{% trans 'Auto push' %}</label>
<div class="col-sm-8">
{{ form.auto_push}}
</div>
</div>
<h3>{% trans 'Other' %}</h3>
{% bootstrap_field form.sudo layout="horizontal" %}
{% bootstrap_field form.shell layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
var auth_method = '#'+'{{ form.auth_method.id_for_label }}';
var auto_generate_key = '#'+'{{ form.auto_generate_key.id_for_label }}';
function authMethodDisplay() {
if ($(auth_method).val() == 'P') {
$('.password-auth').removeClass('hidden');
$('.public-key-auth').addClass('hidden');
$('#'+'{{ form.password.id_for_label }}').attr('required', 'required');
$('#'+'{{ form.password.id_for_label }}').removeAttr('disabled');
$('#'+'{{ form.private_key_file.id_for_label }}').removeAttr('required');
} else if ($(auth_method).val() == 'K') {
$('.password-auth').addClass('hidden');
$('.public-key-auth').removeClass('hidden');
$('#'+'{{ form.password.id_for_label }}').removeAttr('required');
$('#'+'{{ form.password.id_for_label }}').attr('disabled', 'disabled');
if ($(auto_generate_key).prop('checked')){
$('#'+'{{ form.private_key_file.id_for_label }}').closest('.form-group').addClass('hidden');
} else {
$('#'+'{{ form.private_key_file.id_for_label }}').closest('.form-group').removeClass('hidden');
$('#'+'{{ form.private_key_file.id_for_label }}').closest('.form-group input').attr('required', 'required');
}
}
}
$(document).ready(function () {
$('.select2').select2();
authMethodDisplay();
$(auth_method).change(function () {
authMethodDisplay();
});
$(auto_generate_key).change(function () {
authMethodDisplay();
});
})
</script>
{% endblock %}

View File

@@ -0,0 +1,62 @@
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>{% trans 'Create admin user' %}</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
{% if form.non_field_errors %}
<div class="alert alert-danger">
{{ form.non_field_errors }}
</div>
{% endif %}
<form enctype="multipart/form-data" method="post" class="form-horizontal" action="" >
{% csrf_token %}
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.username layout="horizontal" %}
{% bootstrap_field form.password layout="horizontal" %}
{% bootstrap_field form.private_key_file layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
$('.select2').select2();
})
</script>
{% endblock %}

View File

@@ -0,0 +1,441 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active">
<a href="" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'assets:admin-user-update' pk=admin_user.id %}"><i class="fa fa-edit"></i>Update</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-danger btn-delete-admin-user">
<i class="fa fa-edit"></i>Delete
</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label"><b>{{ admin_user.name }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td>{% trans 'Name' %}:</td>
<td><b>{{ admin_user.name }}</b></td>
</tr>
<tr>
<td>{% trans 'Username' %}:</td>
<td><b>{{ admin_user.username }}</b></td>
</tr>
<tr>
<td>{% trans 'Date created' %}:</td>
<td><b>{{ admin_user.date_created }}</b></td>
</tr>
<tr>
<td>{% trans 'Created by' %}:</td>
<td><b>{{ asset_group.created_by }}</b></td>
</tr>
<tr>
<td>{% trans 'Comment' %}:</td>
<td><b>{{ admin_user.comment }}</b></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left">{% trans 'Asset list of ' %} <b>{{ admin_user.name }}</b> <span class="badge"> {{ paginator.count }}</span></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover" id="system_user_assets_table">
<thead>
<tr>
<th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th>
<th>{% trans 'Alive' %}</th>
<th>{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
{# {% for asset in page_obj %}#}
{# <tr>#}
{# <td>{{ asset.hostname }}</td>#}
{# <td>{{ asset.ip }}</td>#}
{# <td>{{ asset.port }}</td>#}
{# <td>Alive</td>#}
{# </tr>#}
{# {% endfor %}#}
</tbody>
</table>
{# <div class="row">#}
{# {% include '_pagination.html' %}#}
{# </div>#}
</div>
</div>
</div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Quick update' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="50%">{% trans 'Get install script' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs" style="width: 54px">{% trans 'Get' %}</button>
</span>
</td>
</tr>
<tr>
<td width="50%">{% trans 'Retest asset connectivity' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs" style="width: 54px">{% trans 'Start' %}</button>
</span>
</td>
</tr>
<tr>
<td width="50%">{% trans 'Reset private key' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs" style="width: 54px">{% trans 'Reset' %}</button>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Replace asset admin user with this' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<form>
<tr class="no-borders-tr">
<td colspan="2">
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for asset in assets_remain %}
<option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-info btn-sm btn-replace-asset-admin_user">{% trans 'Replace' %}</button>
</td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
<div class="panel panel-warning">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Replace asset admin user with this admin user' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<form>
<tr class="no-borders-tr">
<td colspan="2">
<select data-placeholder="{% trans 'Select asset groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for asset_group in asset_groups %}
<option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-warning btn-sm btn-replace-asset_groups-admin_user">{% trans 'Replace' %}</button>
</td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
Array.prototype.unique = function(){
var res = [];
var json = {};
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){
res.push(this[i]);
json[this[i]] = 1;
}
}
return res;
};
function objectRemove(obj, name, url, data) {
function doRemove() {
var body = data;
var success = function() {
swal('Remove!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Remove"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
swal({
title: 'Are you sure remove ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doRemove()
});
}
jumpserver.assets_selected = {};
jumpserver.asset_groups_selected = {};
$(document).ready(function () {
$('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
jumpserver.asset_groups_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
delete jumpserver.asset_groups_selected[data.id]
});
var options = {
ele: $('#system_user_assets_table'),
buttons: [],
order: [],
columnDefs: [
{targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_remove" data-aid="99991937">{% trans "Remove" %}</a>'.replace('99991937', rowData.id);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}?admin_user_id={{ admin_user.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "is_active" }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
function adminUserDelete(name, url) {
function doDelete() {
var body = {};
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
window.location.href="{% url 'assets:idc-list' %}";
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'DELETE',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
})
.on('click', '.btn-replace-asset-admin_user', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
jumpserver.asset_groups_selected = {};
var $data_table = $("#system_user_assets_table").DataTable();
var assets = [];
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
assets.unique();
var data = [];
var admin_user_id = {{ admin_user.id }};
var the_url = '{% url "api-assets:asset-list" %}';
for (var i=0; i<assets.length; i++) {
data.push({"id": assets[i], "admin_user": admin_user_id});
}
APIUpdateAttr({
url: the_url,
body: JSON.stringify(data),
method: 'PATCH'
});
$data_table.ajax.reload();
})
.on('click', '.btn-replace-asset_groups-admin_user', function () {
if (Object.keys(jumpserver.asset_groups_selected).length === 0) {
return false;
}
jumpserver.assets_selected = {};
var $data_table = $("#system_user_assets_table").DataTable();
var asset_groups = [];
var assets = [];
var data = [];
var the_url = '{% url "api-assets:asset-list" %}';
$.map(jumpserver.asset_groups_selected, function(value, index) {
asset_groups.push(parseInt(index));
});
$.ajax({
url: '{% url "api-assets:asset-group-list" %}?id__in=['+asset_groups.join(',')+']',
method: 'GET',
dataType: 'json',
success: function (result) {
for (var i=0; i<result.length; i++) {
for (var j=0; j<result[i]['assets'].length; j++) {
assets.push(result[i]['assets'][j])
}
}
for (var z=0; z<assets.length; z++) {
data.push({"id":assets[z], "admin_user":{{admin_user.id}} });
}
APIUpdateAttr({
url: the_url,
body: JSON.stringify(data),
method: 'PATCH'
});
$data_table.ajax.reload();
}
});
})
.on('click', '.btn_asset_remove', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:admin-user-detail' pk=admin_user.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var assets = [];
var delete_asset_id = $(this).data('aid');
$.ajax({
url: the_url,
method: 'GET',
dataType: 'json',
success: function (result) {
for (var i=0; i<result['assets'].length; i++) {
assets.push(result['assets'][i])
}
assets.remove(delete_asset_id);
var data = {"assets": assets};
objectRemove($this, name, the_url, data);
}
})
}).on('click', '.btn-delete-admin-user', function () {
var $this = $(this);
var name = "{{ admin_user.name }}";
var uid = "{{ admin_user.id }}";
var the_url = '{% url "api-assets:admin-user-detail" pk=99991937 %}'.replace('99991937', uid);
var redirect_url = "{% url 'assets:admin-user-list' %}";
objectDelete($this, name, the_url, redirect_url);
})
</script>
{% endblock %}

View File

@@ -0,0 +1,71 @@
{% extends '_base_list.html' %}
{% load i18n static %}
{% block table_search %}
{% endblock %}
{% block table_container %}
<div class="uc pull-left m-l-5 m-r-5">
<a href="{% url "assets:admin-user-create" %}" class="btn btn-sm btn-primary"> {% trans "Create admin user" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="admin_user_list_table" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" class="ipt_check_all" >
</th>
<th class="text-center">{% trans 'Name' %}</th>
<th class="text-center">{% trans 'Username' %}</th>
<th class="text-center">{% trans 'Asset num' %}</th>
<th class="text-center">{% trans 'Comment' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function(){
var options = {
ele: $('#admin_user_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:admin-user-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 4, createdCell: function (td, cellData) {
var innerHtml = cellData.length > 8 ? cellData.substring(0, 24) + '...': cellData;
$(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');
}},
{targets: 5, createdCell: function (td, cellData, rowData) {
{# var script_btn = '<a href="{% url "assets:admin-user-update" pk=99991937 %}" class="btn btn-xs btn-primary">{% trans "Script" %}</a>'.replace('99991937', cellData);#}
var update_btn = '<a href="{% url "assets:admin-user-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
{# $(td).html(script_btn + update_btn + del_btn)#}
$(td).html(update_btn + del_btn)
}}],
ajax_url: '{% url "api-assets:admin-user-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" },
{data: "comment" }, {data: "id" }],
};
jumpserver.initDataTable(options);
})
.on('click', '.btn_admin_user_delete', function () {
var $this = $(this);
var $data_table = $("#admin_user_list_table").DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:admin-user-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
});
</script>
{% endblock %}

View File

@@ -0,0 +1,69 @@
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% block form %}
<div class="ydxbd" id="formlists" style="display: block;">
<p id="tags_p" class="mgl-5 c02">选择需要修改属性</p>
<div class="tagBtnList">
<a class="label label-primary" id="change_all" value="1">全选</a>
{% for field in form %}
{% if field.name != 'assets' %}
<a data-id="{{ field.id_for_label }}" class="label label-default label-primary field-tag" value="1">{{ field.label }}</a>
{% endif %}
{% endfor %}
</div>
</div>
<form method="post" class="form-horizontal" id="add_form">
{% csrf_token %}
{% bootstrap_form form layout="horizontal" %}
<div class="form-group abc">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
$('.select2').select2();
}).on('click', '.field-tag', function() {
changeField(this);
}).on('click', '#change_all', function () {
var tag_fields = $('.field-tag');
var $this = $(this);
var active = '1';
if ($this.attr('value') == '0'){
active = '0';
$this.attr('value', '1').addClass('label-primary')
} else {
active = '1';
$this.attr('value', '0').removeClass('label-primary')
}
$.each(tag_fields, function (k, v) {
changeField(v, active)
})
});
function changeField(obj, active) {
var $this = $(obj);
var field_id = $this.data('id');
if (!active) {
active = $this.attr('value');
}
if (active == '0') {
$this.attr('value', '1').addClass('label-primary');
var form_groups = $('#add_form .form-group:not(.abc)');
form_groups.filter(':has(#' + field_id + ')').show().find('select,input').prop('disabled', false)
} else {
$this.attr('value', '0').removeClass('label-primary');
var form_groups = $('#add_form .form-group:not(.abc)');
form_groups.filter(':has(#' + field_id + ')').hide().find('select,input').prop('disabled', true)
}
}
</script>
{% endblock %}

View File

@@ -0,0 +1,58 @@
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% block form %}
<form action="" method="post" class="form-horizontal">
{% if form.non_field_errors %}
<div class="alert alert-danger">
{{ form.non_field_errors }}
</div>
{% endif %}
{% csrf_token %}
<h3>{% trans 'Basic' %}</h3>
{% bootstrap_field form.hostname layout="horizontal" %}
{% bootstrap_field form.ip layout="horizontal" %}
{% bootstrap_field form.public_ip layout="horizontal" %}
{% bootstrap_field form.port layout="horizontal" %}
{% bootstrap_field form.type layout="horizontal" %}
{% bootstrap_field form.env layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Group' %}</h3>
{% bootstrap_field form.idc layout="horizontal" %}
{% bootstrap_field form.groups layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Asset user' %}</h3>
{% bootstrap_field form.admin_user layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Other' %}</h3>
{% bootstrap_field form.comment layout="horizontal" %}
{% bootstrap_field form.is_active layout="horizontal" %}
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-default" type="reset"> {% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
$('.select2').select2();
$("#id_tags").select2({
tags: true,
maximumSelectionLength: 8 //最多能够选择的个数
//closeOnSelect: false
});
})
</script>
{% endblock %}

View File

@@ -0,0 +1,471 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href='{% static "css/plugins/select2/select2.min.css" %}' rel="stylesheet">
<link href='{% static "css/plugins/sweetalert/sweetalert.css" %}' rel="stylesheet">
<script src='{% static "js/plugins/select2/select2.full.min.js" %}'></script>
<script src='{% static "js/plugins/sweetalert/sweetalert.min.js" %}'></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active">
<a href="{% url 'assets:asset-detail' pk=asset.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Asset detail' %} </a>
</li>
{% if user.is_superuser %}
<li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'assets:asset-update' pk=asset.id %}"><i class="fa fa-edit"></i>Update</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-danger btn-delete-asset">
<i class="fa fa-edit"></i>Delete
</a>
</li>
{% endif %}
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label"><b>{{ asset.hostname }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="20%">{% trans 'Hostname' %}:</td>
<td><b>{{ asset.hostname }}</b></td>
</tr>
<tr>
<td>{% trans 'IP' %}:</td>
<td><b>{{ asset.ip }}</b></td>
</tr>
<tr>
<td>{% trans 'Public IP' %}:</td>
<td><b>{{ asset.public_ip }}</b></td>
</tr>
<tr>
<td>{% trans 'Port' %}:</td>
<td><b>{{ asset.port }}</b></td>
</tr>
<tr>
<td>{% trans 'Admin user' %}:</td>
{% if asset.admin_user %}
<td><b>{{ asset.admin_user.name }}</b></td>
{% else %}
<td><b>None</b></td>
{% endif %}
</tr>
<tr>
<td>{% trans 'Remote card IP' %}:</td>
<td><b>{{ asset.remote_card_ip }}</b></td>
</tr>
<tr>
<td>{% trans 'IDC' %}:</td>
<td><b>{{ asset.idc.name }}</b></td>
</tr>
<tr>
<td>{% trans 'Cabinet number' %}:</td>
<td><b>{{ asset.cabinet_no }}</b></td>
</tr>
<tr>
<td>{% trans 'Cabinet position' %}:</td>
<td><b>{{ asset.cabinet_pos }}</b></td>
</tr>
<tr>
<td>{% trans 'Vendor' %}:</td>
<td><b>{{ asset.vendor }}</b></td>
</tr>
<tr>
<td>{% trans 'Model' %}:</td>
<td><b>{{ asset.model }}</b></td>
</tr>
<tr>
<td>{% trans 'CPU' %}:</td>
<td><b>{{ asset.cpu_model }} {{ asset.cpu_count }}*{{ asset.cpu_cores }}</b></td>
</tr>
<tr>
<td>{% trans 'Memory' %}:</td>
<td><b>{{ asset.memory }}</b></td>
</tr>
<tr>
<td>{% trans 'Disk' %}:</td>
<td><b>{{ asset.disk_total }}</b></td>
</tr>
<tr>
<td>{% trans 'Platform' %}:</td>
<td><b>{{ asset.platform }}</b></td>
</tr>
<tr>
<td>{% trans 'OS' %}:</td>
<td><b>{{ asset.os }} {{ asset.os_version }} {{ asset.os_arch }}</b></td>
</tr>
<tr>
<td>{% trans 'Asset status' %}:</td>
<td><b>{{ asset.status }}</b></td>
</tr>
<tr>
<td>{% trans 'Is active' %}:</td>
<td><b>{{ asset.is_active }}</b></td>
</tr>
<tr>
<td>{% trans 'Asset type' %}:</td>
<td><b>{{ asset.type }}</b></td>
</tr>
<tr>
<td>{% trans 'Asset environment' %}:</td>
<td><b>{{ asset.env }}</b></td>
</tr>
<tr>
<td>{% trans 'Serial number' %}:</td>
<td><b>{{ asset.sn }}</b></td>
</tr>
<tr>
<td>{% trans 'Asset number' %}:</td>
<td><b>{{ asset.number }}</b></td>
</tr>
<tr>
<td>{% trans 'Created by' %}:</td>
<td><b>{{ asset.created_by }}</b></td>
</tr>
<tr>
<td>{% trans 'Date joined' %}:</td>
<td><b>{{ asset.date_joined|date:"Y-m-j H:i:s" }}</b></td>
</tr>
<tr>
<td>{% trans 'Comment' %}:</td>
<td><b>{{ asset.comment }}</b></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
{% if user.is_superuser %}
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Quick modify' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="50%">{% trans 'Active' %}:</td>
<td><span class="pull-right">
<div class="switch">
<div class="onoffswitch">
<input type="checkbox" {% if asset.is_active %} checked {% endif %} class="onoffswitch-checkbox" id="is_active">
<label class="onoffswitch-label" for="is_active">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
</div>
</span></td>
</tr>
<tr>
<td>{% trans 'Refresh hardware' %}:</td>
<td>
<span class="pull-right">
<button type="button" class="btn btn-primary btn-xs" id="btn_refresh_asset" style="width: 54px">{% trans 'Refresh' %}</button>
</span>
</td>
</tr>
<tr>
<td>{% trans 'Test admin user' %}:</td>
<td>
<span class="pull-right">
<button type="button" class="btn btn-primary btn-xs" id="btn_test_admin_user" style="width: 54px;">{% trans 'Test' %}</button>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Asset groups' %}
</div>
<div class="panel-body">
<table class="table group_edit" id="add-asset2group">
<tbody>
<form>
<tr>
<td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Join asset groups' %}" id="groups_selected" class="select2 groups" style="width: 100%" multiple="" tabindex="4">
{% for asset_group in asset_groups_remain %}
<option value="{{ asset_group.id }}" id="opt_{{ asset_group.id }}" >{{ asset_group.name }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td colspan="2" class="no-borders">
<button type="button" class="btn btn-info btn-sm" id="btn_add_user_group">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
{% for asset_group in asset_groups %}
<tr>
<td ><b class="bdg_group" data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td>
<td>
<button class="btn btn-danger pull-right btn-xs btn_leave_group" type="button"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="panel panel-warning">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Push system users' %}
</div>
<div class="panel-body">
<table class="table group_edit" id="add-asset2systemuser">
<tbody>
<form>
<tr class="no-borders-tr">
<td colspan="2">
<select data-placeholder="{% trans 'Select system users' %}" class="select2 system-user" style="width: 100%" multiple="" tabindex="4">
{% for system_user in system_users_all %}
<option value="{{ system_user.id }}" id="opt_{{ system_user.id }}">{{ system_user.name }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-warning btn-sm btn-system-user">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
{% for system_user in system_users %}
<tr>
<td ><b class="bdg_group" data-sid={{ system_user.id }}>{{ system_user.name }}</b></td>
<td>
<button class="btn btn-danger btn-xs pull-right btn_leave_system" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
jumpserver.groups_selected = {};
jumpserver.system_user_selected = {};
function updateAssetGroups(groups) {
var the_url = "{% url 'api-assets:asset-update-group' pk=asset.id %}";
var body = {
groups: Object.assign([], groups)
};
var success = function(data) {
// remove all the selected groups from select > option and rendered ul element;
$('.select2-selection__rendered').empty();
$('#groups_selected').val('');
$.map(jumpserver.groups_selected, function(group_name, index) {
$('#opt_' + index).remove();
// change tr html of user groups.
$('#add-asset2group tbody').append(
'<tr>' +
'<td><b class="bdg_group" data-gid="' + index + '">' + group_name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
// clear jumpserver.groups_selected
jumpserver.groups_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
function updateAssetSystemUser(system_users) {
var the_url = "{% url 'api-assets:asset-update-system-users' pk=asset.id %}";
var body = {
system_users: Object.assign([], system_users)
};
var success = function(data) {
$('.select2-selection__rendered').empty();
$('#groups_selected').val('');
$.map(jumpserver.system_user_selected, function(name, index) {
$('#opt_' + index).remove();
$('#add-asset2systemuser tbody').append(
'<tr>' +
'<td><b class="bdg_group" data-sid="' + index + '">' + name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_system" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
// clear jumpserver.groups_selected
jumpserver.system_user_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
function refreshAssetHardware() {
var the_url = "{% url 'api-assets:asset-refresh' pk=asset.id %}";
var success = function (data) {
location.reload();
};
APIUpdateAttr({
url: the_url,
success: success,
method: 'GET'
})
}
$(document).ready(function () {
$('.select2.groups').select2().on('select2:select', function(evt) {
var data = evt.params.data;
jumpserver.groups_selected[data.id] = data.text;
}).on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.groups_selected[data.id]
});
$('.select2.system-user').select2().on('select2:select', function(evt) {
var data = evt.params.data;
jumpserver.system_user_selected[data.id] = data.text;
}).on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.system_user_selected[data.id]
})
}).on('click', '#is_active', function () {
var the_url = '{% url "api-assets:asset-detail" pk=asset.id %}';
var checked = $(this).prop('checked');
var body = {
'is_active': checked
};
var success = '{% trans "Update successfully!" %}';
var status = $(".ibox-content > table > tbody > tr:nth-child(13) > td:last >b").text();
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success_message: success
});
if (status == "False") {
$(".ibox-content > table > tbody > tr:nth-child(13) > td:last >b").html('True');
}else{
$(".ibox-content > table > tbody > tr:nth-child(13) > td:last >b").html('False');
}
}).on('click', '#btn_add_user_group', function () {
if (Object.keys(jumpserver.groups_selected).length === 0) {
return false;
}
var groups = $('.bdg_group').map(function() {
return $(this).data('gid');
}).get();
$.map(jumpserver.groups_selected, function(value, index) {
groups.push(parseInt(index));
$('#opt_' + index).remove();
});
updateAssetGroups(groups)
}).on('click', '.btn_leave_group', function() {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_group');
var gid = $badge.data('gid');
var group_name = $badge.html() || $badge.text();
$('#groups_selected').append(
'<option value="' + gid + '" id="opt_' + gid + '">' + group_name + '</option>'
);
$tr.remove();
var groups = $('.bdg_group').map(function () {
return $(this).data('gid');
}).get();
updateAssetGroups(groups)
}).on('click', '.btn-system-user', function () {
if (Object.keys(jumpserver.system_user_selected).length === 0) {
return false;
}
var system_users = $('.bdg_group').map(function() {
return $(this).data('sid');
}).get();
$.map(jumpserver.system_user_selected, function(value, index) {
system_users.push(parseInt(index));
$('#opt_' + index).remove();
});
updateAssetSystemUser(system_users)
}).on('click', '.btn_leave_system', function () {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_group');
var sid = $badge.data('sid');
var name = $badge.html() || $badge.text();
$('#groups_selected').append(
'<option value="' + sid + '" id="opt_' + sid + '">' + name + '</option>'
);
$tr.remove();
var system_users = $('.bdg_group').map(function () {
return $(this).data('sid');
}).get();
updateAssetSystemUser(system_users)
}).on('click', '.btn-delete-asset', function () {
var $this = $(this);
var name = "{{ asset.hostname }}";
var uid = "{{ asset.id }}";
var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid);
var redirect_url = "{% url 'assets:asset-list' %}";
objectDelete($this, name, the_url, redirect_url);
}).on('click', '#btn_refresh_asset', function () {
alert('请等待几秒, 等待完成');
refreshAssetHardware()
}).on('click', '#btn_test_admin_user', function () {
$.ajax({
url: '{% url "api-assets:asset-admin-user-test" pk=asset.id %}'
}).done(function (data, textStatue, jqXHR) {
toastr.success('Success')
}).fail(function (data, textStaue, errorThrown) {
toastr.error('Error')
})
})
</script>
{% endblock %}

View File

@@ -0,0 +1,121 @@
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-10">
<div class="ibox float-e-margins">
<div id="ibox-content" class="ibox-title">
<h5> {{ action }}</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="panel blank-panel">
<div class="panel-body">
<div class="tab-content">
<div id="tab-1" class="ibox float-e-margins tab-pane active"></div>
<form id="groupForm" method="post" class="form-horizontal">
{% csrf_token %}
<h3 class="widget-head-color-box">资产组信息</h3>
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3 class="widget-head-color-box">用户选择的资产</h3>
<div class="form-group">
<label class="col-sm-2 control-label" id="asset_on_count">已选({{ assets_count }}</label>
<div class="col-sm-9" id="asset_sed">
<div class="form-asset-on" id="add_asset">
<p id="asset_on_p">
{% for asset in assets_on_list %}
<button name='asset_hostname' title='{{ asset.ip }}' type='button' class='btn btn-default btn-xs'>{{ asset.hostname }}</button>
{% endfor %}
</p>
</div>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-5">
<button class="btn btn-white" type="reset"> 重置 </button>
<button class="btn btn-primary" type="submit"> 提交 </button>
<div id='box2'> </div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 模态框Modal -->
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content" id="box">
<!--此部分为主体内容,将远程加载进来-->
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script type="text/javascript">
$(document).ready(function () {
$('.select2').select2();
$('.select2-system-user').select2();
});
$('#add_asset').on('click',function(){
$('#modal').modal('show');
});
$('#modal').modal({
show: false,
backdrop: 'static',
keyboard: 'false',
remote:"{% url 'assets:asset-modal-list' %}?group_id={{ group_id }}"
});
$('#modal').on('show.bs.modal',function(){
//alert('当调用show方法时立即触发')
});
$('#modal').on('shown.bs.modal',function(){
//alert('当弹窗完全加载完后,再触发;')
});
$('#modal').on('hide.bs.modal',function(){
//alert('当关闭时,立即触发;')
});
$('#modal').on('hidden.bs.modal',function(){
//alert('当关完全关闭后,再触发;')
});
$('#modal').on('loaded.bs.modal',function(){
//alert('当远程数据加载完毕后,再触发;')
});
</script>
{% endblock %}

View File

@@ -0,0 +1,271 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active"><a href="" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a></li>
<li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'assets:asset-group-update' pk=asset_group.id %}"><i class="fa fa-edit"></i>Update</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left"></span>{% trans 'Asset list of ' %} <b>{{ asset_group.name }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover " id="asset_list_table" >
<thead>
<tr>
<th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th>
<th>{% trans 'Type' %}</th>
<th>{% trans 'Alive' %}</th>
<th>{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Push system users' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<form>
<tr class="no-borders-tr">
<td colspan="2">
<select data-placeholder="{% trans 'Select system users' %}" class="select2 system-user-select" style="width: 100%" multiple="" tabindex="4">
{% for system_user in system_users %}
<option value="{{ system_user.id }}"> {{ system_user.name }} </option>
{% endfor %}
</select>
</td>
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-primary btn-sm btn-push-system-user">{% trans 'Push' %}</button>
</td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{# </div>#}
{% endblock %}
{% block custom_foot_js %}
<script>
jumpserver.assets_selected = {};
function updateGroupAssets(assets) {
var the_url = "{}";
var body = {
assets: Object.assign([], assets)
};
var $data_table = $("#asset_list_table").DataTable();
var success = function(data) {
$('.select2-selection__rendered').empty();
$.map(jumpserver.assets_selected, function(asset_ip, index) {
$('#opt_' + index).remove();
$data_table.ajax.reload();
});
jumpserver.groups_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PUT',
success: success
});
}
function leaveGroup(obj, name, url, data) {
function doDelete() {
var body = data;
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
function pushSystemUser(sysUserID) {
var the_url = "{% url 'api-assets:asset-group-push-system-user' pk=asset_group.id %}";
var body = {
system_user: sysUserID
};
var success = function(data) {
var url = "{% url 'ops:task-detail' pk=234234234 %}".replace("234234234", data);
setTimeout(function () {
location.href = url
}, 1000);
};
APIUpdateAttr({
url: the_url,
method: 'PATCH',
body: JSON.stringify(body),
success: success
});
}
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
Array.prototype.unique = function(){
var res = [];
var json = {};
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){
res.push(this[i]);
json[this[i]] = 1;
}
}
return res;
};
$(document).ready(function () {
$('.select2').select2();
$('.select2.asset-select').select2()
.on('select2:select', function(evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
console.log(jumpserver.assets_selected)
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id]
});
var options = {
ele: $('#asset_list_table'),
buttons: [],
order: [],
columnDefs: [
{targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 4, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 5, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Remove" %}</a>'.replace('99991937', rowData.id);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}?asset_group_id={{ asset_group.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "type" }, {data: "is_active" }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', ".btn-asset-group-add-asset", function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
updateGroupAssets(jumpserver.assets_selected);
})
.on('click', '.btn-push-system-user', function () {
var data = $('.system-user-select').select2();
var system_id = data.val()[0];
if (!system_id) {
return false
}
pushSystemUser(system_id)
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var assets = [];
$('#asset_list_table > tbody > tr').map(function () {
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
});
var delete_asset_id = $(this).data('aid');
assets.remove(delete_asset_id);
var data = {"assets": assets};
leaveGroup($this, name, the_url, data);
})
</script>
{% endblock %}

View File

@@ -0,0 +1,183 @@
{% extends '_base_list.html' %}
{% load i18n static %}
{% block table_search %}
{% endblock %}
{% block table_container %}
<div class="uc pull-left m-l-5 m-r-5">
<a href="{% url "assets:asset-group-create" %}" class="btn btn-sm btn-primary"> {% trans "Create asset group" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="asset_groups_list_table" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" class="ipt_check_all" >
</th>
<th class="text-center">{% trans 'Name' %}</th>
<th class="text-center">{% trans 'Asset' %}</th>
<th class="text-center">{% trans 'Comment' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% include 'assets/_asset_group_bulk_update_modal.html' %}
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function(){
var options = {
ele: $('#asset_groups_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-group-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData) {
var innerHtml = cellData.length > 30 ? cellData.substring(0, 30) + '...': cellData;
$(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-group-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_group_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn)
}}],
ajax_url: '{% url "api-assets:asset-group-list" %}',
columns: [{data: "id"}, {data: "name" }, {data: "assets_amount" }, {data: "comment" }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn_asset_group_delete', function () {
var $this = $(this);
var $data_table = $('#asset_groups_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#asset_groups_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = '{% url "api-assets:asset-group-list" %}';
console.log(plain_id_list);
console.log(the_url);
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected groups !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Group deleted' %}";
swal("{% trans 'Group Delete' %}", msg, "success");
$('#asset_groups_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Group deleting failed.' %}";
swal("{% trans 'Group Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_group_bulk_update_modal').modal('show');
}
switch(action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
})
.on('click', '#btn_asset_group_bulk_update', function () {
var json_data = $("#fm_asset_group_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.assets != undefined) {
body.assets = json_data.assets;
}
if (typeof body.assets === 'string') {
body.assets = [parseInt(body.assets)]
} else if(typeof body.assets === 'array') {
var new_assets = body.assets.map(Number);
body.assets = new_assets;
}
if (json_data.system_users != undefined) {
body.system_users = json_data.system_users;
}
if (typeof body.system_users === 'string') {
body.system_users = [parseInt(body.system_users)];
} else if (typeof body.system_users === 'array') {
var new_system_users = body.system_users.map(Number);
body.system_users = new_system_users;
}
var post_list = [];
var $data_table = $('#asset_groups_list_table').DataTable()
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = '{% url "api-assets:asset-group-list" %}';
var success = function() {
var msg = "{% trans 'The selected asset groups has been updated successfully.' %}";
swal("{% trans 'AssetGroup Updated' %}", msg, "success");
$('#asset_groups_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
{# console.log(JSON.stringify(post_list));#}
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
$('#asset_group_bulk_update_modal').modal('hide');
});
</script>
{% endblock %}

View File

@@ -0,0 +1,319 @@
{% extends '_base_list.html' %}
{% load i18n %}
{% load static %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
{#<style>#}
{# .custom{#}
{# margin-right:5px;#}
{# }#}
{# #modal .modal-body { max-height: 200px; }#}
{#</style>#}
{% endblock %}
{% block content_left_head %}{% endblock %}
{% block table_search %}
<div class="html5buttons">
<div class="dt-buttons btn-group">
<a class="btn btn-default btn_import" data-toggle="modal" data-target="#asset_import_modal" tabindex="0">
<span>{% trans "Import" %}</span>
</a>
<a class="btn btn-default btn_export" tabindex="0">
<span>{% trans "Export" %}</span>
</a>
</div>
</div>
{% endblock %}
{% block table_container %}
<div class="uc pull-left m-l-5 m-r-5"><a href="{% url "assets:asset-create" %}" class="btn btn-sm btn-primary"> {% trans "Create asset" %} </a></div>
<table class="table table-striped table-bordered table-hover " id="asset_list_table" >
<thead>
<tr>
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
<th class="text-center">{% trans 'Hostname' %}</th>
<th class="text-center">{% trans 'IP' %}</th>
<th class="text-center">{% trans 'Port' %}</th>
<th class="text-center">{% trans 'Type' %}</th>
<th class="text-center">{% trans 'Env' %}</th>
<th class="text-center">{% trans 'Hardware' %}</th>
<th class="text-center">{% trans 'Valid' %}</th>
<th class="text-center">{% trans 'Alive' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option>
<option value="deactive">{% trans 'Deactive selected' %}</option>
<option value="active">{% trans 'Active' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% include 'assets/_asset_import_modal.html' %}
{#{% include 'assets/_asset_bulk_update_modal.html' %}#}
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<script type="text/javascript">
window.onload = function (){
var tag_on = document.getElementsByName("tag_on");
var oDiv = document.getElementById("ydxbd");
if(tag_on.length > 0){
oDiv.style.display = "block";
}
};
function tagShow() {
var oDiv = document.getElementById("ydxbd");
if (oDiv.style.display == 'none'){
oDiv.style.display = "block";
}else{
oDiv.style.display = "none";
}
} //onload;
$(document).ready(function(){
var options = {
ele: $('#asset_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 7, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 8, createdCell: function (td, cellData) {
if (cellData == 'Unknown'){
$(td).html('<i class="fa fa-circle text-warning"></i>')
} else if (!cellData) {
$(td).html('<i class="fa fa-circle text-danger"></i>')
} else {
$(td).html('<i class="fa fa-circle text-navy"></i>')
}
}},
{targets: 9, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}',
columns: [{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "get_type_display" }, {data: "get_env_display"}, {data: "hardware"},
{data: "is_active" }, {data: "is_online"}, {data: "id" }],
op_html: $('#actions').html()
};
var table = jumpserver.initDataTable(options);
$('.btn_export').click(function () {
var assets = [];
var rows = table.rows('.selected').data();
$.each(rows, function (index, obj) {
assets.push(obj.id)
});
console.log(assets);
$.ajax({
url: "{% url "assets:asset-export" %}",
method: 'POST',
data: JSON.stringify({assets_id: assets}),
dataType: "json",
success: function (data, textStatus) {
window.open(data.redirect)
},
error: function () {
toastr.error('Export failed');
}
})
});
$('#btn_asset_import').click(function() {
var $form = $('#fm_asset_import');
$form.find('.help-block').remove();
function success (data) {
if (data.valid === false) {
$('<span />', {class: 'help-block text-danger'}).html(data.msg).insertAfter($('#id_assets'));
} else {
$('#id_created').html(data.created_info);
$('#id_created_detail').html(data.created.join(', '));
$('#id_updated').html(data.updated_info);
$('#id_updated_detail').html(data.updated.join(', '));
$('#id_failed').html(data.failed_info);
$('#id_failed_detail').html(data.failed.join(', '));
var $data_table = $('#asset_list_table').DataTable();
$data_table.ajax.reload();
}
}
$form.ajaxSubmit({success: success});
})
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var $data_table = $("#asset_list_table").DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid);
console.log(the_url);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#asset_list_table').DataTable();
var id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push(this.data().id);
});
if (id_list.length == 0) {
return false;
}
var the_url = "{% url 'api-assets:asset-list' %}";
function doDeactive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = false;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doActive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = true;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected assets !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Asset Deleted.' %}";
swal("{% trans 'Asset Delete' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
var id_list_string = id_list.join(',');
var url = "{% url 'assets:asset-bulk-update' %}?assets_id=" + id_list_string;
location.href = url
}
switch(action) {
case 'deactive':
doDeactive();
break;
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
case 'active':
doActive();
break;
default:
break;
}
});
{##}
{#.on('click', '#btn_asset_bulk_update', function () {#}
{# var json_data = $("#fm_asset_bulk_update").serializeObject();#}
{# var body = {};#}
{# body.enable_otp = (json_data.enable_otp === 'on')? true: false;#}
{# if (json_data.type != '') {#}
{# body.type = json_data.type;#}
{# }#}
{# if (json_data.groups != undefined) {#}
{# body.groups = json_data.groups;#}
{# }#}
{# if (typeof body.groups === 'string') {#}
{# body.groups = [parseInt(body.groups)]#}
{# } else if(typeof body.groups === 'array') {#}
{# var new_groups = body.groups.map(Number);#}
{# body.groups = new_groups;#}
{# }#}
{##}
{# if (json_data.system_users != undefined) {#}
{# body.system_users = json_data.system_users;#}
{# }#}
{# if (typeof body.system_users === 'string') {#}
{# body.system_users = [parseInt(body.system_users)]#}
{# } else if(typeof body.system_users === 'array') {#}
{# var new_users = body.system_users.map(Number);#}
{# body.system_users = new_users;#}
{# }#}
{##}
{# if (json_data.tags != undefined) {#}
{# body.tags = json_data.tags;#}
{# }#}
{# if (typeof body.tags == 'string') {#}
{# body.tags = [parseInt(body.tags)];#}
{# } else if (typeof body.tags === 'array') {#}
{# var new_tags = body.tags.map(Number);#}
{# body.tags = new_tags;#}
{# }#}
{##}
{# var $data_table = $('#asset_list_table').DataTable();#}
{# var post_list = [];#}
{# $data_table.rows({selected: true}).every(function(){#}
{# var content = Object.assign({id: this.data().id}, body);#}
{# post_list.push(content);#}
{# });#}
{# if (post_list === []) {#}
{# return false#}
{# }#}
{# var the_url = "{% url 'api-assets:asset-list' %}";#}
{# var success = function() {#}
{# var msg = "{% trans 'The selected assets has been updated successfully.' %}";#}
{# swal("{% trans 'Asset Updated' %}", msg, "success");#}
{# $('#asset_list_table').DataTable().ajax.reload();#}
{# jumpserver.checked = false;#}
{# };#}
{# console.log(JSON.stringify(post_list));#}
{# console.log(the_url);#}
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
{# $('#asset_bulk_update_modal').modal('hide');#}
{#})#}
</script>
{% endblock %}

View File

@@ -0,0 +1,127 @@
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">分配/回收资产</h4>
</div>
<div class="modal-body" style="padding-bottom: 0px;">
<table aria-describedby="editable_info" role="grid" class="table table-striped table-bordered table-hover dataTable" id="editable">
<thead>
<tr>
<th class="text-center" style="background-color:white">
<input type="checkbox" id="check_all" onclick="checkAll()">
</th>
<th id="th_no">id</th>
<th>资产名称</th>
<th>IP</th>
<th>类型</th>
</tr>
</thead>
<tbody>
{% for asset in assets %}
{% if asset.id in all_assets %}
<tr name="oAssets" class="odd selected text-center">
<td class="text-center" ><input type="checkbox" name="checked" value="{{ asset.id }}" checked="checked"></td>
{% else %}
<tr name="oAssets">
<td class="text-center"><input type="checkbox" name="checked" value="{{ asset.id }}" ></td>
{% endif %}
<td class="text-center">{{ asset.id }}</td>
<td class="text-center">{{ asset.hostname }}</td>
<td class="text-center">{{ asset.ip }}</td>
<td class="text-center">{{ asset.env }}-{{ asset.type }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" id="close-btn">取消</button>
<button type="button" class="btn btn-primary" id="save-btn">保存</button>
</div>
<script type="text/javascript">
$(document).ready(function(){
var table = $('#editable').DataTable({
"aLengthMenu": [[10, 25, 50, -1], ["10", "25", "50", "all"]],
"iDisplayLength":25,
"aaSorting": [[2, "asc"]],
"aoColumnDefs": [ { "bSortable": false, "aTargets": [ 0 ] }],
"bAutoWidth": false,
"language": {
"url": "/static/js/plugins/dataTables/i18n/zh-hans.json"
},
columns: [
{data: "checkbox"},
{data: "id"},
{data: "hostname"},
{data: "ip"},
{data: "type"}
]
});
//将ID列隐藏
table.column('1').visible(false);
$('#editable tbody').on( 'click', 'tr', function () {
//alert($(this).hasClass('selected'));
if($(this).hasClass('selected')){
$(this).removeClass('selected');
this.children[0].children[0].checked=0;
}else{
$(this).addClass('selected');
this.children[0].children[0].checked=1;
}
});
$('#close-btn').on('click',function(){
$('#modal').modal('hide');
});
var size_name = document.getElementById('asset_on_count').innerText;
$('#save-btn').on('click',function(){
//alert( table.rows('.selected').data().length +' row(s) selected' );
var d = table.rows('.selected').data();
var size = d.length;
var re = /\d+/;
document.getElementById('add_asset').value = size;
var str= size_name;
var re=/\d+/g;
document.getElementById('asset_on_count').innerText = str.replace(re, size);
var column2 = table.rows('.selected').data();
$("#asset_sed").find("input[name='assets']").remove();
$("#asset_sed").find("button[name='asset_hostname']").remove();
for(var i=0;i<column2.length;i++){
column2[i].checkbox='<input name="checked" value="1" checked="" type="checkbox">';
var value = column2[i].id;
var ip = column2[i].ip;
var hostname = column2[i].hostname;
$("#asset_sed").append("<input type='hidden' name='assets' value='"+value+"'>");
$("#asset_on_p").append("<button name='asset_hostname' title='"+ip+"' type='button' class='btn btn-default btn-xs ss'>"+hostname+"</button> ");
}
$('#modal').modal('hide');
});
}); //$(document).ready
var bCheck = 1;
function checkAll(){
if(bCheck){
$("tr[name='oAssets']").each(function(){
oCheckbox = this.children[0].children[0];
$(this).toggleClass('selected',true);
oCheckbox.checked=1;
});
document.getElementById('check_all').checked=1;
bCheck = 0;
}else{
$("tr[name='oAssets']").each(function(){
oCheckbox = this.children[0].children[0];
$(this).toggleClass('selected',false);
oCheckbox.checked=0;
});
document.getElementById('check_all').checked=0;
bCheck = 1;
}
}
</script>

View File

@@ -0,0 +1,73 @@
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% block custom_head_css_js_create %}
<link href="{% static "css/plugins/inputTags.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/inputTags.jquery.min.js" %}"></script>
{% endblock %}
{% block form %}
<form action="" method="post" class="form-horizontal">
{% if form.no_field_errors %}
<div class="alert alert-danger">
{{ form.non_field_errors }}
</div>
{% endif %}
{% csrf_token %}
<h3>{% trans 'Basic' %}</h3>
{% bootstrap_field form.hostname layout="horizontal" %}
{% bootstrap_field form.ip layout="horizontal" %}
{% bootstrap_field form.public_ip layout="horizontal" %}
{% bootstrap_field form.port layout="horizontal" %}
{% bootstrap_field form.type layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Group' %}</h3>
{% bootstrap_field form.idc layout="horizontal" %}
{% bootstrap_field form.groups layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Asset user' %}</h3>
{% bootstrap_field form.admin_user layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Configuration' %}</h3>
{% bootstrap_field form.number layout="horizontal" %}
{% bootstrap_field form.remote_card_ip layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Location' %}</h3>
{% bootstrap_field form.cabinet_no layout="horizontal" %}
{% bootstrap_field form.cabinet_pos layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Other' %}</h3>
{% bootstrap_field form.status layout="horizontal" %}
{% bootstrap_field form.env layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
{% bootstrap_field form.is_active layout="horizontal" %}
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
$('.select2').select2();
$("#tags").select2({
tags: true,
maximumSelectionLength: 8 //最多能够选择的个数
});
})
</script>
{% endblock %}

View File

@@ -0,0 +1,15 @@
{% load i18n %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% trans 'Confirm delete' %}</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<p>{% trans 'Are you sure delete' %} <b>{{ object.name }} </b> ?</p>
<input type="submit" value="Confirm" />
</form>
</body>
</html>

View File

@@ -0,0 +1,364 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
<style type="text/css">
</style>
{% 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 'assets:idc-detail' pk=idc.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li class="active"><a href="{% url 'assets:idc-assets' pk=idc.id %}" class="text-center">
<i class="fa fa-bar-chart-o"></i> {% trans 'IDC assets' %}</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left">{% trans 'IDC assets' %} <b>{{ idc.name }} </b><span class="badge"></span></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table table-striped table-bordered table-hover " id="idc_assets_table" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" class="ipt_check_all" >
</th>
<th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th>
<th>{% trans 'Type' %}</th>
<th>{% trans 'Valid' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Remove selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-warning">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Add assets to' %} {{ idc.name }}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<form>
<tr class="no-borders-tr">
<td colspan="2">
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for asset in assets_remain %}
<option value="{{ asset.id }}" id="opt_{{ asset.id }}">{{ asset.ip}}:{{ asset.port }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-primary btn-sm btn-asset-attach">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<script>
jumpserver.assets_selected = {};
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
function updateIDCAssets(assets) {
var the_url = "{% url 'api-assets:idc-update-assets' pk=idc.id %}";
var body = {
assets: Object.assign([], assets)
};
var $data_table = $("#idc_assets_table").DataTable();
var success = function(data) {
$('.select2-selection__rendered').empty();
$.map(jumpserver.assets_selected, function(asset_ip, index) {
$('#opt_' + index).remove();
$data_table.ajax.reload();
});
jumpserver.groups_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PUT',
success: success
});
}
function deleteIDCAssets(assets) {
var the_url = "{% url 'api-assets:idc-update-assets' pk=idc.id %}";
var body = {
assets: Object.assign([], assets)
};
var $data_table = $("#idc_assets_table").DataTable();
var success = function(data) {
$data_table.ajax.reload();
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PUT',
success: success
});
}
$(document).ready(function () {
$('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
});
var options = {
ele: $('#idc_assets_table'),
buttons: [],
order: [],
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 5, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}}],
ajax_url: '{% url "api-assets:asset-list" %}?idc_id={{ idc.id }}',
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "type" }, {data: "is_active" }],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn-asset-attach', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
var assets=[];
var $data_table = $("#idc_assets_table").DataTable();
$.ajax({
url: '{% url "api-assets:asset-list" %}',
method: 'GET',
data: {"idc_id": {{ idc.id }}},
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
updateIDCAssets(assets);
}
});
})
.on('click', '#btn_bulk_update', function () {
var action = $("#slct_bulk_update").val();
var $data_table = $("#idc_assets_table").DataTable();
var id_list = [];
var plain_id_list = [];
var assets = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
$.ajax({
url: '{% url "api-assets:asset-list" %}',
data: {"idc_id": {{ idc.id }}},
dataType: 'json',
method: 'GET',
success: function (result) {
for (var i in result) {
if (!isNaN(result[i]['id'])) {
assets.push(result[i]['id']);
}
}
for (var j in plain_id_list) {
assets.remove(plain_id_list[j])
}
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected assets !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Asset Deleted.' %}";
swal("{% trans 'Asset Delete' %}", msg, "success");
$('#idc_assets_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error");
};
var url_delete = "{% url 'api-assets:idc-update-assets' pk=idc.id %}";
var body = {
assets: Object.assign([], assets)
};
APIUpdateAttr({url: url_delete, body: JSON.stringify(body), method: 'PUT', success: success, error: fail});
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_bulk_update_modal').modal('show');
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
}
});
})
.on('click', '#btn_asset_bulk_update', function () {
var json_data = $("#fm_asset_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.groups != undefined) {
body.groups = json_data.groups;
}
if (typeof body.groups === 'string') {
body.groups = [parseInt(body.groups)]
} else if(typeof body.groups === 'array') {
var new_groups = body.groups.map(Number);
body.groups = new_groups;
}
if (json_data.users != undefined) {
body.users = json_data.users;
}
if (typeof body.users === 'string') {
body.users = [parseInt(body.users)]
} else if(typeof body.users === 'array') {
var new_users = body.users.map(Number);
body.users = new_users;
}
if (json_data.tags != undefined) {
body.tags = json_data.tags;
}
if (typeof body.tags == 'string') {
body.tags = [parseInt(body.tags)];
} else if (typeof body.tags === 'array') {
var new_tags = body.tags.map(Number);
body.tags = new_tags;
}
var $data_table = $('#asset_list_table').DataTable();
var post_list = [];
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = "{% url 'api-assets:asset-list' %}";
var success = function() {
var msg = "{% trans 'The selected assets has been updated successfully.' %}";
swal("{% trans 'Asset Updated' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
$('#asset_bulk_update_modal').modal('hide');
});
</script>
{% endblock %}

View File

@@ -0,0 +1,73 @@
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-10">
<div class="ibox float-e-margins">
<div id="ibox-content" class="ibox-title">
<h5> {{ action }}</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="panel blank-panel">
<div class="panel-body">
<div class="tab-content">
<div id="tab-1" class="ibox float-e-margins tab-pane active"></div>
<form id="IDCForm" method="post" class="form-horizontal">
{% csrf_token %}
<h3 class="widget-head-color-box">基本信息</h3>
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.address layout="horizontal" %}
{% bootstrap_field form.contact layout="horizontal" %}
{% bootstrap_field form.phone layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3 class="widget-head-color-box">IP段</h3>
{% bootstrap_field form.operator layout="horizontal" %}
{% bootstrap_field form.intranet layout="horizontal" %}
{% bootstrap_field form.extranet layout="horizontal" %}
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-default" type="reset"> {% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
$('.select2').select2();
})
</script>
{% endblock %}

View File

@@ -0,0 +1,156 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active">
<a href="{% url 'assets:idc-detail' pk=idc.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li>
<a href="{% url 'assets:idc-assets' pk=idc.id %}" class="text-center">
<i class="fa fa-bar-chart-o"></i> {% trans 'IDC assets' %}
</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'assets:idc-update' pk=idc.id %}"><i class="fa fa-edit"></i>Update</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-danger btn-delete-idc">
<i class="fa fa-edit"></i>Delete
</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label"><b>{{ idc.name }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="20%">{% trans 'Name' %}:</td>
<td><b>{{ idc.name }}</b></td>
</tr>
<tr>
<td>{% trans 'Bandwidth' %}:</td>
<td><b>{{ idc.bandwidth }}</b></td>
</tr>
<tr>
<td>{% trans 'Contact' %}:</td>
<td><b>{{ idc.contact }}</b></td>
</tr>
<tr>
<td>{% trans 'Phone' %}:</td>
<td><b>{{ idc.phone }}</b></td>
</tr>
<tr>
<td>{% trans 'Address' %}:</td>
<td><b>{{ idc.address }}</b></td>
</tr>
<tr>
<td>{% trans 'Intranet' %}:</td>
<td><b>{{ idc.Intranet }}</b></td>
</tr>
<tr>
<td>{% trans 'Extranet' %}:</td>
<td><b>{{ idc.extranet }}</b></td>
</tr>
<tr>
<td>{% trans 'Operator' %}:</td>
<td><b>{{ idc.operator }}</b></td>
</tr>
<tr>
<td>{% trans 'Date created' %}:</td>
<td><b>{{ system_user.date_created }}</b></td>
</tr>
<tr>
<td>{% trans 'Created by' %}:</td>
<td><b>{{ asset_group.created_by }}</b></td>
</tr>
<tr>
<td>{% trans 'Comment' %}:</td>
<td><b>{{ system_user.comment }}</b></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
function idcDelete(name, url) {
function doDelete() {
var body = {};
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
window.location.href="{% url 'assets:idc-list' %}";
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'DELETE',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
$(document).ready(function () {
$('.select2').select2();
})
.on('click', '.btn-delete-idc', function () {
var name = $('.idc-details > tbody > tr').attr("data-name");
var id = {{ idc.id }};
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace(99991937, id);
idcDelete(name, the_url);
});
</script>
{% endblock %}

View File

@@ -0,0 +1,129 @@
{% extends '_base_list.html' %}
{% load i18n static %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
{% endblock %}
{% block table_search %}{% endblock %}
{% block table_container %}
<div class="uc pull-left m-l-5 m-r-5">
<a href="{% url "assets:idc-create" %}" class="btn btn-sm btn-primary"> {% trans "Create IDC" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="idc_list_table" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" class="ipt_check_all" >
</th>
<th class="text-center"><a href="{% url 'assets:idc-list' %}?sort=name">{% trans 'Name' %}</a></th>
<th class="text-center">{% trans 'Asset num' %}</th>
<th class="text-center">{% trans 'Contact' %}</th>
<th class="text-center">{% trans 'Phone' %}</th>
<th class="text-center">{% trans 'Operator' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function(){
var options = {
ele: $('#idc_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:idc-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 6, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:idc-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_idc_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn)
}}],
ajax_url: '{% url "api-assets:idc-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets_amount" }, {data: "contact" }, {data: "phone" },
{data: "operator" }, {data: "id" }],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn_idc_delete', function () {
var $this = $(this);
var $data_table = $('#idc_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#idc_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = "{% url 'api-assets:idc-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected idc' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'IDC Deleted.' %}";
swal("{% trans 'IDC Delete' %}", msg, "success");
$('#idc_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'IDC Deleting failed.' %}";
swal("{% trans 'IDC Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
switch (action) {
case 'delete':
doDelete();
break;
default:
break;
}
});
</script>
{% endblock %}

View File

@@ -0,0 +1,371 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li>
<a href="{% url 'assets:system-user-detail' pk=system_user.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li class="active"><a href="{% url 'assets:system-user-asset' pk=system_user.id %}" class="text-center">
<i class="fa fa-bar-chart-o"></i> {% trans 'Attached assets' %}</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left">{% trans 'Assets of ' %} <b>{{ system_user.name }} </b><span class="badge">{{ paginator.count }}</span></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover" id="system_user_list">
<thead>
<tr>
<th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th>
<th>{% trans 'Reachable' %}</th>
<th>{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
{% for asset in page_obj %}
<tr>
<td>{{ asset.hostname }}</td>
<td>{{ asset.ip }}</td>
<td>{{ asset.port }}</td>
<td>
<i class="fa fa-check text-navy"></i>
</td>
<td>
<button class="btn btn-danger pull-right btn-xs {% if asset.is_inherit_from_asset_groups %} disabled {% endif %}" type="button"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{# <div class="row">#}
{# {% include '_pagination.html' %}#}
{# </div>#}
</div>
</div>
</div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Attach to assets ' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<form>
<tr class="no-borders-tr">
<td colspan="2">
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for asset in assets_remain %}
<option value="{{ asset.id }}">{{ asset.ip}}:{{ asset.port }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-primary btn-sm btn-add-asset2system-user">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Attach to asset groups' %}
</div>
<div class="panel-body">
<table class="table group_edit">
<tbody>
<form>
<tr>
<td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Add asset group' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for asset_group in asset_groups_remain %}
<option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td colspan="2" class="no-borders">
<button type="button" class="btn btn-info btn-sm" id="btn_add_user_group">{% trans 'Attach AssetGroup' %}</button>
</td>
</tr>
</form>
{% for asset_group in asset_groups %}
<tr>
<td ><b class="bdg_asset_groups" data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td>
<td>
<button class="btn btn-danger pull-right btn-xs btn-leave-system_user" type="button"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
jumpserver.assets_selected = {};
jumpserver.asset_groups_selected = {};
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
Array.prototype.unique = function(){
var res = [];
var json = {};
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){
res.push(this[i]);
json[this[i]] = 1;
}
}
return res;
};
function objectDelete(obj, name, url, data) {
function doDelete() {
var body = data;
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
function updateSystemUserAssetGroup(asset_groups) {
var the_url = "{% url 'api-assets:systemuser-update-assetgroups' pk=system_user.id %}";
var body = {
asset_groups: Object.assign([], asset_groups)
};
var success = function(data) {
$('.select2-selection__rendered').empty();
$('#groups_selected').val('');
$.map(jumpserver.asset_groups_selected, function(asset_groups, index) {
$('#opt_' + index).remove();
$('.system-user-table tbody').append(
'<tr>' +
'<td><b class="bdg_asset_groups" data-sid="' + index + '">' + asset_groups + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn-leave-system_user" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
jumpserver.assets_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
$(document).ready(function () {
$('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
jumpserver.asset_groups_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
delete jumpserver.asset_groups_selected[data.id];
});
var options = {
ele: $('#system_user_list'),
buttons: [],
order: [],
columnDefs: [
{targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Delete" %}</a>'.replace('99991937', rowData.id);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}?system_user_id={{ system_user.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" }, {data: function () { return ""; } }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn-add-asset2system-user', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
var $data_table = $("#system_user_list").DataTable();
var assets = [];
$.ajax({
url: '{% url "api-assets:asset-list" %}?system_user_id={{ system_user.id }}',
method: 'GET',
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
assets.unique();
var the_url = "{% url 'api-assets:systemuser-update-assets' pk=system_user.id %}";
var body = {"assets": assets};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PATCH'
});
$data_table.ajax.reload();
}
});
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:systemuser-update-assets' pk=system_user.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var $data_table = $("#system_user_list").DataTable();
var assets = [];
$('#system_user_list > tbody > tr').map(function () {
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
});
var delete_asset_id = $(this).data('aid');
assets.remove(delete_asset_id);
assets.unique();
var data = {"assets": assets};
objectDelete($this, name, the_url, data);
$data_table.ajax.reload();
})
.on('click', '#btn_add_user_group', function () {
jumpserver.assets_selected = {};
if (Object.keys(jumpserver.asset_groups_selected).length === 0) {
return false;
}
asset_groups = [];
$.ajax({
url: '{% url "api-assets:systemuser-update-assetgroups" pk=system_user.id %}',
method: 'GET',
dataType: 'json',
success: function (result) {
for (var i in result['asset_groups']) {
if (!isNaN(result['asset_groups'][i])) {
asset_groups.push(parseInt(result['asset_groups'][i]));
}
}
$.map(jumpserver.asset_groups_selected, function(value, index) {
asset_groups.push(parseInt(index));
});
asset_groups.unique();
console.log(asset_groups);
var the_url = '{% url "api-assets:systemuser-update-assetgroups" pk=system_user.id %}';
var body = {"asset_groups": asset_groups};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PATCH'
});
{# TODO: reload the table #}
{# window.location.href="{% url 'assets:system-user-asset' pk=system_user.id %}"#}
}
});
})
.on('click', '.btn-leave-system_user', function () {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_asset_groups');
var sid = $badge.data('gid');
var name = $badge.html() || $badge.text();
$('system-user-table').append(
'<option value="' + sid + '" id="opt_' + sid + '">' + name + '</option>'
);
$tr.remove();
var asset_groups = $('.bdg_asset_groups').map(function () {
return $(this).data('gid');
}).get();
updateSystemUserAssetGroup(asset_groups);
});
</script>
{% endblock %}

View File

@@ -0,0 +1,7 @@
{% extends 'assets/_system_user.html' %}
{% load i18n %}
{% load static %}
{% block auth %}
{{ block.super }}
{% endblock %}

View File

@@ -0,0 +1,178 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href='{% static "css/plugins/select2/select2.min.css" %}' rel="stylesheet">
<script src='{% static "js/plugins/select2/select2.full.min.js" %}'></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active">
<a href="{% url 'assets:system-user-detail' pk=system_user.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li>
<a href="{% url 'assets:system-user-asset' pk=system_user.id %}" class="text-center">
<i class="fa fa-bar-chart-o"></i> {% trans 'Attached assets' %}
</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'assets:system-user-update' pk=system_user.id %}"><i class="fa fa-edit"></i>Update</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label"><b>{{ system_user.name }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td>{% trans 'Name' %}:</td>
<td><b>{{ system_user.name }}</b></td>
</tr>
<tr>
<td>{% trans 'Username' %}:</td>
<td><b>{{ system_user.username }}</b></td>
</tr>
<tr>
<td>{% trans 'Protocol' %}:</td>
<td><b>{{ system_user.protocol }}</b></td>
</tr>
<tr>
<td>{% trans 'Auto push' %}:</td>
<td><b>{{ system_user.auto_push|yesno:"Yes,No,Unknown" }}</b></td>
</tr>
<tr>
<td>{% trans 'Sudo' %}:</td>
<td><b>{{ system_user.sudo }}</b></td>
</tr>
{% if system_user.shell %}
<tr>
<td>{% trans 'Shell' %}:</td>
<td><b>{{ system_user.shell }}</b></td>
</tr>
{% endif %}
{% if system_user.home %}
<tr>
<td>{% trans 'Home' %}:</td>
<td><b>{{ system_user.home }}</b></td>
</tr>
{% endif %}
{% if system_user.uid %}
<tr>
<td>{% trans 'Uid' %}:</td>
<td><b>{{ system_user.uid }}</b></td>
</tr>
{% endif %}
<tr>
<td>{% trans 'Date created' %}:</td>
<td><b>{{ system_user.date_created }}</b></td>
</tr>
<tr>
<td>{% trans 'Created by' %}:</td>
<td><b>{{ asset_group.created_by }}</b></td>
</tr>
<tr>
<td>{% trans 'Comment' %}:</td>
<td><b>{{ system_user.comment }}</b></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Quick update' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="50%">{% trans 'Get manual install script' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs" style="width: 54px">{% trans 'Get' %}</button>
</span>
</td>
</tr>
<tr>
<td width="50%">{% trans 'Retest asset connectivity' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs" style="width: 54px">{% trans 'Start' %}</button>
</span>
</td>
</tr>
<tr>
<td width="50%">{% trans 'Reset private key' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs" style="width: 54px">{% trans 'Reset' %}</button>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
{# function switch_user_status(obj) {#}
{# var status = $(obj).prop('checked');#}
{##}
{# $.ajax({#}
{# url: "{% url 'users:user-active-api' pk=user.id %}",#}
{# type: "PUT",#}
{# data: {#}
{# 'is_active': status#}
{# },#}
{# success: function (data, status) {#}
{# console.log(data)#}
{# },#}
{# error: function () {#}
{# console.log('error')#}
{# }#}
{# })#}
{# }#}
$(document).ready(function () {
$('.select2').select2();
});
</script>
{% endblock %}

View File

@@ -0,0 +1,138 @@
{% extends '_base_list.html' %}
{% load i18n %}
{% block table_search %}
{% endblock %}
{% block table_container %}
<div class="uc pull-left m-l-5 m-r-5">
<a href="{% url 'assets:system-user-create' %}" class="btn btn-sm btn-primary "> {% trans "Create system user" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="system_user_list_table" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" class="ipt_check_all" >
</th>
<th class="text-center">{% trans 'Name' %}</th>
<th class="text-center">{% trans 'Username' %}</th>
<th class="text-center">{% trans 'Asset' %}</th>
<th class="text-center">{% trans 'Unreachable' %}</th>
<th class="text-center">{% trans 'Comment' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function(){
var options = {
ele: $('#system_user_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:system-user-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 5, createdCell: function (td, cellData) {
var innerHtml = cellData.length > 30 ? cellData.substring(0, 30) + '...': cellData;
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
}},
{targets: 6, createdCell: function (td, cellData, rowData) {
{# var script_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs btn-primary">{% trans "Script" %}</a>'.replace('99991937', cellData);#}
var update_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn)
}}],
ajax_url: '{% url "api-assets:system-user-list" %}',
columns: [{data: "id" }, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () { return "3"}},
{data: "comment" }, {data: "id" }],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn_admin_user_delete', function () {
var $this = $(this);
var $data_table = $('#idc_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:system-user-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#system_user_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = "{% url 'api-assets:system-user-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected System Users !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'System Users Deleted.' %}";
swal("{% trans 'System Users Delete' %}", msg, "success");
$('#system_user_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'System Users Deleting failed.' %}";
swal("{% trans 'System Users Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
{# TODO: bulk update the System Users #}
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
})
</script>
{% endblock %}

View File

@@ -0,0 +1,53 @@
{% extends 'assets/_system_user.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% block auth %}
<div class="password-auth hidden">
{% bootstrap_field form.password layout="horizontal" %}
</div>
<div class="public-key-auth">
<div>
{% bootstrap_field form.private_key_file layout="horizontal" %}
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
var auth_method = '#'+'{{ form.auth_method.id_for_label }}';
var auto_generate_key = '#'+'{{ form.auto_generate_key.id_for_label }}';
function authMethodDisplay() {
if ($(auth_method).val() == 'P') {
$('.password-auth').removeClass('hidden');
$('.public-key-auth').addClass('hidden');
$('#'+'{{ form.password.id_for_label }}').removeAttr('disabled');
} else if ($(auth_method).val() == 'K') {
$('.password-auth').addClass('hidden');
$('.public-key-auth').removeClass('hidden');
$('#'+'{{ form.password.id_for_label }}').removeAttr('required');
$('#'+'{{ form.password.id_for_label }}').attr('disabled', 'disabled');
if ($(auto_generate_key).prop('checked')){
$('#'+'{{ form.private_key_file.id_for_label }}').closest('.form-group').addClass('hidden');
} else {
$('#'+'{{ form.private_key_file.id_for_label }}').closest('.form-group').removeClass('hidden');
}
}
}
$(document).ready(function () {
$('.select2').select2();
authMethodDisplay();
$(auth_method).change(function () {
authMethodDisplay();
});
$(auto_generate_key).change(function () {
authMethodDisplay();
});
})
</script>
{% endblock %}

View File

@@ -0,0 +1,264 @@
{% extends '_base_list.html' %}
{% load i18n %}
{% load static %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
<style>
.custom{
margin-right:5px;
}
#modal .modal-body { max-height: 200px; }
</style>
{% endblock %}
{% block content_left_head %}{% endblock %}
{% block table_search %}
{# <div class="html5buttons">#}
{# <div class="dt-buttons btn-group">#}
{# <a class="btn btn-default btn_export" tabindex="0">#}
{# <span>{% trans "Export" %}</span>#}
{# </a>#}
{# </div>#}
{# </div>#}
{% endblock %}
{% block table_container %}
<table class="table table-striped table-bordered table-hover " id="asset_list_table" >
<thead>
<tr>
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
<th class="text-center">{% trans 'Hostname' %}</th>
<th class="text-center">{% trans 'IP' %}</th>
<th class="text-center">{% trans 'Port' %}</th>
<th class="text-center">{% trans 'Type' %}</th>
<th class="text-center">{% trans 'Env' %}</th>
<th class="text-center">{% trans 'Hardware' %}</th>
<th class="text-center">{% trans 'Valid' %}</th>
<th class="text-center">{% trans 'Alive' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<script type="text/javascript">
$(document).ready(function(){
var options = {
ele: $('#asset_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 7, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 8, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-circle text-danger"></i>')
} else {
$(td).html('<i class="fa fa-circle text-navy"></i>')
}
}}
],
ajax_url: '{% url "api-assets:asset-list" %}',
columns: [{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "get_type_display" }, {data: "get_env_display"}, {data: "hardware"},
{data: "is_active" }, {data: "is_active"}],
};
var table = jumpserver.initDataTable(options);
$('.btn_export').click(function () {
var assets = [];
var rows = table.rows('.selected').data();
$.each(rows, function (index, obj) {
assets.push(obj.id)
});
console.log(assets);
$.ajax({
url: "{% url "assets:asset-export" %}",
method: 'POST',
data: JSON.stringify({assets_id: assets}),
dataType: "json",
success: function (data, textStatus) {
window.open(data.redirect)
},
error: function () {
toastr.error('Export failed');
}
})
});
$('#btn_asset_import').click(function() {
var $form = $('#fm_asset_import');
$form.find('.help-block').remove();
function success (data) {
if (data.valid === false) {
$('<span />', {class: 'help-block text-danger'}).html(data.msg).insertAfter($('#id_assets'));
} else {
$('#id_created').html(data.created_info);
$('#id_created_detail').html(data.created.join(', '));
$('#id_updated').html(data.updated_info);
$('#id_updated_detail').html(data.updated.join(', '));
$('#id_failed').html(data.failed_info);
$('#id_failed_detail').html(data.failed.join(', '));
var $data_table = $('#asset_list_table').DataTable();
$data_table.ajax.reload();
}
}
$form.ajaxSubmit({success: success});
})
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#asset_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (plain_id_list.length == 0) {
return false;
}
var the_url = "{% url 'api-assets:asset-list' %}";
function doDeactive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = false;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doActive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = true;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected assets !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Asset Deleted.' %}";
swal("{% trans 'Asset Delete' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_bulk_update_modal').modal('show');
}
switch(action) {
case 'deactive':
doDeactive();
break;
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
case 'active':
doActive();
break;
default:
break;
}
})
.on('click', '#btn_asset_bulk_update', function () {
var json_data = $("#fm_asset_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.groups != undefined) {
body.groups = json_data.groups;
}
if (typeof body.groups === 'string') {
body.groups = [parseInt(body.groups)]
} else if(typeof body.groups === 'array') {
var new_groups = body.groups.map(Number);
body.groups = new_groups;
}
if (json_data.system_users != undefined) {
body.system_users = json_data.system_users;
}
if (typeof body.system_users === 'string') {
body.system_users = [parseInt(body.system_users)]
} else if(typeof body.system_users === 'array') {
var new_users = body.system_users.map(Number);
body.system_users = new_users;
}
if (json_data.tags != undefined) {
body.tags = json_data.tags;
}
if (typeof body.tags == 'string') {
body.tags = [parseInt(body.tags)];
} else if (typeof body.tags === 'array') {
var new_tags = body.tags.map(Number);
body.tags = new_tags;
}
var $data_table = $('#asset_list_table').DataTable();
var post_list = [];
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = "{% url 'api-assets:asset-list' %}";
var success = function() {
var msg = "{% trans 'The selected assets has been updated successfully.' %}";
swal("{% trans 'Asset Updated' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
console.log(JSON.stringify(post_list));
console.log(the_url);
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
$('#asset_bulk_update_modal').modal('hide');
});
</script>
{% endblock %}

View File

@@ -0,0 +1,6 @@
from django import template
from django.utils import timezone
from django.conf import settings
register = template.Library()

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,57 @@
# coding:utf-8
from django.conf.urls import url
from .. import api
from rest_framework import routers
from rest_framework_bulk.routes import BulkRouter
app_name = 'assets'
router = BulkRouter()
router.register(r'v1/groups', api.AssetGroupViewSet, 'asset-group')
router.register(r'v1/assets', api.AssetViewSet, 'asset')
router.register(r'v1/idc', api.IDCViewSet, 'idc')
router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user')
router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user')
urlpatterns = [
url(r'^v1/assets-bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'),
url(r'^v1/system-user/(?P<pk>[0-9]+)/auth-info/', api.SystemUserAuthInfoApi.as_view(),
name='system-user-auth-info'),
url(r'^v1/assets/(?P<pk>\d+)/groups/$',
api.AssetUpdateGroupApi.as_view(), name='asset-update-group'),
url(r'^v1/assets/(?P<pk>\d+)/refresh/$',
api.AssetRefreshHardwareView.as_view(), name='asset-refresh'),
url(r'^v1/assets/(?P<pk>\d+)/admin-user-test/$',
api.AssetAdminUserTestView.as_view(), name='asset-admin-user-test'),
url(r'^v1/assets/(?P<pk>\d+)/system-users/$',
api.SystemUserUpdateApi.as_view(), name='asset-update-system-users'),
url(r'^v1/groups/(?P<pk>\d+)/push-system-user/$',
api.AssetGroupPushSystemUserView.as_view(), name='asset-group-push-system-user'),
# update the system users, which add and delete the asset to the system user
url(r'^v1/system-user/(?P<pk>\d+)/assets/$',
api.SystemUserUpdateAssetsApi.as_view(), name='systemuser-update-assets'),
url(r'^v1/system-user/(?P<pk>\d+)/groups/$',
api.SystemUserUpdateAssetGroupApi.as_view(), name='systemuser-update-assetgroups'),
# update the asset group, which add or delete the asset to the group
url(r'^v1/groups/(?P<pk>\d+)/assets/$',
api.AssetGroupUpdateApi.as_view(), name='asset-groups-update'),
# update the asset group, and add or delete the system_user to the group
url(r'^v1/groups/(?P<pk>\d+)/system-users/$',
api.AssetGroupUpdateSystemUserApi.as_view(), name='asset-groups-update-systemusers'),
# update the IDC, and add or delete the assets to the IDC
url(r'^v1/idc/(?P<pk>\d+)/assets/$',
api.IDCUpdateAssetsApi.as_view(), name='idc-update-assets'),
]
urlpatterns += router.urls

View File

@@ -0,0 +1,56 @@
# coding:utf-8
from django.conf.urls import url
from .. import views
app_name = 'assets'
urlpatterns = [
# Resource asset url
url(r'^$', views.AssetListView.as_view(), name='asset-index'),
url(r'^asset/$', views.AssetListView.as_view(), name='asset-list'),
url(r'^asset/create/$', views.AssetCreateView.as_view(), name='asset-create'),
url(r'^asset/export/$', views.AssetExportView.as_view(), name='asset-export'),
url(r'^asset/import/$', views.BulkImportAssetView.as_view(), name='asset-import'),
url(r'^asset/(?P<pk>[0-9]+)/$', views.AssetDetailView.as_view(), name='asset-detail'),
url(r'^asset/(?P<pk>[0-9]+)/update/$', views.AssetUpdateView.as_view(), name='asset-update'),
url(r'^asset/(?P<pk>[0-9]+)/delete/$', views.AssetDeleteView.as_view(), name='asset-delete'),
url(r'^asset-modal$', views.AssetModalListView.as_view(), name='asset-modal-list'),
url(r'^asset/update/$', views.AssetBulkUpdateView.as_view(), name='asset-bulk-update'),
# User asset view
url(r'^user-asset/$', views.UserAssetListView.as_view(), name='user-asset-list'),
# Resource asset group url
url(r'^asset-group/$', views.AssetGroupListView.as_view(), name='asset-group-list'),
url(r'^asset-group/create/$', views.AssetGroupCreateView.as_view(), name='asset-group-create'),
url(r'^asset-group/(?P<pk>[0-9]+)/$', views.AssetGroupDetailView.as_view(), name='asset-group-detail'),
url(r'^asset-group/(?P<pk>[0-9]+)/update/$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'),
url(r'^asset-group/(?P<pk>[0-9]+)/delete/$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'),
# Resource idc url
url(r'^idc/$', views.IDCListView.as_view(), name='idc-list'),
url(r'^idc/create/$', views.IDCCreateView.as_view(), name='idc-create'),
url(r'^idc/(?P<pk>[0-9]+)/$', views.IDCDetailView.as_view(), name='idc-detail'),
url(r'^idc/(?P<pk>[0-9]+)/update/', views.IDCUpdateView.as_view(), name='idc-update'),
url(r'^idc/(?P<pk>[0-9]+)/delete/$', views.IDCDeleteView.as_view(), name='idc-delete'),
url(r'^idc/(?P<pk>[0-9]+)/assets/$', views.IDCAssetsView.as_view(), name='idc-assets'),
# Resource admin user url
url(r'^admin-user/$', views.AdminUserListView.as_view(), name='admin-user-list'),
url(r'^admin-user/create/$', views.AdminUserCreateView.as_view(), name='admin-user-create'),
url(r'^admin-user/(?P<pk>[0-9]+)/$', views.AdminUserDetailView.as_view(), name='admin-user-detail'),
url(r'^admin-user/(?P<pk>[0-9]+)/update/$', views.AdminUserUpdateView.as_view(), name='admin-user-update'),
url(r'^admin-user/(?P<pk>[0-9]+)/delete/$', views.AdminUserDeleteView.as_view(), name='admin-user-delete'),
# Resource system user url
url(r'^system-user/$', views.SystemUserListView.as_view(), name='system-user-list'),
url(r'^system-user/create/$', views.SystemUserCreateView.as_view(), name='system-user-create'),
url(r'^system-user/(?P<pk>[0-9]+)/$', views.SystemUserDetailView.as_view(), name='system-user-detail'),
url(r'^system-user/(?P<pk>[0-9]+)/update/$', views.SystemUserUpdateView.as_view(), name='system-user-update'),
url(r'^system-user/(?P<pk>[0-9]+)/delete/$', views.SystemUserDeleteView.as_view(), name='system-user-delete'),
url(r'^system-user/(?P<pk>[0-9]+)/asset/$', views.SystemUserAssetView.as_view(), name='system-user-asset'),
# url(r'^system-user/(?P<pk>[0-9]+)/asset-group$', views.SystemUserAssetGroupView.as_view(),
# name='system-user-asset-group'),
]

17
apps/assets/utils.py Normal file
View File

@@ -0,0 +1,17 @@
# ~*~ coding: utf-8 ~*~
#
from ops.utils import run_AdHoc
def test_admin_user_connective_manual(asset):
if not isinstance(asset, list):
asset = [asset]
task_tuple = (
('ping', ''),
)
summary, _ = run_AdHoc(task_tuple, asset, record=False)
if len(summary['failed']) != 0:
return False
else:
return True

View File

@@ -0,0 +1,7 @@
# coding:utf-8
from .asset import *
from .group import *
from .idc import *
from .system_user import *
from .admin_user import *

View File

@@ -0,0 +1,112 @@
# coding:utf-8
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.conf import settings
from django.views.generic import TemplateView, ListView, View
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, IDC, SystemUser
from ..hands import AdminUserRequiredMixin
__all__ = ['AdminUserCreateView', 'AdminUserDetailView',
'AdminUserDeleteView', 'AdminUserListView',
'AdminUserUpdateView',
]
class AdminUserListView(AdminUserRequiredMixin, TemplateView):
model = AdminUser
template_name = 'assets/admin_user_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Admin user list'),
}
kwargs.update(context)
return super(AdminUserListView, self).get_context_data(**kwargs)
class AdminUserCreateView(AdminUserRequiredMixin,
SuccessMessageMixin,
CreateView):
model = AdminUser
form_class = forms.AdminUserForm
template_name = 'assets/admin_user_create_update.html'
success_url = reverse_lazy('assets:admin-user-list')
def get_context_data(self, **kwargs):
context = {
'app': 'assets',
'action': 'Create admin user'
}
kwargs.update(context)
return super(AdminUserCreateView, self).get_context_data(**kwargs)
def get_success_message(self, cleaned_data):
success_message = _(
'Create admin user <a href="{url}">{name}</a> successfully.'.format(
url=reverse_lazy('assets:admin-user-detail',
kwargs={'pk': self.object.pk}),
name=self.object.name,
))
return success_message
def form_invalid(self, form):
return super(AdminUserCreateView, self).form_invalid(form)
class AdminUserUpdateView(AdminUserRequiredMixin, UpdateView):
model = AdminUser
form_class = forms.AdminUserForm
template_name = 'assets/admin_user_create_update.html'
def get_context_data(self, **kwargs):
context = {
'app': 'assets',
'action': 'Update admin user'
}
kwargs.update(context)
return super(AdminUserUpdateView, self).get_context_data(**kwargs)
def get_success_url(self):
success_url = reverse_lazy('assets:admin-user-detail',
kwargs={'pk': self.object.pk})
return success_url
class AdminUserDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
template_name = 'assets/admin_user_detail.html'
context_object_name = 'admin_user'
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=AdminUser.objects.all())
return super(AdminUserDetailView, self).get(request, *args, **kwargs)
def get_queryset(self):
return self.object.assets.all()
def get_context_data(self, **kwargs):
asset_groups = AssetGroup.objects.all()
assets = self.get_queryset()
context = {
'app': 'assets',
'action': 'Admin user detail',
'assets_remain': [asset for asset in Asset.objects.all() if asset not in assets],
'asset_groups': asset_groups,
}
kwargs.update(context)
return super(AdminUserDetailView, self).get_context_data(**kwargs)
class AdminUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = AdminUser
template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:admin-user-list')

345
apps/assets/views/asset.py Normal file
View File

@@ -0,0 +1,345 @@
# coding:utf-8
from __future__ import absolute_import, unicode_literals
import csv
import json
import uuid
import codecs
import chardet
from io import StringIO
from collections import defaultdict
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView, ListView, View
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy
from django.views.generic.detail import DetailView, SingleObjectMixin
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator
from django.core.cache import cache
from django.utils import timezone
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import get_object_or_404, redirect, reverse
from common.mixins import JSONResponseMixin
from common.utils import get_object_or_none
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, IDC, SystemUser
from ..hands import AdminUserRequiredMixin
from ..tasks import update_assets_hardware_info
__all__ = ['AssetListView', 'AssetCreateView', 'AssetUpdateView',
'UserAssetListView', 'AssetBulkUpdateView', 'AssetDetailView',
'AssetModalListView', 'AssetDeleteView', 'AssetExportView',
'BulkImportAssetView',
]
class AssetListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/asset_list.html'
def get_context_data(self, **kwargs):
context = {
'app': 'Assets',
'action': 'Asset list',
'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
# 'form': forms.AssetBulkUpdateForm(),
}
kwargs.update(context)
return super(AssetListView, self).get_context_data(**kwargs)
class UserAssetListView(LoginRequiredMixin, TemplateView):
template_name = 'assets/user_asset_list.html'
def get_context_data(self, **kwargs):
context = {
'app': 'Assets',
'action': 'Asset list',
'system_users': SystemUser.objects.all(),
}
kwargs.update(context)
return super(UserAssetListView, self).get_context_data(**kwargs)
class AssetCreateView(AdminUserRequiredMixin, CreateView):
model = Asset
form_class = forms.AssetCreateForm
template_name = 'assets/asset_create.html'
success_url = reverse_lazy('assets:asset-list')
def form_valid(self, form):
self.asset = asset = form.save()
asset.created_by = self.request.user.username or 'Admin'
asset.date_created = timezone.now()
asset.save()
return super(AssetCreateView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = {
'app': 'Assets',
'action': 'Create asset',
}
kwargs.update(context)
return super(AssetCreateView, self).get_context_data(**kwargs)
def get_success_url(self):
update_assets_hardware_info.delay([self.asset._to_secret_json()])
return super(AssetCreateView, self).get_success_url()
class AssetModalListView(AdminUserRequiredMixin, ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
model = Asset
context_object_name = 'asset_modal_list'
template_name = 'assets/asset_modal_list.html'
def get_context_data(self, **kwargs):
assets = Asset.objects.all()
assets_id = self.request.GET.get('assets_id', '')
assets_id_list = [i for i in assets_id.split(',') if i.isdigit()]
context = {
'all_assets': assets_id_list,
'assets': assets
}
kwargs.update(context)
return super(AssetModalListView, self).get_context_data(**kwargs)
class AssetBulkUpdateView(AdminUserRequiredMixin, ListView):
model = Asset
form_class = forms.AssetBulkUpdateForm
template_name = 'assets/asset_bulk_update.html'
success_url = reverse_lazy('assets:asset-list')
def get(self, request, *args, **kwargs):
assets_id = self.request.GET.get('assets_id', '')
self.assets_id_list = [int(i) for i in assets_id.split(',') if i.isdigit()]
if kwargs.get('form'):
self.form = kwargs['form']
elif assets_id:
self.form = self.form_class(
initial={'assets': self.assets_id_list}
)
else:
self.form = self.form_class()
return super(AssetBulkUpdateView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form.save()
return redirect(self.success_url)
else:
return self.get(request, form=form, *args, **kwargs)
def get_context_data(self, **kwargs):
# assets_list = Asset.objects.filter(id__in=self.assets_id_list)
context = {
'app': 'Assets',
'action': 'Bulk update asset',
'form': self.form,
'assets_selected': self.assets_id_list,
'assets': Asset.objects.all(),
}
kwargs.update(context)
return super(AssetBulkUpdateView, self).get_context_data(**kwargs)
class AssetUpdateView(AdminUserRequiredMixin, UpdateView):
model = Asset
form_class = forms.AssetUpdateForm
template_name = 'assets/asset_update.html'
success_url = reverse_lazy('assets:asset-list')
def get_context_data(self, **kwargs):
context = {
'app': 'Assets',
'action': 'Update asset',
}
kwargs.update(context)
return super(AssetUpdateView, self).get_context_data(**kwargs)
def form_invalid(self, form):
print(form.errors)
return super(AssetUpdateView, self).form_invalid(form)
class AssetDeleteView(AdminUserRequiredMixin, DeleteView):
model = Asset
template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:asset-list')
class AssetDetailView(DetailView):
model = Asset
context_object_name = 'asset'
template_name = 'assets/asset_detail.html'
def get_context_data(self, **kwargs):
asset_groups = self.object.groups.all()
system_users = self.object.system_users.all()
context = {
'app': 'Assets',
'action': 'Asset detail',
'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all()
if asset_group not in asset_groups],
'asset_groups': asset_groups,
'system_users_all': SystemUser.objects.all(),
'system_users': system_users,
}
kwargs.update(context)
return super(AssetDetailView, self).get_context_data(**kwargs)
@method_decorator(csrf_exempt, name='dispatch')
class AssetExportView(View):
def get(self, request):
spm = request.GET.get('spm', '')
assets_id_default = [Asset.objects.first().id] if Asset.objects.first() else [1]
assets_id = cache.get(spm, assets_id_default)
fields = [
field for field in Asset._meta.fields
if field.name not in [
'date_created'
]
]
filename = 'assets-{}.csv'.format(
timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S'))
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
response.write(codecs.BOM_UTF8)
assets = Asset.objects.filter(id__in=assets_id)
writer = csv.writer(response, dialect='excel',
quoting=csv.QUOTE_MINIMAL)
header = [field.verbose_name for field in fields]
header.append(_('Asset groups'))
writer.writerow(header)
for asset in assets:
groups = ','.join([group.name for group in asset.groups.all()])
data = [getattr(asset, field.name) for field in fields]
data.append(groups)
writer.writerow(data)
return response
def post(self, request, *args, **kwargs):
try:
assets_id = json.loads(request.body).get('assets_id', [])
except ValueError:
return HttpResponse('Json object not valid', status=400)
spm = uuid.uuid4().hex
cache.set(spm, assets_id, 300)
url = reverse_lazy('assets:asset-export') + '?spm=%s' % spm
return JsonResponse({'redirect': url})
class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
form_class = forms.FileForm
def form_valid(self, form):
f = form.cleaned_data['file']
det_result = chardet.detect(f.read())
f.seek(0) # reset file seek index
file_data = f.read().decode(det_result['encoding']).strip(codecs.BOM_UTF8.decode())
csv_file = StringIO(file_data)
reader = csv.reader(csv_file)
csv_data = [row for row in reader]
fields = [
field for field in Asset._meta.fields
if field.name not in [
'date_created'
]
]
header_ = csv_data[0]
mapping_reverse = {field.verbose_name: field.name for field in fields}
mapping_reverse[_('Asset groups')] = 'groups'
attr = [mapping_reverse.get(n, None) for n in header_]
if None in attr:
data = {'valid': False,
'msg': 'Must be same format as '
'template or export file'}
return self.render_json_response(data)
created, updated, failed = [], [], []
assets = []
for row in csv_data[1:]:
if set(row) == {''}:
continue
asset_dict = dict(zip(attr, row))
id_ = asset_dict.pop('id', 0)
try:
id_ = int(id_)
except ValueError:
id_ = 0
asset = get_object_or_none(Asset, id=id_)
for k, v in asset_dict.items():
if k == 'idc':
v = get_object_or_none(IDC, name=v)
elif k == 'is_active':
v = bool(v)
elif k == 'admin_user':
v = get_object_or_none(AdminUser, name=v)
elif k in ['port', 'cabinet_pos', 'cpu_count', 'cpu_cores']:
try:
v = int(v)
except ValueError:
v = 0
elif k == 'groups':
groups_name = v.split(',')
v = AssetGroup.objects.filter(name__in=groups_name)
else:
continue
asset_dict[k] = v
if not asset:
try:
groups = asset_dict.pop('groups')
if len(Asset.objects.filter(hostname=asset_dict.get('hostname'))):
raise Exception(_('already exists'))
asset = Asset.objects.create(**asset_dict)
asset.groups.set(groups)
created.append(asset_dict['hostname'])
assets.append(asset)
except Exception as e:
failed.append('%s: %s' % (asset_dict['hostname'], str(e)))
else:
for k, v in asset_dict.items():
if k == 'groups':
asset.groups.set(v)
continue
if v:
setattr(asset, k, v)
try:
asset.save()
updated.append(asset_dict['hostname'])
except Exception as e:
failed.append('%s: %s' % (asset_dict['hostname'], str(e)))
if assets:
update_assets_hardware_info.delay([asset._to_secret_json() for asset in assets])
data = {
'created': created,
'created_info': 'Created {}'.format(len(created)),
'updated': updated,
'updated_info': 'Updated {}'.format(len(updated)),
'failed': failed,
'failed_info': 'Failed {}'.format(len(failed)),
'valid': True,
'msg': 'Created: {}. Updated: {}, Error: {}'.format(
len(created), len(updated), len(failed))
}
return self.render_json_response(data)

111
apps/assets/views/group.py Normal file
View File

@@ -0,0 +1,111 @@
# coding:utf-8
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.views.generic import TemplateView, ListView, View
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy
from django.views.generic.detail import DetailView, SingleObjectMixin
from django.shortcuts import get_object_or_404, reverse, redirect
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, IDC, SystemUser
from ..hands import AdminUserRequiredMixin
__all__ = ['AssetGroupCreateView', 'AssetGroupDetailView',
'AssetGroupUpdateView', 'AssetGroupListView',
'AssetGroupDeleteView',
]
class AssetGroupCreateView(AdminUserRequiredMixin, CreateView):
model = AssetGroup
form_class = forms.AssetGroupForm
template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list')
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create asset group'),
'assets_count': 0,
}
kwargs.update(context)
return super(AssetGroupCreateView, self).get_context_data(**kwargs)
def form_valid(self, form):
asset_group = form.save()
assets_id_list = self.request.POST.getlist('assets', [])
assets = [get_object_or_404(Asset, id=int(asset_id))
for asset_id in assets_id_list]
asset_group.created_by = self.request.user.username or 'Admin'
asset_group.assets.add(*tuple(assets))
asset_group.save()
return super(AssetGroupCreateView, self).form_valid(form)
class AssetGroupListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/asset_group_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Asset group list'),
'assets': Asset.objects.all(),
'system_users': SystemUser.objects.all(),
'keyword': self.request.GET.get('keyword', '')
}
kwargs.update(context)
return super(AssetGroupListView, self).get_context_data(**kwargs)
class AssetGroupDetailView(AdminUserRequiredMixin, DetailView):
model = AssetGroup
template_name = 'assets/asset_group_detail.html'
context_object_name = 'asset_group'
def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
system_users = SystemUser.objects.all()
system_users_remain = SystemUser.objects.exclude(id__in=system_users)
context = {
'app': _('Assets'),
'action': _('Asset group detail'),
'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all()
if asset not in assets_remain],
'system_users': system_users,
'system_users_remain': system_users_remain,
}
kwargs.update(context)
return super(AssetGroupDetailView, self).get_context_data(**kwargs)
class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView):
model = AssetGroup
form_class = forms.AssetGroupForm
template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list')
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=AssetGroup.objects.all())
return super(AssetGroupUpdateView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
assets_all = self.object.assets.all()
context = {
'app': _('Assets'),
'action': _('Create asset group'),
'assets_on_list': assets_all,
'assets_count': len(assets_all),
'group_id': self.object.id,
}
kwargs.update(context)
return super(AssetGroupUpdateView, self).get_context_data(**kwargs)
class AssetGroupDeleteView(AdminUserRequiredMixin, DeleteView):
template_name = 'assets/delete_confirm.html'
model = AssetGroup
success_url = reverse_lazy('assets:asset-group-list')

101
apps/assets/views/idc.py Normal file
View File

@@ -0,0 +1,101 @@
# coding:utf-8
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.views.generic import TemplateView, ListView, View
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy
from django.views.generic.detail import DetailView, SingleObjectMixin
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, IDC, SystemUser
from ..hands import AdminUserRequiredMixin
__all__ = ['IDCListView', 'IDCCreateView', 'IDCUpdateView',
'IDCDetailView', 'IDCDeleteView', 'IDCAssetsView']
class IDCListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/idc_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('IDC list'),
# 'keyword': self.request.GET.get('keyword', '')
}
kwargs.update(context)
return super(IDCListView, self).get_context_data(**kwargs)
class IDCCreateView(AdminUserRequiredMixin, CreateView):
model = IDC
form_class = forms.IDCForm
template_name = 'assets/idc_create_update.html'
success_url = reverse_lazy('assets:idc-list')
def get_context_data(self, **kwargs):
context = {
'app': _('assets'),
'action': _('Create IDC'),
}
kwargs.update(context)
return super(IDCCreateView, self).get_context_data(**kwargs)
def form_valid(self, form):
idc = form.save(commit=False)
idc.created_by = self.request.user.username or 'System'
idc.save()
return super(IDCCreateView, self).form_valid(form)
class IDCUpdateView(AdminUserRequiredMixin, UpdateView):
model = IDC
form_class = forms.IDCForm
template_name = 'assets/idc_create_update.html'
context_object_name = 'idc'
success_url = reverse_lazy('assets:idc-list')
def form_valid(self, form):
idc = form.save(commit=False)
idc.save()
return super(IDCUpdateView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = {
'app': _('assets'),
'action': _('Update IDC'),
}
kwargs.update(context)
return super(IDCUpdateView, self).get_context_data(**kwargs)
class IDCDetailView(AdminUserRequiredMixin, DetailView):
model = IDC
template_name = 'assets/idc_detail.html'
context_object_name = 'idc'
class IDCAssetsView(AdminUserRequiredMixin, DetailView):
model = IDC
template_name = 'assets/idc_assets.html'
context_object_name = 'idc'
def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
context = {
'app': _('Assets'),
'action': _('Asset detail'),
'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
}
kwargs.update(context)
return super(IDCAssetsView, self).get_context_data(**kwargs)
class IDCDeleteView(AdminUserRequiredMixin, DeleteView):
model = IDC
template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:idc-list')

View File

@@ -0,0 +1,147 @@
# ~*~ coding: utf-8 ~*~
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.conf import settings
from django.db import transaction
from django.views.generic import TemplateView, ListView
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin
from .. import forms
from ..models import Asset, AssetGroup, SystemUser
from ..hands import AdminUserRequiredMixin
from perms.utils import associate_system_users_and_assets
__all__ = ['SystemUserCreateView', 'SystemUserUpdateView',
'SystemUserDetailView', 'SystemUserDeleteView',
'SystemUserAssetView', 'SystemUserListView',
]
class SystemUserListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/system_user_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('System user list'),
}
kwargs.update(context)
return super(SystemUserListView, self).get_context_data(**kwargs)
class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = SystemUser
form_class = forms.SystemUserForm
template_name = 'assets/system_user_create.html'
success_url = reverse_lazy('assets:system-user-list')
@transaction.atomic
def post(self, request, *args, **kwargs):
return super(SystemUserCreateView, self).post(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create system user'),
}
kwargs.update(context)
return super(SystemUserCreateView, self).get_context_data(**kwargs)
def get_success_message(self, cleaned_data):
url = reverse_lazy('assets:system-user-detail',
kwargs={'pk': self.object.pk}),
success_message = _(
'Create system user <a href="{url}">{name}</a> '
'successfully.'.format(url=url, name=self.object.name)
)
return success_message
class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView):
model = SystemUser
form_class = forms.SystemUserUpdateForm
template_name = 'assets/system_user_update.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Update system user')
}
kwargs.update(context)
return super(SystemUserUpdateView, self).get_context_data(**kwargs)
def form_valid(self, form):
response = super(SystemUserUpdateView, self).form_valid(form)
system_user = self.object
assets = system_user.assets.all()
asset_groups = system_user.asset_groups.all()
associate_system_users_and_assets([system_user], assets, asset_groups, force=True)
return response
def get_success_url(self):
success_url = reverse_lazy('assets:system-user-detail',
kwargs={'pk': self.object.pk})
return success_url
class SystemUserDetailView(AdminUserRequiredMixin, DetailView):
template_name = 'assets/system_user_detail.html'
context_object_name = 'system_user'
model = SystemUser
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('System user detail')
}
kwargs.update(context)
return super(SystemUserDetailView, self).get_context_data(**kwargs)
class SystemUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = SystemUser
template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:system-user-list')
class SystemUserAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
template_name = 'assets/system_user_asset.html'
context_object_name = 'system_user'
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=SystemUser.objects.all())
return super(SystemUserAssetView, self).get(request, *args, **kwargs)
def get_asset_groups(self):
return self.object.asset_groups.all()
# Todo: queryset default order by connectivity, need ops support
def get_queryset(self):
return list(self.object.get_assets())
def get_context_data(self, **kwargs):
asset_groups = self.get_asset_groups()
assets = self.get_queryset()
context = {
'app': 'assets',
'action': 'System user asset',
'assets_remain': [asset for asset in Asset.objects.all() if asset not in assets],
'asset_groups': asset_groups,
'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all()
if asset_group not in asset_groups]
}
kwargs.update(context)
return super(SystemUserAssetView, self).get_context_data(**kwargs)

1
apps/audits/__init__.py Normal file
View File

@@ -0,0 +1 @@

92
apps/audits/api.py Normal file
View File

@@ -0,0 +1,92 @@
# ~*~ coding: utf-8 ~*~
#
from __future__ import absolute_import, unicode_literals
from rest_framework import generics, viewsets
from rest_framework_bulk import BulkModelViewSet
from audits.backends import command_store, record_store
from audits.backends.command.serializers import CommandLogSerializer
from audits.backends.record.serializers import RecordSerializer
from . import models, serializers
from .hands import IsSuperUserOrAppUser, IsAppUser
class ProxyLogReceiveView(generics.CreateAPIView):
queryset = models.ProxyLog.objects.all()
serializer_class = serializers.ProxyLogSerializer
permission_classes = (IsAppUser,)
def get_serializer(self, *args, **kwargs):
kwargs['data']['terminal'] = self.request.user.terminal.name
return super(ProxyLogReceiveView, self).get_serializer(*args, **kwargs)
class ProxyLogViewSet(viewsets.ModelViewSet):
"""User proxy to backend server need call this api.
params: {
"username": "",
"name": "",
"hostname": "",
"ip": "",
"terminal": "",
"login_type": "",
"system_user": "",
"was_failed": "",
"date_start": ""
}
"""
queryset = models.ProxyLog.objects.all()
serializer_class = serializers.ProxyLogSerializer
permission_classes = (IsSuperUserOrAppUser,)
class CommandLogViewSet(BulkModelViewSet):
"""接受app发送来的command log, 格式如下
{
"proxy_log_id": 23,
"user": "admin",
"asset": "localhost",
"system_user": "web",
"command_no": 1,
"command": "whoami",
"output": "d2hvbWFp", # base64.b64encode(s)
"timestamp": 1485238673.0
}
"""
queryset = command_store.all()
serializer_class = CommandLogSerializer
permission_classes = (IsSuperUserOrAppUser,)
class RecordLogViewSet(BulkModelViewSet):
"""接受app发送来的record log, 格式如下
{
"proxy_log_id": 23,
"output": "d2hvbWFp", # base64.b64encode(s)
"timestamp": 1485238673.0
}
"""
serializer_class = RecordSerializer
permission_classes = (IsSuperUserOrAppUser,)
def get_queryset(self):
filter_kwargs = {}
proxy_log_id = self.request.query_params.get('proxy_log_id')
data_from_ts = self.request.query_params.get('date_from_ts')
if proxy_log_id:
filter_kwargs['proxy_log_id'] = proxy_log_id
if data_from_ts:
filter_kwargs['date_from_ts'] = data_from_ts
if filter_kwargs:
return record_store.filter(**filter_kwargs)
else:
return record_store.all()

7
apps/audits/apps.py Normal file
View File

@@ -0,0 +1,7 @@
from __future__ import unicode_literals
from django.apps import AppConfig
class AuditsConfig(AppConfig):
name = 'audits'

View File

@@ -0,0 +1,10 @@
from importlib import import_module
from django.conf import settings
command_engine = import_module(settings.COMMAND_STORE_BACKEND)
command_store = command_engine.CommandStore()
record_engine = import_module(settings.RECORD_STORE_BACKEND)
record_store = record_engine.RecordStore()
from .command.serializers import CommandLogSerializer

View File

@@ -0,0 +1,19 @@
# coding: utf-8
import abc
class CommandBase(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def save(self, proxy_log_id, user, asset, system_user,
command_no, command, output, timestamp):
pass
@abc.abstractmethod
def filter(self, date_from_ts=None, date_to_ts=None, user='',
asset='', system_user='', command='', proxy_log_id=0):
pass

View File

@@ -0,0 +1,45 @@
# ~*~ coding: utf-8 ~*~
from .base import CommandBase
from audits.models import CommandLog
class CommandStore(CommandBase):
model = CommandLog
queryset = []
def save(self, proxy_log_id, user, asset, system_user,
command_no, command, output, timestamp):
self.model.objects.create(
proxy_log_id=proxy_log_id, user=user, asset=asset,
system_user=system_user, command_no=command_no,
command=command, output=output, timestamp=timestamp
)
def filter(self, date_from_ts=None, date_to_ts=None, user='',
asset='', system_user='', command='', proxy_log_id=0):
filter_kwargs = {}
if date_from_ts:
filter_kwargs['timestamp__gte'] = date_from_ts
if date_to_ts:
filter_kwargs['timestamp__lte'] = date_to_ts
if user:
filter_kwargs['user'] = user
if asset:
filter_kwargs['asset'] = asset
if system_user:
filter_kwargs['system_user'] = system_user
if command:
filter_kwargs['command__icontains'] = command
if proxy_log_id:
filter_kwargs['proxy_log_id'] = proxy_log_id
if filter_kwargs:
self.queryset = self.model.objects.filter(**filter_kwargs)
return self.queryset
def all(self):
"""返回所有数据"""
return self.model.objects.iterator()

View File

@@ -0,0 +1,21 @@
# ~*~ coding: utf-8 ~*~
import base64
from rest_framework import serializers
from audits.models import CommandLog
from audits.backends import command_store
class CommandLogSerializer(serializers.ModelSerializer):
"""使用这个类作为基础Command Log Serializer类, 用来序列化"""
class Meta:
model = CommandLog
fields = '__all__'
def create(self, validated_data):
try:
output = validated_data['output']
validated_data['output'] = base64.b64decode(output)
except IndexError:
pass
return command_store.save(**dict(validated_data))

View File

@@ -0,0 +1,2 @@
# ~*~ coding: utf-8 ~*~

View File

@@ -0,0 +1,14 @@
# coding: utf-8
import abc
class RecordBase(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def save(self, proxy_log_id, output, timestamp):
pass
@abc.abstractmethod
def filter(self, date_from_ts=None, proxy_log_id=None):
pass

View File

@@ -0,0 +1,31 @@
# ~*~ coding: utf-8 ~*~
from .base import RecordBase
from audits.models import RecordLog
class RecordStore(RecordBase):
model = RecordLog
queryset = []
def save(self, proxy_log_id, output, timestamp):
return self.model.objects.create(
proxy_log_id=proxy_log_id, output=output, timestamp=timestamp
)
def filter(self, date_from_ts=None, proxy_log_id=''):
filter_kwargs = {}
if date_from_ts:
filter_kwargs['timestamp__gte'] = date_from_ts
if proxy_log_id:
filter_kwargs['proxy_log_id'] = proxy_log_id
if filter_kwargs:
self.queryset = self.model.objects.filter(**filter_kwargs)
return self.queryset
def all(self):
"""返回所有数据"""
return self.model.objects.all()

View File

@@ -0,0 +1,20 @@
# ~*~ coding: utf-8 ~*~
import base64
from rest_framework import serializers
from audits.models import RecordLog
from audits.backends import record_store
class RecordSerializer(serializers.ModelSerializer):
"""使用这个类作为基础Command Log Serializer类, 用来序列化"""
class Meta:
model = RecordLog
fields = '__all__'
def create(self, validated_data):
try:
output = validated_data['output']
validated_data['output'] = base64.b64decode(output)
except IndexError:
pass
return record_store.save(**dict(validated_data))

8
apps/audits/hands.py Normal file
View File

@@ -0,0 +1,8 @@
# ~*~ coding: utf-8 ~*~
#
from users.utils import AdminUserRequiredMixin
from users.models import User
from assets.models import Asset, SystemUser
from users.permissions import IsSuperUserOrAppUser, IsAppUser
from applications.models import Terminal

0
logs/test.log → apps/audits/migrations/__init__.py Executable file → Normal file
View File

94
apps/audits/models.py Normal file
View File

@@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
from django.db import models
from django.utils.translation import ugettext_lazy as _
class LoginLog(models.Model):
LOGIN_TYPE_CHOICE = (
('W', 'Web'),
('ST', 'SSH Terminal'),
('WT', 'Web Terminal')
)
username = models.CharField(max_length=20, verbose_name=_('Username'))
name = models.CharField(max_length=20, blank=True, verbose_name=_('Name'))
login_type = models.CharField(choices=LOGIN_TYPE_CHOICE, max_length=2,
verbose_name=_('Login type'))
login_ip = models.GenericIPAddressField(verbose_name=_('Login ip'))
login_city = models.CharField(max_length=254, blank=True, null=True,
verbose_name=_('Login city'))
user_agent = models.CharField(max_length=254, blank=True, null=True,
verbose_name=_('User agent'))
date_login = models.DateTimeField(auto_now_add=True,
verbose_name=_('Date login'))
class Meta:
db_table = 'login_log'
ordering = ['-date_login', 'username']
class ProxyLog(models.Model):
LOGIN_TYPE_CHOICE = (
('ST', 'SSH Terminal'),
('WT', 'Web Terminal'),
)
user = models.CharField(max_length=32, verbose_name=_('User'))
asset = models.CharField(max_length=32, verbose_name=_('Asset'))
system_user = models.CharField(max_length=32, verbose_name=_('System user'))
login_type = models.CharField(
choices=LOGIN_TYPE_CHOICE, max_length=2, blank=True,
null=True, verbose_name=_('Login type'))
terminal = models.CharField(
max_length=32, blank=True, null=True, verbose_name=_('Terminal'))
is_failed = models.BooleanField(
default=False, verbose_name=_('Did connect failed'))
is_finished = models.BooleanField(
default=False, verbose_name=_('Is finished'))
date_start = models.DateTimeField(
auto_created=True, verbose_name=_('Date start'))
date_finished = models.DateTimeField(
null=True, verbose_name=_('Date finished'))
def __unicode__(self):
return '%s-%s-%s' % (self.user, self.asset, self.system_user)
def commands(self):
from audits.backends import command_store
return command_store.filter(proxy_log_id=self.id)
class Meta:
ordering = ['-date_start', 'user']
class CommandLog(models.Model):
proxy_log_id = models.IntegerField(db_index=True)
user = models.CharField(max_length=48, db_index=True)
asset = models.CharField(max_length=128, db_index=True)
system_user = models.CharField(max_length=48, db_index=True)
command_no = models.IntegerField()
command = models.TextField(max_length=767, blank=True)
output = models.TextField(blank=True)
timestamp = models.FloatField(db_index=True)
def __unicode__(self):
return '%s: %s' % (self.id, self.command)
class Meta:
ordering = ['command_no', 'command']
class RecordLog(models.Model):
proxy_log_id = models.IntegerField(db_index=True)
output = models.TextField(verbose_name=_('Output'))
timestamp = models.FloatField(db_index=True)
def __unicode__(self):
return 'Record: %s' % self.proxy_log_id
class Meta:
ordering = ['timestamp']

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
#
from __future__ import absolute_import, unicode_literals
from rest_framework import serializers
from common.utils import timesince
from . import models
class ProxyLogSerializer(serializers.ModelSerializer):
time = serializers.SerializerMethodField()
command_length = serializers.SerializerMethodField()
class Meta:
model = models.ProxyLog
fields = '__all__'
@staticmethod
def get_time(obj):
if not obj.is_finished:
return ''
else:
return timesince(obj.date_start, since=obj.date_finished)
@staticmethod
def get_command_length(obj):
return 2

12
apps/audits/tasks.py Normal file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env python
# ~*~ coding: utf-8 ~*~
#
from celery import shared_task
from .utils import write_login_log
@shared_task
def write_login_log_async(*args, **kwargs):
write_login_log(*args, **kwargs)

View File

@@ -0,0 +1,109 @@
{% extends '_base_list.html' %}
{% load i18n %}
{% load static %}
{% load common_tags %}
{% block content_left_head %}
<link href="{% static "css/plugins/footable/footable.core.css" %}" rel="stylesheet">
<link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet">
<style>
#search_btn {
margin-bottom: 0;
}
</style>
{% endblock %}
{% block table_search %}
<form id="search_form" method="get" action="" class="pull-right form-inline">
<div class="form-group" id="date">
<div class="input-daterange input-group" id="datepicker">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
<input type="text" class="input-sm form-control" style="width: 100px;" name="date_from" value="{{ date_from }}">
<span class="input-group-addon">to</span>
<input type="text" class="input-sm form-control" style="width: 100px;" name="date_to" value="{{ date_to }}">
</div>
</div>
<div class="input-group">
<select class="select2 form-control" name="username">
<option value="">{% trans 'User' %}</option>
{% for u in user_list %}
<option value="{{ u.username }}" {% if username == u.username %} selected {% endif %}>{{ u.username }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<select class="select2 form-control" name="ip">
<option value="">{% trans 'Asset' %}</option>
{% for a in asset_list %}
<option value="{{ a.ip }}" {% if ip == a.ip %} selected {% endif %}>{{ a.ip }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<select class="select2 form-control" name="system_user">
<option value="">{% trans 'System user' %}</option>
{% for s in system_user_list %}
<option value="{{ s.username }}" {% if s.username == system_user %} selected {% endif %}>{{ s.username }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<input type="text" class="form-control input-sm" name="command" placeholder="Command" value="{{ command }}">
</div>
<div class="input-group">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
搜索
</button>
</div>
</div>
</form>
{% endblock %}
{% block table_container %}
<table class="footable table table-stripped toggle-arrow-tiny" data-page="false">
<thead>
<tr>
<th data-toggle="true">ID</th>
<th>Command</th>
<th>Username</th>
<th>IP</th>
<th>System user</th>
<th>Proxy log</th>
<th>Datetime</th>
<th data-hide="all">Output</th>
</tr>
</thead>
<tbody>
{% for command in command_list %}
<tr>
<td>{{ command.id }}</td>
<td>{{ command.command }}</td>
<td>{{ command.user }}</td>
<td>{{ command.asset }}</td>
<td>{{ command.system_user }}</td>
<td><a href="{% url 'audits:proxy-log-detail' pk=command.proxy_log_id %}">{{ command.proxy_log_id}}</a></td>
<td>{{ command.timestamp|ts_to_date }}</td>
<td><pre style="border: none; background: none">{{ command.output|to_html|safe }}</pre></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block custom_foot_js %}
<script src="{% static "js/plugins/footable/footable.all.min.js" %}"></script>
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script>
$(document).ready(function () {
$('.footable').footable();
$('.select2').select2();
$('#date .input-daterange').datepicker({
dateFormat: 'mm/dd/yy',
keyboardNavigation: false,
forceParse: false,
autoclose: true
});
});
</script>
{% endblock %}

View File

@@ -0,0 +1,101 @@
{% extends '_base_list.html' %}
{% load i18n %}
{% load static %}
{% load common_tags %}
{% block content_left_head %}
<link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet">
<style>
#search_btn {
margin-bottom: 0;
}
</style>
{% endblock %}
{% block table_search %}
<form id="search_form" method="get" action="" class="pull-right form-inline">
<div class="form-group" id="date">
<div class="input-daterange input-group" id="datepicker">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
<input type="text" class="input-sm form-control" style="width: 100px;" name="date_from" value="{{ date_from }}">
<span class="input-group-addon">to</span>
<input type="text" class="input-sm form-control" style="width: 100px;" name="date_to" value="{{ date_to }}">
</div>
</div>
<div class="input-group">
<select class="select2 form-control" name="username">
<option value="">{% trans 'Select user' %}</option>
{% for user in user_list %}
<option value="{{ user.username }}" {% if user.username == username %} selected {% endif %}>{{ user.username }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
</div>
<div class="input-group">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
搜索
</button>
</div>
</div>
</form>
{% endblock %}
{% block table_head %}
<th class="text-center">{% trans 'ID' %}</th>
<th class="text-center">{% trans 'Username' %}</th>
<th class="text-center">{% trans 'Name' %}</th>
<th class="text-center">{% trans 'Type' %}</th>
<th class="text-center">{% trans 'UA' %}</th>
<th class="text-center">{% trans 'IP' %}</th>
<th class="text-center">{% trans 'City' %}</th>
<th class="text-center">{% trans 'Date' %}</th>
{% endblock %}
{% block table_body %}
{% for login_log in login_log_list %}
<tr class="gradeX">
<td class="text-center">
{{ login_log.id }}
{# <a href="{% url 'audits:proxy-log-detail' pk=login_log.id %}">{{ login_log.id }}</a>#}
</td>
<td class="text-center">{{ login_log.username }}</td>
<td class="text-center">{{ login_log.name }}</td>
<td class="text-center">{{ login_log.get_login_type_display }}</td>
{% if login_log.login_type == 'W' %}
<td class="text-center">
<span href="javascript:void(0);" data-toggle="tooltips" title="{{ login_log.user_agent }}">{{ login_log.user_agent | truncatechars:20 }}</span>
</td>
{% else %}
<td class="text-center">{{ login_log.terminal }}</td>
{% endif %}
<td class="text-center">{{ login_log.login_ip }}</td>
<td class="text-center">{{ login_log.login_city }}</td>
<td class="text-center">{{ login_log.date_login }}</td>
</tr>
{% endfor %}
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script>
$(document).ready(function() {
$('table').DataTable({
"searching": false,
"bInfo" : false,
"paging": false,
"order": []
});
$('#date .input-daterange').datepicker({
dateFormat: 'mm/dd/yy',
keyboardNavigation: false,
forceParse: false,
autoclose: true
});
$('.select2').select2();
})
</script>
{% endblock %}

View File

@@ -0,0 +1,58 @@
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit">
{% include '_head_css_js.html' %}
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
<link href="{% static "css/plugins/footable/footable.core.css" %}" rel="stylesheet">
<script src="{% static 'js/jquery-2.1.1.js' %}"></script>
<script src="{% static 'js/plugins/sweetalert/sweetalert.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="wrapper wrapper-content animated fadeInRight">
<div class="tab-content">
<div class="ibox-content">
<input type="text" class="form-control input-sm m-b-xs" id="filter"
placeholder="Search in table">
<table class="footable table table-stripped toggle-arrow-tiny" data-page-size="10" data-filter=#filter>
<thead>
<tr>
<th data-toggle="true">ID</th>
<th>Command</th>
<th data-hide="all">Output</th>
<th>Datetime</th>
</tr>
</thead>
<tbody class="table_body">
{% for command in object_list %}
<tr>
<td>{{ command.command_no }}</td>
<td>{{ command.command }}</td>
<td>{{ command.output_decode |safe }}</td>
<td>{{ command.datetime }}</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="5">
<ul class="pagination pull-right"></ul>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</body>
<script src="{% static "js/plugins/footable/footable.all.min.js" %}"></script>
<script>
$(document).ready(function () {
$('.footable').footable();
});
</script>
</html>

Some files were not shown because too many files have changed in this diff Show More