Compare commits

...

2243 Commits
0.2.1 ... 1.2.1

Author SHA1 Message Date
老广
53c532a6ad Merge pull request #1213 from jumpserver/dev
更新资产选择
2018-04-19 10:49:01 +08:00
ibuler
035dd16b36 [Bugfix] 修复授权详情中选择用户或资产的bug 2018-04-19 10:34:17 +08:00
ibuler
48e8785725 [Update] 修改users otp secret key 2018-04-18 12:46:25 +08:00
ibuler
b90d3306c5 [Bugfix] 去掉gateway name连接 2018-04-17 12:01:00 +08:00
ibuler
7f7d634c38 Merge remote-tracking branch 'github/master' into dev 2018-04-16 17:08:01 +08:00
老广
45b13abed3 Merge pull request #1204 from jumpserver/bugfix_user_assets
[Bugfix] 修复用户看不到我的资产的bug
2018-04-16 17:04:29 +08:00
ibuler
72cd7a3be2 [Bugfix] 修复用户看不到我的资产的bug 2018-04-16 17:01:25 +08:00
ibuler
3ccd54680e [Bugfix] 修改授权详情快速Node更改失效的bug 2018-04-14 12:18:15 +08:00
ibuler
071d14c639 [Update] 修改资产获取select 2018-04-13 21:26:10 +08:00
ibuler
823e879432 [Update] 更新节点移动交互 2018-04-13 15:48:10 +08:00
ibuler
739932b005 [Update] 更新资产导入 2018-04-12 18:50:43 +08:00
ibuler
24f144fdc3 [Bugfix] 修复导入资产时url地址问题 2018-04-12 18:17:42 +08:00
ibuler
967800391e [Update] 更新api 2018-04-12 17:31:37 +08:00
老广
3ccb6637d7 Merge pull request #1197 from jumpserver/dev
[Update] 更新迁移脚本
2018-04-12 17:03:39 +08:00
ibuler
8dfdefd428 [Update] 更新迁移脚本 2018-04-12 17:02:04 +08:00
老广
ab2c58b626 Merge pull request #1194 from jumpserver/dev
[Bugfix] 修复资产重复的bug
2018-04-12 11:08:14 +08:00
ibuler
ee4f5a8194 [Bugfix] 修复资产重复的bug 2018-04-12 11:07:40 +08:00
老广
084a76b215 Merge pull request #1193 from jumpserver/dev
更改表结构
2018-04-12 10:17:53 +08:00
ibuler
2398e9acbd 更改表截稿 2018-04-12 10:16:38 +08:00
老广
5ad8b3cc70 Merge pull request #1191 from jumpserver/dev
[Update] 更改版本号
2018-04-12 09:51:54 +08:00
ibuler
7d14e1f248 [Update] 更改版本号 2018-04-12 09:49:44 +08:00
老广
819f8f469d Merge pull request #1187 from jumpserver/dev
[Bugfix] 修复一个脚本的bug
2018-04-11 17:02:02 +08:00
ibuler
a31b7a8800 [Update] 2018-04-11 16:59:07 +08:00
老广
24bdaecab4 Merge pull request #1185 from jumpserver/dev
授权规则优化,支持细颗粒授权
2018-04-11 15:25:02 +08:00
ibuler
8b3b517bab [Update] 修改授权规则详情列表页面 2018-04-11 15:24:12 +08:00
ibuler
7fc2ef00ee [Update] 修改资产api获取的bug 2018-04-11 12:45:04 +08:00
ibuler
cbd6c3ee69 [Update] 添加迁移脚本 2018-04-11 12:23:35 +08:00
ibuler
3835adafb8 [Update] 修改bug 2018-04-11 12:13:49 +08:00
ibuler
bbaa35c773 [Update] 修改Perms 2018-04-11 11:34:15 +08:00
ibuler
0fa8287811 Merge branch 'dev' into perms 2018-04-11 10:25:18 +08:00
ibuler
78f4e5a89a [Update] 修改用户Opt 2018-04-10 21:04:56 +08:00
ibuler
3193c5549d Merge remote-tracking branch 'github/dev' into dev 2018-04-10 21:02:36 +08:00
ibuler
ed71e7d2d9 [Update] 修改用户Opt 2018-04-10 21:02:07 +08:00
ibuler
33c299566a [Update] 修复bug 2018-04-10 20:45:01 +08:00
ibuler
84634eb8c0 [Update] 修改Permr认证 2018-04-10 20:29:06 +08:00
ibuler
a4ff2181c5 [Update] 修改用户view的api 2018-04-10 09:41:06 +08:00
ibuler
fffa0def9e [Update] 修改api和view 2018-04-08 20:02:40 +08:00
ibuler
d0ede246e7 [Update] 修改授权 2018-04-08 00:16:37 +08:00
BaiJiangJie
b8b78ffeb2 Merge pull request #1162 from BaiJiangJie/dev
创建用户发送邮件
2018-04-06 15:50:50 +08:00
老广
d2d10b59ac Merge pull request #1175 from jumpserver/dev
支持sftp
2018-04-06 13:30:05 +08:00
ibuler
cb8e59edf2 [Update] 修改文案 2018-04-06 13:23:15 +08:00
ibuler
1c0d783eec [update] 添加Migrations 2018-04-06 11:36:47 +08:00
ibuler
4fa72400be Merge remote-tracking branch 'github/dev' into dev 2018-04-06 11:35:33 +08:00
ibuler
37c0062fae [Update] 添加审计模块 2018-04-06 11:27:52 +08:00
BaiJiangjie
8504c3d2fd 修复资产列表导出问题 2018-04-04 19:38:32 +08:00
老广
2d10e13057 Merge pull request #1171 from jumpserver/dev
Dev
2018-04-04 14:05:16 +08:00
ibuler
1d7ba3e204 [Bugfix] 修复小bug 2018-04-04 13:03:36 +08:00
ibuler
d966e22cf9 [Update] 修改小bug 2018-04-04 13:01:57 +08:00
ibuler
6a88fd2d60 [Update] 修改api权限 2018-04-04 08:47:02 +08:00
BaiJiangjie
b63999f385 创建用户发送邮件 2018-04-03 16:28:58 +08:00
老广
82d06351e7 Merge pull request #1158 from jumpserver/dev
bugfix for celery log path
2018-04-03 14:50:49 +08:00
ibuler
aa8bece724 Merge branch 'ansible' into dev 2018-04-03 14:49:58 +08:00
老广
241bdff7c8 Merge pull request #1156 from jumpserver/dev
Dev
2018-04-03 12:18:41 +08:00
ibuler
168335a381 [Update] 更新内容 2018-04-03 12:14:58 +08:00
ibuler
121726b731 Merge remote-tracking branch 'github/dev' into dev 2018-04-03 10:44:35 +08:00
ibuler
0b812a03c6 [Bugfix] 修复 ApiUpdateAttr的bug 2018-04-03 10:36:11 +08:00
ibuler
79ae6efafb [Bugfix] 修复没有Log path引起的bug 2018-04-02 19:14:42 +08:00
老广
d2f108eeec Merge pull request #1154 from BaiJiangJie/master
终端管理用户显示,资产导入IP字段空格,资产导入domain字段保存
2018-04-02 19:03:51 +08:00
BaiJiangJie
c48beb10af Merge pull request #1 from BaiJiangJie/dev
终端管理用户,资产列表IP字段,domain保存对象
2018-04-02 18:52:52 +08:00
老广
ea9264ec49 Merge pull request #1153 from BaiJiangJie/dev
修复导入资产列表IP字段前后有空格问题,导入资产列表时domain保存为对象
2018-04-02 18:43:33 +08:00
BaiJiangjie
5b65ed8a19 修复导入资产列表IP字段前后有空格问题,导入资产列表时doamin保存为对象 2018-04-02 18:32:24 +08:00
ibuler
951ac252fe [Merge] 更新ansible功能 2018-04-02 17:45:17 +08:00
ibuler
24c4e1df50 [Update] 资产,系统用户,管理用户等支持查看日志 2018-04-02 16:55:39 +08:00
ibuler
d247e49b70 [Update] 修改celery位置 2018-04-02 15:54:49 +08:00
ibuler
a4c843ff13 [Update] 迁移celery到ops 2018-04-02 13:19:31 +08:00
BaiJiangjie
ec6103448e 使终端管理的应用用户不显示在用户组里 2018-04-02 12:02:06 +08:00
老广
0ca14463cd Merge pull request #1147 from jumpserver/dev
支持网域功能
2018-04-02 10:59:55 +08:00
ibuler
df80e8047a [Update] 修改日志 2018-04-01 23:45:37 +08:00
ibuler
09fc2776df [Update] Support history view 2018-03-30 22:03:43 +08:00
ibuler
e4c2affb5f Merge branch 'rev' into dev 2018-03-29 15:07:49 +08:00
ibuler
6fae4d5dee [Bugfix] for some commit 2018-03-29 15:06:35 +08:00
ibuler
0c80e3e815 [rev] for api commit 2018-03-29 15:02:09 +08:00
ibuler
d32f070b5c [Update] 修改Inverntoy,增加更多属性 2018-03-28 19:37:29 +08:00
ibuler
b959f1f68b Merge branch 'bugfix_ip_lookup' into dev 2018-03-28 16:47:44 +08:00
ibuler
e1cab35db0 [Bugfix] 修改获取城市 2018-03-28 16:47:36 +08:00
ibuler
8014cc48b6 [Update] 修改settings和缩进 2018-03-28 15:47:20 +08:00
ibuler
829f57e2d7 [Bugfix] 修复小bug 2018-03-28 14:35:27 +08:00
ibuler
5f0b4a4b63 [Update] 修改一些翻译 2018-03-28 11:28:40 +08:00
ibuler
c5af4d47eb Merge branch 'some_auth_api' into dev 2018-03-27 18:37:04 +08:00
ibuler
c37bfb682a [Update] 添加设置认证api和创建用户时可以不选择组 2018-03-27 18:34:41 +08:00
ibuler
3aaea6cc31 Merge branch 'bugfix_useradd' into dev 2018-03-27 17:48:35 +08:00
ibuler
f85e5b6f75 [Bugfix] 修改添加用户的bug 2018-03-27 17:47:53 +08:00
ibuler
d598571dc1 [Update] 添加一个log 2018-03-27 16:51:27 +08:00
ibuler
e873be95d5 [Update] 导入到当前node 2018-03-26 16:16:18 +08:00
ibuler
dbaa4ab502 [Update] 修改资产导入的事务问题 2018-03-26 15:55:31 +08:00
ibuler
ac1e319cd9 [Merge] merge with vpc 2018-03-26 09:56:25 +08:00
ibuler
a39424ac09 [Update] 更新jms脚本 2018-03-25 21:48:41 +08:00
ibuler
75319b99ae [Update] 更新ap请求 2018-03-25 21:47:29 +08:00
ibuler
7f4f67aa8d [Update] 支持网域 2018-03-23 19:46:46 +08:00
ibuler
fe1862120f [Update] 删掉集群等等 2018-03-21 18:13:16 +08:00
ibuler
759760e7d9 [Update] 服务器可以生成用户密钥 2018-03-21 15:22:10 +08:00
老广
15b74da57c Merge pull request #1100 from jumpserver/dev
Dev
2018-03-21 11:59:05 +08:00
ibuler
6f29cf5ddd [Update] 修改quickstart 2018-03-21 09:26:14 +08:00
ibuler
0bba840e4d Merge branch 'pubkey' into dev 2018-03-19 16:24:59 +08:00
ibuler
2156e0f51a [Update] 修改jms 2018-03-19 16:24:50 +08:00
ibuler
2fc9c04228 [Bugfix] 修复更新系统用户后关联节点丢失的问题 2018-03-19 15:32:02 +08:00
ibuler
d8e614c54d [Update] 管理脚本 2018-03-19 11:26:51 +08:00
ibuler
2ab26e25cc [Update] 改为supervisor启动 2018-03-16 10:43:21 +08:00
ibuler
f195b309d4 [Bugfix] 全选后编辑checkbox问题 2018-03-16 10:42:53 +08:00
ibuler
5e41c5cadc [Update] 删掉没用的脚本 2018-03-15 18:14:43 +08:00
ibuler
d92d09bd80 [Update] 更新说明 2018-03-15 09:34:19 +08:00
liuzheng
227804b7ab Update step_by_step.rst 2018-03-15 07:33:56 +08:00
liuzheng
eeae989c06 Update step_by_step.rst 2018-03-15 07:30:32 +08:00
liuzheng
c67a9eb845 Update quickstart.rst 2018-03-15 07:27:30 +08:00
老广
35ed881139 Merge pull request #1070 from jumpserver/dev
[Update] 升级版本号
2018-03-14 20:03:02 +08:00
ibuler
a58db9826e [Update] 升级版本号 2018-03-14 19:57:35 +08:00
老广
5250a223c3 Merge pull request #1069 from jumpserver/dev
Dev to master
2018-03-14 19:56:04 +08:00
ibuler
15427fb743 [Update] 还原ldap配置 2018-03-14 19:37:36 +08:00
ibuler
7874a1539c [Update] 修改配置,默认先从数据库认证 2018-03-14 19:33:48 +08:00
老广
9f23520712 Merge pull request #1068 from jumpserver/dev
merge dev to master
2018-03-14 18:39:31 +08:00
ibuler
63f1ec839c [Update] merge with master 2018-03-14 18:38:54 +08:00
ibuler
7e087ad5c6 Merge remote-tracking branch 'github/dev' into dev 2018-03-14 18:36:22 +08:00
ibuler
93895b6b92 [Update] 修改一些文案说明和翻译 2018-03-14 18:14:37 +08:00
q4speed
4d7fbcc49b 修复文字过长bug 2018-03-14 18:01:37 +08:00
ibuler
3822d51888 Merge branch 'docs' into dev 2018-03-14 16:21:53 +08:00
ibuler
aa5187dc39 Merge remote-tracking branch 'github/dev' into dev 2018-03-14 16:21:35 +08:00
ibuler
e9be4f51e5 [Update] 删除资产详情中的windows等测试连接 2018-03-14 16:19:59 +08:00
ibuler
496403bde0 [Update] 修改docs 2018-03-14 16:08:27 +08:00
ibuler
4f522c1cd1 [Update] docs 2018-03-14 16:06:05 +08:00
ibuler
5c3846a886 [Update] 添加Faq 2018-03-14 15:54:27 +08:00
ibuler
42f297e6c4 [Update] 更新一些文案 2018-03-14 13:13:32 +08:00
fit2cloud-fengyi
5d88c7b779 add git install 2018-03-14 13:09:51 +08:00
ibuler
74047d19d0 Merge branch 'dev' of bitbucket.org:jumpserver/core into dev 2018-03-14 12:18:17 +08:00
ibuler
8b63961d4d [Update] 默认开启定时检测,运行失败默认log为warn 2018-03-14 12:17:48 +08:00
liuzheng712
9c2470b67c feat: update the sdk 2018-03-13 19:05:16 +08:00
liuzheng
240faee2b4 Update upgrade.rst 2018-03-13 14:53:23 +08:00
liuzheng
3d3d9b565a Update upgrade.rst 2018-03-13 14:51:22 +08:00
ibuler
2e8f5919a8 [Update] 默认关闭自动定时推送功能 2018-03-13 09:57:38 +08:00
ibuler
faf6a7b623 [Update] 删掉token api调用次数限制 2018-03-12 20:29:27 +08:00
ibuler
8e4ab9f3a9 [Update] 支持获取token的用户 2018-03-12 19:39:27 +08:00
ibuler
e4823a21e3 [Update] 优化部分代码 2018-03-12 18:29:06 +08:00
ibuler
634af19945 Merge branch 'dev' of bitbucket.org:jumpserver/core into dev 2018-03-12 18:24:14 +08:00
liuzheng712
b2ae0e8f44 fix: download update 2018-03-12 17:53:22 +08:00
ibuler
4a3e5e9b22 Merge branch 'dev' of bitbucket.org:jumpserver/core into dev 2018-03-12 16:44:10 +08:00
ibuler
43b4b7c55e [Feature] 资产节点增加批量测试可连接性和更新硬件信息 2018-03-12 11:41:12 +08:00
fit2cloud-fengyi
b19a0e1cdf 删除faq和久的intro 2018-03-12 10:33:55 +08:00
liuzheng
b92ccdd05e fix: update the jms-storage==0.0.11 2018-03-12 10:30:49 +08:00
fit2cloud-fengyi
34cc6abec5 Merge remote-tracking branch 'origin/docs' into docs 2018-03-12 10:28:54 +08:00
ibuler
f59f03adfd [Update] 支持使用环境变量关闭定时任务 2018-03-12 10:20:23 +08:00
老广
0f2b0b146d Update README.md 2018-03-12 09:17:34 +08:00
老广
e085fee101 Update README.md 2018-03-12 09:16:54 +08:00
ibuler
fe03011177 [Update] 不允许添加应用程序类型的用户 2018-03-11 19:46:40 +08:00
ibuler
9ffb079c8f [Update] 增加修改system user auth 的api 2018-03-09 12:53:08 +08:00
ibuler
050b6e6d88 [Update] 修改一些docs 2018-03-09 12:12:10 +08:00
fit2cloud-fengyi
422990a992 添加 venv 到 ignore 文件 2018-03-09 10:33:57 +08:00
老广
06ff7f75ce Merge pull request #1061 from toryzen/master
Update step_by_step.rst
2018-03-09 10:07:38 +08:00
toryzen
0b82b97c66 Update step_by_step.rst
删除多余的3.2章节
2018-03-09 10:04:59 +08:00
ibuler
fcbe94de37 [Update] 更新持久化 2018-03-08 12:28:45 +08:00
老广
ce35a8e2ac Merge pull request #1059 from jumpserver/dev
Dev
2018-03-08 12:11:50 +08:00
老广
bebd71895c Merge pull request #1058 from jumpserver/docs
Docs
2018-03-08 12:11:04 +08:00
ibuler
ea18727bdb Merge remote-tracking branch 'github/docs' into docs 2018-03-08 12:08:45 +08:00
fit2cloud-fengyi
b90c5d1e43 英文格式 2018-03-08 12:00:14 +08:00
liuzheng
0be31a8078 Merge pull request #1056 from jumpserver/dev
revert: add the old apps/users/migrations/0002_auto_20171225_1157.py
2018-03-08 09:18:25 +08:00
liuzheng712
9162f4a226 revert: add the old apps/users/migrations/0002_auto_20171225_1157.py 2018-03-08 09:13:40 +08:00
老广
3bf7d061c9 Merge pull request #1055 from jumpserver/dev
Dev
2018-03-07 23:31:31 +08:00
ibuler
51e15b583f Merge remote-tracking branch 'origin/dev' into dev 2018-03-07 23:29:17 +08:00
ibuler
60427b9908 [Update] README.md 2018-03-07 23:28:30 +08:00
老广
60bc42f630 Dev (#1054)
* [Update] 修改 success message, 添加资产组时可以添加资产

* [Update] system user form add label

* [Update] set default cluster

* [Update] 修改一些翻译

* [Bugfix] 修复重置密码bug

* [Bugfix] 默认default cluster

* [Bugfix] 用户添加报错

* 修改tab样式

* [Bugfix] 修复了一些显示上的bug

* 修复全选按钮在搜索后仍然选择全部的问题

* [Bugfix] 修复以下bug
1. 查看执行历史异常
2. 用户授权资产页显示message

* [Update] api 返回platform, 并增加web terminal nav

* [Feature] 添加setting页面

* [Feature] 添加basic settings

* [Update] 修改翻译

* [Update] 修改config

* [Update] 启动加载common setting

* [Bugfix] 修复cluster创建的bug

* [Bugfix] 修复title显示Jumpserver

* [Bugfix] setting tables not found

* [Bugfix] settings add option

* [Feature] 添加后端paging

* [Bugfix] 资产列表选择别的页会报错

* [Update] check all 只选择当前页面

* [Bugfix] user login ip

* [Bugfix] for login ip

* [Bugfix] 修复资产列表显示bug

* [Remove] labels

* [Bugfix] task运行失败,因为tasks没有设置

* [Feature] 增加标签

* [Bugfix] 读取不到prefix

* For storage

* [Change] 修改部分翻译

* [Update] 启用ldap移动位置

* [Update] 修改翻译

* [Feature] 支持es存储命令

* Update README.md

* [Feature] 添加es支持

* [update] 修改用户创建时 姓名和用户名的位置

* [Update] 修改install.md

* [Update] remote default PAGE_SIZE stting

* [Feature] terminal config load

* [Feature] es support

* [Update] 修改requirement

* [Update] 修改requirements

* [Update] 修改dictfiled

* [Fix] 修改Logger

* [Bugfix] 倒序显示

* [Update] 修改默认头像和logo

* [Update] 修改django-celery-beat的版本

* [Feature] 添加修改用户密码api

* add logo test

* [Bugfix] 修复一些bug

* [Update] 修改copyrite

* [Update] 修改copyright

* Update ISSUE_TEMPLATE.md

* [Update] 修改禁止排序的颜色

* [Feature] 标签管理功能

* [Bugfix] git status

* [Model] 修改create_by字段

* [Update] 修改位置

* [Update] 修改签名md5算法

* [Feature] 资产列表标签搜索

* [Feature] 添加资产详情标签

* [Bugfix] 修复资产搜索bug

* [Update] ansible disk bug

* [Update] ansible disk bug

* [Bugfix] 修复获取kvmcpu的bug

* [Bugfix] 修复bsd获取cpu数量bug

* [Bugfix] 修改翻译

* [Bugfix] 资产model 太长

* [Bugfix] 修改项目结构描述

修正"项目多语言目录"

* Update project_structure.md

* [Update] add debug log

* refactor: rename folder i18n

* [Feature] 添加链接token

* [Feature] Label 删除修改

* [Update] 修改部分翻译

* [Update] 修改小bug

* [Update] 修复获取资产信息异常bug

* [Bugfix] 修复系统用户上传秘钥的bug

* [Update] 修改获取资产信息产生的异常

* [Update] 删除部分资产属性

* [Bugfix] 资产批量便捷

* [Update] 修改认证

* [Feature] 支持popover

* [Feature] tree

* [Feature] 添加资产树

* [Feature] 使用ztree

* [Feature] tree增删功能

* [Bugfix] 修复组详情bug

* [Bugfix] 修复组详情bug

* [Bugfix] 修改创建label时报错的bug

* [Bugfix] 修改label api bug

* [Update] 去掉资产组添加

* [Update] 修改ztrr

* Update README.md

* [Update] 修改资产创建

* [Bugfix] 修复ldap认证bug

* [Update] 修改一处翻译

* [Update] 更改授权规则前commit

* [Abandon] ...

* Update README.md

* Update README.md

* Update README.md

* [Feature] 完成资产授权和资产添加

* [Update] 修改授权

* [Bugfix] 修改创建系统用户的bug

* feat: rdp support

* [Update] 拆分asset api module

* [Update] 资产列表选中和移除资产

* [Feature] 更改perms api

* [Update] 使用资产树,去掉集群和资产组

* [Update] 修改系统用户推送,拆分assets的部分模块

* [Update] 完成树形改造

* [Update] 完成资产书

* [Update] 修改资产model

* ubuntu16.04 deb_requirements.txt update (#1007)

* Update run server.py (#915)

Fix  for not callable error when  config.py not exists

* [Update]一些修改

* [Update] 修改初始

* feat: replay setting page and api

* 增加隐藏树功能

* [Update] 修改翻译

* 对齐菜单文字。修改英文

* feat: update app setting

* fix: app get replay storage

* [Update] 修改文案

* [Docs] 初始化doc

* [Bugfix] 用户csv导入编码问题

* [Update] 修改设置的一些require

* [Bugfix] 修复管理用户无法查看的bug

* [Update] 修改授权api, windows资产只有rdp协议,linux只有ssh协议

* [Update] terminal可以更改名称

* [Update] 统一copyright

* [Update] 修改文档

* [Bugfix] 修复资产禁用还可以登录

* [Update] 修改文案

* [Update] 支持拖拽更新

* [Bugfix] 修复bug,修改celery beat版本依赖

* [Update] 修改一些小问题

* 添加普通用户使用内容

* [Update] 修改一些文案

* Update README.md

* Update README.md

* Update README.md

* 用户列表

* [Update] 修改一些bug和文案

* [Delete] 删除build 页面

* 用户管理模块更新

* 用户管理模块更新

* [Update] 修改conf

* [Update] bugfix

* [Update] 更新文档地址

* 用户管理模块更新

* [Update] 修改部分翻译和文档

* 管理用户

* 权限管理文档

* 权限管理文档命名修改

* 作业中心文档

* 细节改动

* 添加贡献者

* 截图

* [Update] 修改一些bug

* add ignore

* [Update] 修改文档

* fix bug

* add ignore

* [Igore] force

* [Update] 修改链接

* [Update] 修改版本

* 标签管理

* 会话管理,权限管理,作业中心文档

* [Update] 增加批量终端session api

* [Update] 修改Node value唯一

* 系统设置

* 快速启动修改

* [Bugfix] 修复首页无法显示数据的bug

* feat: s3 replay file get

* feat: update

* [Update] 修改bug

* [Update] 修改Model

* [Update] 修改文档地址

* [Update] 修改gua的安装

* [Update] 修改推送任务

* [Update] 修改安装分支

* feat: update the requirements

* [Update] 更新README

* fix: remove gssapi==1.2.4

* [Update] 修改readme

* fix(config = settings.TERMINAL_REPLAY_STORAGE.items()):

* fix: AttributeError: 'SessionReplayViewSet' object has no attribute 'ACCESS_KEY'

* [Update] 修改readme

* [Update] index

* [Update] 修改Linux截图
2018-03-07 23:26:50 +08:00
ibuler
63924a2ef4 Merge branch 'master' of github.com:jumpserver/jumpserver into dev 2018-03-07 23:26:25 +08:00
ibuler
2842153e21 [Update] 修改Linux截图 2018-03-07 23:21:29 +08:00
老广
3643ee1f89 Dev (#1053)
* [Update] 修改 success message, 添加资产组时可以添加资产

* [Update] system user form add label

* [Update] set default cluster

* [Update] 修改一些翻译

* [Bugfix] 修复重置密码bug

* [Bugfix] 默认default cluster

* [Bugfix] 用户添加报错

* 修改tab样式

* [Bugfix] 修复了一些显示上的bug

* 修复全选按钮在搜索后仍然选择全部的问题

* [Bugfix] 修复以下bug
1. 查看执行历史异常
2. 用户授权资产页显示message

* [Update] api 返回platform, 并增加web terminal nav

* [Feature] 添加setting页面

* [Feature] 添加basic settings

* [Update] 修改翻译

* [Update] 修改config

* [Update] 启动加载common setting

* [Bugfix] 修复cluster创建的bug

* [Bugfix] 修复title显示Jumpserver

* [Bugfix] setting tables not found

* [Bugfix] settings add option

* [Feature] 添加后端paging

* [Bugfix] 资产列表选择别的页会报错

* [Update] check all 只选择当前页面

* [Bugfix] user login ip

* [Bugfix] for login ip

* [Bugfix] 修复资产列表显示bug

* [Remove] labels

* [Bugfix] task运行失败,因为tasks没有设置

* [Feature] 增加标签

* [Bugfix] 读取不到prefix

* For storage

* [Change] 修改部分翻译

* [Update] 启用ldap移动位置

* [Update] 修改翻译

* [Feature] 支持es存储命令

* Update README.md

* [Feature] 添加es支持

* [update] 修改用户创建时 姓名和用户名的位置

* [Update] 修改install.md

* [Update] remote default PAGE_SIZE stting

* [Feature] terminal config load

* [Feature] es support

* [Update] 修改requirement

* [Update] 修改requirements

* [Update] 修改dictfiled

* [Fix] 修改Logger

* [Bugfix] 倒序显示

* [Update] 修改默认头像和logo

* [Update] 修改django-celery-beat的版本

* [Feature] 添加修改用户密码api

* add logo test

* [Bugfix] 修复一些bug

* [Update] 修改copyrite

* [Update] 修改copyright

* Update ISSUE_TEMPLATE.md

* [Update] 修改禁止排序的颜色

* [Feature] 标签管理功能

* [Bugfix] git status

* [Model] 修改create_by字段

* [Update] 修改位置

* [Update] 修改签名md5算法

* [Feature] 资产列表标签搜索

* [Feature] 添加资产详情标签

* [Bugfix] 修复资产搜索bug

* [Update] ansible disk bug

* [Update] ansible disk bug

* [Bugfix] 修复获取kvmcpu的bug

* [Bugfix] 修复bsd获取cpu数量bug

* [Bugfix] 修改翻译

* [Bugfix] 资产model 太长

* [Bugfix] 修改项目结构描述

修正"项目多语言目录"

* Update project_structure.md

* [Update] add debug log

* refactor: rename folder i18n

* [Feature] 添加链接token

* [Feature] Label 删除修改

* [Update] 修改部分翻译

* [Update] 修改小bug

* [Update] 修复获取资产信息异常bug

* [Bugfix] 修复系统用户上传秘钥的bug

* [Update] 修改获取资产信息产生的异常

* [Update] 删除部分资产属性

* [Bugfix] 资产批量便捷

* [Update] 修改认证

* [Feature] 支持popover

* [Feature] tree

* [Feature] 添加资产树

* [Feature] 使用ztree

* [Feature] tree增删功能

* [Bugfix] 修复组详情bug

* [Bugfix] 修复组详情bug

* [Bugfix] 修改创建label时报错的bug

* [Bugfix] 修改label api bug

* [Update] 去掉资产组添加

* [Update] 修改ztrr

* Update README.md

* [Update] 修改资产创建

* [Bugfix] 修复ldap认证bug

* [Update] 修改一处翻译

* [Update] 更改授权规则前commit

* [Abandon] ...

* Update README.md

* Update README.md

* Update README.md

* [Feature] 完成资产授权和资产添加

* [Update] 修改授权

* [Bugfix] 修改创建系统用户的bug

* feat: rdp support

* [Update] 拆分asset api module

* [Update] 资产列表选中和移除资产

* [Feature] 更改perms api

* [Update] 使用资产树,去掉集群和资产组

* [Update] 修改系统用户推送,拆分assets的部分模块

* [Update] 完成树形改造

* [Update] 完成资产书

* [Update] 修改资产model

* ubuntu16.04 deb_requirements.txt update (#1007)

* Update run server.py (#915)

Fix  for not callable error when  config.py not exists

* [Update]一些修改

* [Update] 修改初始

* feat: replay setting page and api

* 增加隐藏树功能

* [Update] 修改翻译

* 对齐菜单文字。修改英文

* feat: update app setting

* fix: app get replay storage

* [Update] 修改文案

* [Docs] 初始化doc

* [Bugfix] 用户csv导入编码问题

* [Update] 修改设置的一些require

* [Bugfix] 修复管理用户无法查看的bug

* [Update] 修改授权api, windows资产只有rdp协议,linux只有ssh协议

* [Update] terminal可以更改名称

* [Update] 统一copyright

* [Update] 修改文档

* [Bugfix] 修复资产禁用还可以登录

* [Update] 修改文案

* [Update] 支持拖拽更新

* [Bugfix] 修复bug,修改celery beat版本依赖

* [Update] 修改一些小问题

* 添加普通用户使用内容

* [Update] 修改一些文案

* Update README.md

* Update README.md

* Update README.md

* 用户列表

* [Update] 修改一些bug和文案

* [Delete] 删除build 页面

* 用户管理模块更新

* 用户管理模块更新

* [Update] 修改conf

* [Update] bugfix

* [Update] 更新文档地址

* 用户管理模块更新

* [Update] 修改部分翻译和文档

* 管理用户

* 权限管理文档

* 权限管理文档命名修改

* 作业中心文档

* 细节改动

* 添加贡献者

* 截图

* [Update] 修改一些bug

* add ignore

* [Update] 修改文档

* fix bug

* add ignore

* [Igore] force

* [Update] 修改链接

* [Update] 修改版本

* 标签管理

* 会话管理,权限管理,作业中心文档

* [Update] 增加批量终端session api

* [Update] 修改Node value唯一

* 系统设置

* 快速启动修改

* [Bugfix] 修复首页无法显示数据的bug

* feat: s3 replay file get

* feat: update

* [Update] 修改bug

* [Update] 修改Model

* [Update] 修改文档地址

* [Update] 修改gua的安装

* [Update] 修改推送任务

* [Update] 修改安装分支

* feat: update the requirements

* [Update] 更新README

* fix: remove gssapi==1.2.4

* [Update] 修改readme

* fix(config = settings.TERMINAL_REPLAY_STORAGE.items()):

* fix: AttributeError: 'SessionReplayViewSet' object has no attribute 'ACCESS_KEY'

* [Update] 修改readme

* [Update] index
2018-03-07 23:18:34 +08:00
ibuler
14510b08a4 Merge branch 'github_master' into github_dev 2018-03-07 23:13:17 +08:00
ibuler
f2251bbb32 [Update] index 2018-03-07 22:38:37 +08:00
liuzheng712
580f1f2a82 Merge branch 'dev' of bitbucket.org:jumpserver/core into dev 2018-03-07 22:15:41 +08:00
liuzheng712
3c6c05f83e fix: update 2018-03-07 22:15:17 +08:00
ibuler
4e0f81e447 Merge remote-tracking branch 'origin/dev' into dev 2018-03-07 22:15:06 +08:00
ibuler
629ff39026 [Update] 修改readme 2018-03-07 22:10:30 +08:00
liuzheng712
51d7e51119 fix: AttributeError: 'SessionReplayViewSet' object has no attribute 'ACCESS_KEY' 2018-03-07 22:05:50 +08:00
liuzheng712
3c32048aa8 Merge branch 'dev' of bitbucket.org:jumpserver/core into dev 2018-03-07 21:55:33 +08:00
liuzheng712
166a3fff5c fix(config = settings.TERMINAL_REPLAY_STORAGE.items()): 2018-03-07 21:54:58 +08:00
ibuler
476a00d270 Merge branch 'docs' into dev 2018-03-07 21:41:08 +08:00
ibuler
2e51a28deb Merge remote-tracking branch 'origin/dev' into dev 2018-03-07 21:39:04 +08:00
ibuler
0bd33ec823 [Update] 修改readme 2018-03-07 21:38:34 +08:00
liuzheng712
813e10ed11 fix: remove gssapi==1.2.4 2018-03-07 21:35:18 +08:00
ibuler
8b4d7c0dd7 Merge remote-tracking branch 'origin/dev' into dev 2018-03-07 21:33:26 +08:00
ibuler
395dc2e505 [Update] 更新README 2018-03-07 21:32:49 +08:00
liuzheng712
2406a7590b feat: update the requirements 2018-03-07 21:28:06 +08:00
ibuler
f86322fa15 [Update] 修改安装分支 2018-03-07 21:26:19 +08:00
ibuler
88c10e851b [Update] 修改推送任务 2018-03-07 21:24:13 +08:00
老广
c2abd58dcb Merge to dev (#1051)
* [Update] 修改 success message, 添加资产组时可以添加资产

* [Update] system user form add label

* [Update] set default cluster

* [Update] 修改一些翻译

* [Bugfix] 修复重置密码bug

* [Bugfix] 默认default cluster

* [Bugfix] 用户添加报错

* 修改tab样式

* [Bugfix] 修复了一些显示上的bug

* 修复全选按钮在搜索后仍然选择全部的问题

* [Bugfix] 修复以下bug
1. 查看执行历史异常
2. 用户授权资产页显示message

* [Update] api 返回platform, 并增加web terminal nav

* [Feature] 添加setting页面

* [Feature] 添加basic settings

* [Update] 修改翻译

* [Update] 修改config

* [Update] 启动加载common setting

* [Bugfix] 修复cluster创建的bug

* [Bugfix] 修复title显示Jumpserver

* [Bugfix] setting tables not found

* [Bugfix] settings add option

* [Feature] 添加后端paging

* [Bugfix] 资产列表选择别的页会报错

* [Update] check all 只选择当前页面

* [Bugfix] user login ip

* [Bugfix] for login ip

* [Bugfix] 修复资产列表显示bug

* [Remove] labels

* [Bugfix] task运行失败,因为tasks没有设置

* [Feature] 增加标签

* [Bugfix] 读取不到prefix

* For storage

* [Change] 修改部分翻译

* [Update] 启用ldap移动位置

* [Update] 修改翻译

* [Feature] 支持es存储命令

* Update README.md

* [Feature] 添加es支持

* [update] 修改用户创建时 姓名和用户名的位置

* [Update] 修改install.md

* [Update] remote default PAGE_SIZE stting

* [Feature] terminal config load

* [Feature] es support

* [Update] 修改requirement

* [Update] 修改requirements

* [Update] 修改dictfiled

* [Fix] 修改Logger

* [Bugfix] 倒序显示

* [Update] 修改默认头像和logo

* [Update] 修改django-celery-beat的版本

* [Feature] 添加修改用户密码api

* add logo test

* [Bugfix] 修复一些bug

* [Update] 修改copyrite

* [Update] 修改copyright

* Update ISSUE_TEMPLATE.md

* [Update] 修改禁止排序的颜色

* [Feature] 标签管理功能

* [Bugfix] git status

* [Model] 修改create_by字段

* [Update] 修改位置

* [Update] 修改签名md5算法

* [Feature] 资产列表标签搜索

* [Feature] 添加资产详情标签

* [Bugfix] 修复资产搜索bug

* [Update] ansible disk bug

* [Update] ansible disk bug

* [Bugfix] 修复获取kvmcpu的bug

* [Bugfix] 修复bsd获取cpu数量bug

* [Bugfix] 修改翻译

* [Bugfix] 资产model 太长

* [Bugfix] 修改项目结构描述

修正"项目多语言目录"

* Update project_structure.md

* [Update] add debug log

* refactor: rename folder i18n

* [Feature] 添加链接token

* [Feature] Label 删除修改

* [Update] 修改部分翻译

* [Update] 修改小bug

* [Update] 修复获取资产信息异常bug

* [Bugfix] 修复系统用户上传秘钥的bug

* [Update] 修改获取资产信息产生的异常

* [Update] 删除部分资产属性

* [Bugfix] 资产批量便捷

* [Update] 修改认证

* [Feature] 支持popover

* [Feature] tree

* [Feature] 添加资产树

* [Feature] 使用ztree

* [Feature] tree增删功能

* [Bugfix] 修复组详情bug

* [Bugfix] 修复组详情bug

* [Bugfix] 修改创建label时报错的bug

* [Bugfix] 修改label api bug

* [Update] 去掉资产组添加

* [Update] 修改ztrr

* Update README.md

* [Update] 修改资产创建

* [Bugfix] 修复ldap认证bug

* [Update] 修改一处翻译

* [Update] 更改授权规则前commit

* [Abandon] ...

* Update README.md

* Update README.md

* Update README.md

* [Feature] 完成资产授权和资产添加

* [Update] 修改授权

* [Bugfix] 修改创建系统用户的bug

* feat: rdp support

* [Update] 拆分asset api module

* [Update] 资产列表选中和移除资产

* [Feature] 更改perms api

* [Update] 使用资产树,去掉集群和资产组

* [Update] 修改系统用户推送,拆分assets的部分模块

* [Update] 完成树形改造

* [Update] 完成资产书

* [Update] 修改资产model

* ubuntu16.04 deb_requirements.txt update (#1007)

* Update run server.py (#915)

Fix  for not callable error when  config.py not exists

* [Update]一些修改

* [Update] 修改初始

* feat: replay setting page and api

* 增加隐藏树功能

* [Update] 修改翻译

* 对齐菜单文字。修改英文

* feat: update app setting

* fix: app get replay storage

* [Update] 修改文案

* [Docs] 初始化doc

* [Bugfix] 用户csv导入编码问题

* [Update] 修改设置的一些require

* [Bugfix] 修复管理用户无法查看的bug

* [Update] 修改授权api, windows资产只有rdp协议,linux只有ssh协议

* [Update] terminal可以更改名称

* [Update] 统一copyright

* [Update] 修改文档

* [Bugfix] 修复资产禁用还可以登录

* [Update] 修改文案

* [Update] 支持拖拽更新

* [Bugfix] 修复bug,修改celery beat版本依赖

* [Update] 修改一些小问题

* 添加普通用户使用内容

* [Update] 修改一些文案

* Update README.md

* Update README.md

* Update README.md

* 用户列表

* [Update] 修改一些bug和文案

* [Delete] 删除build 页面

* [Update] 修改conf

* [Update] bugfix

* [Update] 更新文档地址

* [Update] 修改部分翻译和文档

* [Update] 修改一些bug

* [Update] 修改链接

* [Update] 增加批量终端session api

* [Update] 修改Node value唯一

* [Bugfix] 修复首页无法显示数据的bug

* feat: s3 replay file get

* feat: update

* [Update] 修改bug
2018-03-07 21:21:56 +08:00
ibuler
1fa3e98eb0 Merge remote-tracking branch 'github/docs' into docs 2018-03-07 19:13:54 +08:00
ibuler
42af939501 [Update] 修改gua的安装 2018-03-07 19:12:44 +08:00
ibuler
2def25cae6 [Update] 修改文档地址 2018-03-07 19:08:42 +08:00
ibuler
d3fa3d63e7 [Update] 修改Model 2018-03-07 19:05:43 +08:00
ibuler
5cc43f6907 Merge remote-tracking branch 'github/dev' into dev 2018-03-07 18:10:33 +08:00
ibuler
d852f0182b [Update] 修改bug 2018-03-07 17:48:19 +08:00
liuzheng712
9aed73d644 feat: update 2018-03-07 17:18:56 +08:00
liuzheng712
d1a2fe145d Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2018-03-07 17:18:06 +08:00
liuzheng712
83f83d9b07 feat: s3 replay file get 2018-03-07 17:17:31 +08:00
ibuler
c4afd04cbc Merge remote-tracking branch 'github/dev' into dev 2018-03-07 16:13:52 +08:00
ibuler
40d2934de0 [Bugfix] 修复首页无法显示数据的bug 2018-03-07 16:04:13 +08:00
fit2cloud-fengyi
e734fa3b0d 快速启动修改 2018-03-07 14:47:14 +08:00
fit2cloud-fengyi
50b0e024e5 系统设置 2018-03-07 13:07:18 +08:00
fit2cloud-fengyi
f7d1a8b35f 系统设置 2018-03-07 13:03:07 +08:00
ibuler
cd9000e7e9 [Update] 修改Node value唯一 2018-03-07 12:13:03 +08:00
ibuler
af2db2d870 [Update] 增加批量终端session api 2018-03-07 11:28:42 +08:00
shenchenyang
2559899b97 会话管理,权限管理,作业中心文档 2018-03-07 11:17:55 +08:00
fit2cloud-fengyi
86cf7bd6b5 标签管理 2018-03-07 10:35:58 +08:00
ibuler
150855183a [Update] 修改版本 2018-03-06 21:12:51 +08:00
ibuler
0aa4755565 [Update] 修改链接 2018-03-06 21:09:40 +08:00
ibuler
7488d8834e [Igore] force 2018-03-06 18:54:58 +08:00
ibuler
022f6625b1 Merge remote-tracking branch 'github/docs' into docs 2018-03-06 18:54:03 +08:00
fit2cloud-fengyi
115c7c4d50 add ignore 2018-03-06 18:52:09 +08:00
fit2cloud-fengyi
094e862abf fix bug 2018-03-06 18:49:36 +08:00
ibuler
55436ddff1 Merge remote-tracking branch 'github/docs' into docs 2018-03-06 18:41:57 +08:00
ibuler
df1c85494b [Update] 修改文档 2018-03-06 18:41:31 +08:00
fit2cloud-fengyi
8e09151a02 Merge branch 'docs' of https://github.com/jumpserver/jumpserver into docs 2018-03-06 18:30:42 +08:00
fit2cloud-fengyi
18841d6c21 add ignore 2018-03-06 18:29:24 +08:00
ibuler
3fe5dadebc [Update] 修改介绍 2018-03-06 18:27:28 +08:00
ibuler
d3e77b09ef [Merge] with doc 2018-03-06 18:04:03 +08:00
ibuler
25ebb5c442 [Update] 修改一些bug 2018-03-06 17:05:36 +08:00
fit2cloud-fengyi
84c4e69062 截图 2018-03-06 16:54:00 +08:00
fit2cloud-fengyi
ed7f7392db 添加贡献者 2018-03-06 15:42:46 +08:00
fit2cloud-fengyi
457886cb6c Merge branch 'docs' of https://github.com/jumpserver/jumpserver into docs 2018-03-06 15:16:57 +08:00
fit2cloud-fengyi
f724f46e00 细节改动 2018-03-06 15:16:42 +08:00
shenchenyang
6a8d75f00e 作业中心文档 2018-03-06 12:18:08 +08:00
shenchenyang
65619fabc5 权限管理文档命名修改 2018-03-06 11:54:50 +08:00
shenchenyang
370534e28f Merge branch 'docs' of https://github.com/jumpserver/jumpserver into docs 2018-03-06 11:50:20 +08:00
shenchenyang
cefdcb242c 权限管理文档 2018-03-06 11:49:42 +08:00
fit2cloud-fengyi
31ba73e2fa 管理用户 2018-03-06 11:00:19 +08:00
ibuler
86c0a2d28b [Update] 修改部分翻译和文档 2018-03-05 17:14:42 +08:00
fit2cloud-fengyi
4778ac1392 用户管理模块更新 2018-03-05 17:12:02 +08:00
fit2cloud-fengyi
58189df280 用户管理模块更新 2018-03-05 17:09:53 +08:00
ibuler
bc230e0ea5 [Update] 更新文档地址 2018-03-05 15:25:49 +08:00
ibuler
21328382fc [Update] bugfix 2018-03-05 15:05:48 +08:00
ibuler
eca5966257 [Update] 修改conf 2018-03-05 15:04:11 +08:00
fit2cloud-fengyi
42cb54dd2a 用户管理模块更新 2018-03-05 13:10:51 +08:00
fit2cloud-fengyi
d07b427037 用户管理模块更新 2018-03-05 13:10:02 +08:00
ibuler
efcf31b2a9 [Delete] 删除build 页面 2018-03-05 13:09:00 +08:00
ibuler
e123599735 [Update] 修改一些bug和文案 2018-03-05 12:59:14 +08:00
fit2cloud-fengyi
1c204675e5 用户列表 2018-03-05 12:20:40 +08:00
老广
e449a07a3f Update README.md 2018-03-05 10:11:13 +08:00
老广
d4f61b9e69 Update README.md 2018-03-05 10:08:04 +08:00
老广
4451d68d62 Update README.md 2018-03-05 10:07:34 +08:00
ibuler
bd4f96134f [Update] 修改一些文案 2018-03-04 13:01:33 +08:00
fit2cloud-fengyi
767d94875c 添加普通用户使用内容 2018-03-04 09:57:11 +08:00
ibuler
d284c2175d [Update] 修改一些小问题 2018-03-02 15:39:01 +08:00
ibuler
f7ab13952e [Bugfix] 修复bug,修改celery beat版本依赖 2018-03-02 09:36:17 +08:00
ibuler
5dcdeddf22 Merge remote-tracking branch 'github/dev' into dev 2018-03-01 13:39:52 +08:00
ibuler
1018deda96 [Update] 支持拖拽更新 2018-03-01 12:40:41 +08:00
ibuler
5a0068d86a [Update] 修改文案 2018-03-01 10:45:51 +08:00
ibuler
31629fc975 [Bugfix] 修复资产禁用还可以登录 2018-03-01 10:44:55 +08:00
ibuler
634b36c74b [Update] 修改文档 2018-03-01 00:13:53 +08:00
ibuler
521a5c57a2 [Update] 统一copyright 2018-02-28 11:23:04 +08:00
ibuler
1e5b9fb3ef [Update] terminal可以更改名称 2018-02-28 10:39:38 +08:00
ibuler
f886e7c2f5 [Update] 修改授权api, windows资产只有rdp协议,linux只有ssh协议 2018-02-27 19:39:27 +08:00
ibuler
91863107d7 [Bugfix] 修复管理用户无法查看的bug 2018-02-27 15:32:30 +08:00
ibuler
870b863136 [Update] 修改设置的一些require 2018-02-27 15:04:05 +08:00
ibuler
9292e48554 [Bugfix] 用户csv导入编码问题 2018-02-27 12:18:36 +08:00
ibuler
13abd4c751 [Docs] 初始化doc 2018-02-27 10:27:28 +08:00
ibuler
8e2891d7d7 [Update] 修改文案 2018-02-27 10:27:08 +08:00
ibuler
315159e4b6 Merge branch 'dev' of bitbucket.org:jumpserver/core into dev 2018-02-26 18:12:20 +08:00
liuzheng712
fc61dea9b5 fix: app get replay storage 2018-02-26 18:11:46 +08:00
ibuler
08ccac3f66 Merge branch 'dev' of bitbucket.org:jumpserver/core into dev 2018-02-26 18:06:09 +08:00
liuzheng712
ea27d05c58 feat: update app setting 2018-02-26 18:05:41 +08:00
q4speed
05255f850f Merge remote-tracking branch 'origin/dev' into dev 2018-02-26 17:28:18 +08:00
q4speed
c96a107e0a 对齐菜单文字。修改英文 2018-02-26 17:28:03 +08:00
ibuler
e2cb128794 [Update] 修改翻译 2018-02-26 16:57:34 +08:00
ibuler
24fdff0120 Merge remote-tracking branch 'github/dev' into dev 2018-02-26 16:32:40 +08:00
ibuler
8999458a72 Merge branch 'dev' of bitbucket.org:jumpserver/core into dev 2018-02-26 16:32:20 +08:00
q4speed
66b8e8bcf8 增加隐藏树功能 2018-02-26 16:31:51 +08:00
liuzheng
459d0668a8 feat: replay setting page and api 2018-02-26 16:19:29 +08:00
ibuler
c68da5898a [Update] 修改初始 2018-02-26 12:31:33 +08:00
ibuler
1f3b11a223 Merge remote-tracking branch 'github/dev' into dev 2018-02-26 11:38:20 +08:00
ibuler
f1c386714d [Update]一些修改 2018-02-25 22:36:42 +08:00
calmzhu
5193ba2e39 Update run server.py (#915)
Fix  for not callable error when  config.py not exists
2018-02-25 20:09:15 +08:00
bagechashu
eb18648a66 ubuntu16.04 deb_requirements.txt update (#1007) 2018-02-25 20:07:26 +08:00
ibuler
f0dd7d54c8 [Update] 修改资产model 2018-02-25 18:40:15 +08:00
ibuler
08edda35e1 [Update] 完成资产书 2018-02-25 18:08:00 +08:00
ibuler
c8728cace4 [Update] 完成树形改造 2018-02-09 15:24:44 +08:00
ibuler
c7296c2498 [Update] 修改系统用户推送,拆分assets的部分模块 2018-02-09 11:12:40 +08:00
ibuler
f82d939d15 [Update] 使用资产树,去掉集群和资产组 2018-02-08 11:34:21 +08:00
ibuler
3bb6e08985 [Feature] 更改perms api 2018-02-07 23:25:15 +08:00
ibuler
6104acae8f [Update] 资产列表选中和移除资产 2018-02-07 13:39:45 +08:00
ibuler
bd4768c147 [Update] 拆分asset api module 2018-02-06 18:32:02 +08:00
ibuler
d047ff3b3a Merge branch 'dev' into tree 2018-02-06 13:02:30 +08:00
liuzheng712
6edd3f6cf8 feat: rdp support 2018-02-05 21:54:57 +08:00
ibuler
bdf506a555 Merge remote-tracking branch 'github/dev' into dev 2018-02-02 19:04:36 +08:00
ibuler
114289edaf [Bugfix] 修改创建系统用户的bug 2018-02-02 19:04:09 +08:00
ibuler
274cb74097 [Update] 修改授权 2018-02-02 18:52:09 +08:00
ibuler
2d3967872b [Feature] 完成资产授权和资产添加 2018-02-02 17:06:08 +08:00
老广
64da400281 Update README.md 2018-02-01 17:57:50 +08:00
老广
9ffe1b5ab5 Update README.md 2018-02-01 17:56:04 +08:00
老广
83ad72e04b Update README.md 2018-02-01 17:54:26 +08:00
ibuler
653c328e84 [Abandon] ... 2018-02-01 17:14:15 +08:00
ibuler
2bc5e882fd [Update] 更改授权规则前commit 2018-02-01 15:06:44 +08:00
ibuler
45f6a62989 [Update] 修改一处翻译 2018-02-01 12:37:45 +08:00
ibuler
21a7202587 [Bugfix] 修复ldap认证bug 2018-02-01 12:33:05 +08:00
ibuler
02cd3b1a18 Merge remote-tracking branch 'github/dev' into dev 2018-02-01 10:23:32 +08:00
ibuler
a10ff5930f [Update] 修改资产创建 2018-02-01 10:22:20 +08:00
老广
2b4880c784 Update README.md 2018-02-01 10:20:33 +08:00
ibuler
017c3ae36a [Update] 修改ztrr 2018-02-01 01:03:31 +08:00
ibuler
c4b52cb2a3 [Update] 去掉资产组添加 2018-02-01 00:33:00 +08:00
ibuler
5f2ca58d62 [Bugfix] 修改label api bug 2018-01-31 18:59:43 +08:00
ibuler
1c7212014b [Bugfix] 修改创建label时报错的bug 2018-01-31 18:48:07 +08:00
ibuler
97dd411ab8 [Bugfix] 修复组详情bug 2018-01-31 17:06:04 +08:00
ibuler
d2ad10af9a [Bugfix] 修复组详情bug 2018-01-31 17:04:15 +08:00
ibuler
2f06a2b1d3 [Feature] tree增删功能 2018-01-31 17:01:21 +08:00
ibuler
1ac30ed09c [Feature] 使用ztree 2018-01-31 12:46:33 +08:00
ibuler
3603b33a42 [Feature] 添加资产树 2018-01-31 10:46:26 +08:00
ibuler
460fa8e8a9 [Feature] tree 2018-01-30 19:57:47 +08:00
ibuler
9e09a962af [Feature] 支持popover 2018-01-30 18:07:51 +08:00
ibuler
3e62a7f5b7 [Update] 修改认证 2018-01-30 16:12:33 +08:00
ibuler
b4f833740e [Bugfix] 资产批量便捷 2018-01-30 14:54:27 +08:00
ibuler
1fbf4ac08c [Update] 删除部分资产属性 2018-01-30 14:46:02 +08:00
ibuler
da4c5f48a1 [Update] 修改获取资产信息产生的异常 2018-01-30 12:09:33 +08:00
ibuler
1192e8cdad [Bugfix] 修复系统用户上传秘钥的bug 2018-01-30 11:56:41 +08:00
ibuler
bad397e2e6 [Update] 修复获取资产信息异常bug 2018-01-30 10:38:40 +08:00
ibuler
0f15a94b08 Merge remote-tracking branch 'origin/dev' into dev 2018-01-29 17:04:09 +08:00
ibuler
012614562f [Update] 修改小bug 2018-01-29 16:57:50 +08:00
ibuler
8b626ea9d4 [Update] 修改部分翻译 2018-01-29 16:27:21 +08:00
ibuler
58d22b72ec [Feature] Label 删除修改 2018-01-29 16:25:30 +08:00
ibuler
6d552f4680 [Feature] 添加链接token 2018-01-29 16:18:30 +08:00
liuzheng
e821d2995d refactor: rename folder i18n 2018-01-29 11:54:38 +08:00
ibuler
cc4eca2563 [Update] add debug log 2018-01-29 11:53:49 +08:00
liuzheng
04c344e2a0 Update project_structure.md 2018-01-29 11:50:41 +08:00
liuzheng
7f777a4472 Merge pull request #968 from chenchen1750/patch-1
[Bugfix] 修改项目结构描述
2018-01-29 11:49:06 +08:00
chenchen1750
1f792a9e3c [Bugfix] 修改项目结构描述
修正"项目多语言目录"
2018-01-29 11:07:01 +08:00
ibuler
6d4e9c7d30 [Bugfix] 资产model 太长 2018-01-26 17:17:37 +08:00
ibuler
9433d6177a [Bugfix] 修改翻译 2018-01-26 16:50:59 +08:00
ibuler
723805d395 [Bugfix] 修复bsd获取cpu数量bug 2018-01-26 16:28:40 +08:00
ibuler
c553872f90 Merge remote-tracking branch 'github/dev' into dev 2018-01-26 16:22:06 +08:00
ibuler
41756b06e1 [Bugfix] 修复获取kvmcpu的bug 2018-01-26 16:21:14 +08:00
ibuler
9e36a2cbb1 [Update] ansible disk bug 2018-01-26 16:06:36 +08:00
ibuler
f0b9a11482 [Update] ansible disk bug 2018-01-26 16:06:23 +08:00
ibuler
f6d21585ab [Bugfix] 修复资产搜索bug 2018-01-26 15:53:43 +08:00
ibuler
b0fab2453a [Merge] 合并标签功能 2018-01-26 15:49:09 +08:00
ibuler
b2d6645f46 [Feature] 添加资产详情标签 2018-01-26 15:32:23 +08:00
ibuler
cb902362b5 [Feature] 资产列表标签搜索 2018-01-26 14:47:10 +08:00
ibuler
0a2b6494cc [Update] 修改签名md5算法 2018-01-25 16:38:40 +08:00
ibuler
0c935e8922 Merge branch 'dev' of bitbucket.org:jumpserver/core into dev 2018-01-25 16:15:54 +08:00
ibuler
17f91f7f53 [Update] 修改位置 2018-01-25 15:43:52 +08:00
ibuler
d74c2e8466 [Model] 修改create_by字段 2018-01-25 12:17:26 +08:00
ibuler
070c3d73cc [Bugfix] git status 2018-01-25 12:16:26 +08:00
ibuler
7433327d75 [Feature] 标签管理功能 2018-01-23 19:37:22 +08:00
ibuler
a976475617 [Update] 修改禁止排序的颜色 2018-01-23 17:11:26 +08:00
ibuler
f37b331630 Merge with dev 2018-01-23 15:13:24 +08:00
老广
4b0ea63e0a Update ISSUE_TEMPLATE.md 2018-01-23 15:02:34 +08:00
ibuler
9dbf498322 [Update] 修改copyright 2018-01-23 12:40:22 +08:00
ibuler
8e6efac6db [Update] 修改copyrite 2018-01-23 12:39:19 +08:00
ibuler
579e74dd5d [Bugfix] 修复一些bug 2018-01-23 12:22:25 +08:00
ibuler
cad07434ff add logo test 2018-01-23 11:11:20 +08:00
ibuler
f40fbaf602 [Feature] 添加修改用户密码api 2018-01-23 10:36:20 +08:00
ibuler
a43d29d446 [Update] 修改django-celery-beat的版本 2018-01-22 23:57:08 +08:00
ibuler
2f136800c7 [Update] 修改默认头像和logo 2018-01-22 23:47:41 +08:00
ibuler
dd6e9444e1 [Bugfix] 倒序显示 2018-01-22 18:48:16 +08:00
ibuler
7670f521a2 [Fix] 修改Logger 2018-01-22 18:37:28 +08:00
ibuler
cafb0e02a3 [Update] 修改dictfiled 2018-01-22 17:21:03 +08:00
ibuler
9d399c475c [Update] 修改requirements 2018-01-22 12:49:55 +08:00
ibuler
8766a936f3 [Update] 修改requirement 2018-01-22 12:01:32 +08:00
ibuler
968b395bce Merge branch 'es' into dev 2018-01-22 11:51:37 +08:00
ibuler
0a931bbf77 [Feature] es support 2018-01-22 11:38:40 +08:00
ibuler
17181db8a5 [Feature] 支持es存储 2018-01-21 17:27:27 +08:00
ibuler
41f1c3f7f7 [Feature] terminal config load 2018-01-21 15:12:59 +08:00
liuzheng712
c4406c2a33 Merge branch 'master' of github.com:jumpserver/jumpserver into dev 2018-01-21 11:33:44 +08:00
ibuler
7f18821990 [Update] remote default PAGE_SIZE stting 2018-01-20 23:02:17 +08:00
ibuler
8fe3caf2ea [Update] 修改install.md 2018-01-20 22:54:15 +08:00
ibuler
15119bec3c Merge remote-tracking branch 'github/dev' into dev 2018-01-20 22:26:41 +08:00
ibuler
57e508f331 [update] 修改用户创建时 姓名和用户名的位置 2018-01-20 22:26:21 +08:00
ibuler
b936d54a48 [Feature] 添加es支持 2018-01-20 22:22:09 +08:00
老广
5c8dd5676c Merge to master (#944)
* [Update] 修改 success message, 添加资产组时可以添加资产

* [Update] system user form add label

* [Update] set default cluster

* [Update] 修改一些翻译

* [Bugfix] 修复重置密码bug

* [Bugfix] 默认default cluster

* [Bugfix] 用户添加报错

* 修改tab样式

* [Bugfix] 修复了一些显示上的bug

* 修复全选按钮在搜索后仍然选择全部的问题

* [Bugfix] 修复以下bug
1. 查看执行历史异常
2. 用户授权资产页显示message

* [Update] api 返回platform, 并增加web terminal nav

* [Feature] 添加setting页面

* [Feature] 添加basic settings

* [Update] 修改翻译

* [Update] 修改config

* [Update] 启动加载common setting

* [Bugfix] 修复cluster创建的bug

* [Bugfix] 修复title显示Jumpserver

* [Bugfix] setting tables not found

* [Bugfix] settings add option

* [Feature] 添加后端paging

* [Bugfix] 资产列表选择别的页会报错

* [Update] check all 只选择当前页面

* [Bugfix] user login ip

* [Bugfix] for login ip

* [Bugfix] 修复资产列表显示bug

* [Remove] labels

* [Bugfix] task运行失败,因为tasks没有设置

* [Bugfix] 读取不到prefix

* [Change] 修改部分翻译

* [Update] 启用ldap移动位置

* [Update] 修改翻译

* Update README.md
2018-01-20 21:01:55 +08:00
老广
689558b8c7 Update README.md 2018-01-18 18:12:39 +08:00
ibuler
67001dd99f [Feature] 支持es存储命令 2018-01-18 09:56:13 +08:00
ibuler
3c3e9a4113 [Update] 修改翻译 2018-01-17 17:26:25 +08:00
ibuler
d08a1c3ddb [Update] 启用ldap移动位置 2018-01-17 17:22:04 +08:00
ibuler
a77acb7dfb [Change] 修改部分翻译 2018-01-17 17:18:13 +08:00
ibuler
ba5ab21b37 For storage 2018-01-17 17:17:18 +08:00
ibuler
ce9ff67b24 [Bugfix] 读取不到prefix 2018-01-17 16:18:33 +08:00
ibuler
5bbad01909 [Feature] 增加标签 2018-01-16 16:32:06 +08:00
ibuler
01895bafc0 [Bugfix] task运行失败,因为tasks没有设置 2018-01-16 11:40:18 +08:00
ibuler
f1ec53d1bc [Remove] labels 2018-01-16 11:26:30 +08:00
ibuler
d3109a03b2 [Bugfix] 修复资产列表显示bug 2018-01-16 11:20:26 +08:00
ibuler
681ddb5af2 [Bugfix] for login ip 2018-01-16 11:08:05 +08:00
ibuler
29061aa088 [Bugfix] user login ip 2018-01-16 09:58:33 +08:00
ibuler
dad21cadb3 [Update] check all 只选择当前页面 2018-01-15 18:32:07 +08:00
ibuler
7e2d627d3f [Bugfix] 资产列表选择别的页会报错 2018-01-15 18:14:58 +08:00
ibuler
cc18ad9a7f Merge branch 'paging' into dev 2018-01-15 17:41:57 +08:00
ibuler
b2f97a263d [Feature] 添加后端paging 2018-01-15 17:41:49 +08:00
ibuler
8b9e45ad31 [Bugfix] settings add option 2018-01-15 16:00:26 +08:00
ibuler
89e013e2e2 [Bugfix] setting tables not found 2018-01-15 14:17:56 +08:00
ibuler
59a69f0253 [Bugfix] 修复title显示Jumpserver 2018-01-15 13:54:19 +08:00
ibuler
39fff235d1 [Bugfix] 修复cluster创建的bug 2018-01-14 18:02:11 +08:00
ibuler
7316661eb5 [Update] 启动加载common setting 2018-01-12 16:37:55 +08:00
ibuler
f6056426dc [Update] 修改config 2018-01-12 15:57:24 +08:00
ibuler
d48f8dceb5 [Update] 修改翻译 2018-01-12 15:55:08 +08:00
ibuler
abb1a40a4f [Feature] 添加basic settings 2018-01-12 15:43:26 +08:00
ibuler
121f56f44b [Feature] 添加setting页面 2018-01-11 20:10:27 +08:00
ibuler
b49e3b8f84 [Update] api 返回platform, 并增加web terminal nav 2018-01-10 19:39:22 +08:00
ibuler
9bf6b12904 Merge remote-tracking branch 'github/dev' into dev 2018-01-10 18:11:23 +08:00
ibuler
6aaa106aff [Bugfix] 修复以下bug
1. 查看执行历史异常
2. 用户授权资产页显示message
2018-01-10 18:08:27 +08:00
q4speed
576ddbf673 修复全选按钮在搜索后仍然选择全部的问题 2018-01-10 17:56:50 +08:00
ibuler
d415e81add Merge remote-tracking branch 'github/dev' into dev 2018-01-10 17:41:57 +08:00
ibuler
3223d3b74d [Bugfix] 修复了一些显示上的bug 2018-01-10 17:38:10 +08:00
q4speed
7f3d32a876 Merge remote-tracking branch 'origin/dev' into dev 2018-01-10 16:42:57 +08:00
q4speed
6d7b596854 修改tab样式 2018-01-10 16:42:30 +08:00
ibuler
b2b123b41e [Bugfix] 用户添加报错 2018-01-10 15:15:29 +08:00
ibuler
99cd685194 [Bugfix] 默认default cluster 2018-01-10 12:03:35 +08:00
ibuler
7e23d2c234 [Bugfix] 修复重置密码bug 2018-01-10 11:31:25 +08:00
ibuler
b4080be5be [Update] 修改一些翻译 2018-01-10 00:38:21 +08:00
ibuler
22af44211d [Update] set default cluster 2018-01-09 23:33:14 +08:00
ibuler
a4d02adb22 [Update] system user form add label 2018-01-09 23:14:25 +08:00
ibuler
72a82c41ee [Update] 修改 success message, 添加资产组时可以添加资产 2018-01-09 23:07:53 +08:00
ibuler
450a9495ec [Bug&Update] 以下bug和功能
- 修复新建资产不选管理用户和集群异常bug
- profile下拉增加icon
- 授权api增加os和platform
2018-01-09 13:10:28 +08:00
ibuler
c0829194dc [Update] 修改一些bug, 增加执行task的按钮 2018-01-08 19:16:28 +08:00
ibuler
dfaf029a68 [Bugfix] 资产导入bugfix 2018-01-08 15:51:08 +08:00
ibuler
3f1863151a [Bugfix] 修复session搜索bug 2018-01-08 15:15:21 +08:00
ibuler
676d640e70 [Bugfix] 修复导出csv和更新资产环境变量冲突 2018-01-08 14:58:07 +08:00
ibuler
c7d1ba1944 [Update] Middleware 写法升级到新版本, Task login require 2018-01-08 14:18:02 +08:00
ibuler
07a70311df [Bugfix] 修复以下bug
- 删除用户报错,上次更新带来的
- 管理员用户页面会看到所有主机的,而不是授权给自己的
- 授权详情页面 资产显示无效
2018-01-08 11:22:19 +08:00
ibuler
c16471d54f [Bugfix] 资产导入中下载模板异常 2018-01-05 19:09:42 +08:00
ibuler
9a6bc9fec5 [Update] session添加登陆ip 2018-01-05 18:37:36 +08:00
ibuler
1888c698f1 [Bugfix] 修复一些bug 2018-01-05 17:57:02 +08:00
ibuler
6518ae8fa3 Merge remote-tracking branch 'origin/dev' into dev 2018-01-05 14:57:53 +08:00
ibuler
afce4c81a8 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2018-01-05 14:56:50 +08:00
ibuler
28223421b1 [Bugfix] 修复一下bug
1. 添加管理用户时同名的异常
2. 添加授权规则的检查
2018-01-05 14:36:49 +08:00
ibuler
56fd18241d [Update] 修改一些翻译 2018-01-04 09:29:54 +08:00
i317280
7648207ae4 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2018-01-03 17:09:35 +08:00
q4speed
9a2fbba956 修改访问官网链接 2018-01-03 15:07:46 +08:00
ibuler
a327c46229 Merge remote-tracking branch 'github/dev' into dev 2018-01-02 19:37:56 +08:00
ibuler
720dc9ab05 [Bugfix] 修复以下bug
- session时区
- 切换管理和用户页面cookie问题
- 创建权限时验证
- 一些翻译
2018-01-02 19:36:13 +08:00
q4speed
25fa392dda 修复图片高度和大小 2018-01-02 17:51:25 +08:00
q4speed
ad3297ff2f 显示个人头像 2018-01-02 17:40:49 +08:00
q4speed
ab27d1c193 修改菜单折叠起来时Logo 2018-01-02 17:31:20 +08:00
q4speed
8160425672 修改Logo 2018-01-02 17:07:00 +08:00
ibuler
68ccec6b9c [UPdate] 修改cookie设置 2018-01-02 17:02:03 +08:00
q4speed
bf34c2e320 Merge remote-tracking branch 'origin/dev' into dev 2018-01-02 16:50:57 +08:00
q4speed
54bcb33a0e 修改Logo 2018-01-02 16:43:47 +08:00
ibuler
6d15f60c5c 更改默认使用Dev配置文件 2018-01-02 15:23:06 +08:00
ibuler
239a829c20 [Bugfix] support xvdx disk 2018-01-02 14:49:52 +08:00
ibuler
4dbf332a56 [Bugfix] 修复刷新硬件的bug 2018-01-02 14:29:37 +08:00
ibuler
539bf7bec8 Update doc 2018-01-02 10:47:32 +08:00
ibuler
c6eaf894a4 Update doc 2018-01-02 10:46:20 +08:00
ibuler
5eef584c7d [Bugfix] 解决打印print失败问题,原因在于运行docker没有tty,也可以添加PYTHONIOENCODING环境变量解决 2018-01-01 23:45:27 +08:00
ibuler
f4a39aba00 [Debug] 无法print中文 2018-01-01 22:00:08 +08:00
ibuler
3300d20c1c [Update] 修改beat 启动,判断pid文件是否存在 2018-01-01 21:04:43 +08:00
ibuler
edcafa7275 [Update] 修改运行 beat方式 2018-01-01 20:54:48 +08:00
ibuler
e8a72c8c7d [Update] 修改一些翻译 2018-01-01 19:55:37 +08:00
ibuler
73a99de55c [Update] 修改terminal翻译 2018-01-01 15:39:35 +08:00
ibuler
3b6403b2f2 [Update] 修改一些翻译 2018-01-01 15:08:33 +08:00
ibuler
c48531c586 [Update] 添加和修改部分翻译 2018-01-01 00:45:12 +08:00
ibuler
0916757eb8 [Bugfix] 修复一些bug 2017-12-31 21:51:25 +08:00
ibuler
0b299344a7 [Update] 修改database 表现 2017-12-31 12:20:08 +08:00
ibuler
13b610c140 [Change] 仅点击checkbox选中 2017-12-31 11:14:02 +08:00
ibuler
7558c2b3e4 [Debug] debug print error 2017-12-30 23:02:10 +08:00
ibuler
ddd18e10e0 [Debug] debug print error 2017-12-30 22:53:59 +08:00
ibuler
a755882100 [Bugfix] 修复打印中文报错异常 2017-12-30 22:26:05 +08:00
ibuler
6586bef84c [Modify] Add access log 2017-12-30 20:45:54 +08:00
ibuler
e0a3fafbd5 [Bugfix] 详见trello 2017-12-30 02:29:29 +08:00
ibuler
3804ab532d [Update] 修改信号 2017-12-29 23:53:45 +08:00
ibuler
158678c2db [Bugfix] 修改bug,显示cluster 2017-12-28 18:01:15 +08:00
ibuler
2cceb281c2 Merge remote-tracking branch 'github/new_api' into dev 2017-12-28 17:44:59 +08:00
liuzheng712
14de3ba5de Merge branch 'new_api' of github.com:jumpserver/jumpserver into new_api 2017-12-28 17:41:00 +08:00
liuzheng712
ac3ee4c317 feat: luna window 2017-12-28 17:39:24 +08:00
ibuler
69f723c8f5 [Bugfix] requirements 添加openssh-cleints 2017-12-28 16:06:07 +08:00
ibuler
b6b0d6a9be [bugfix] Beat start failed, rm pidfile 2017-12-28 14:34:17 +08:00
ibuler
f992347fc5 [Update] 修改become信息 2017-12-28 14:25:56 +08:00
ibuler
e20444983d [Bugfix] 修改html bug 2017-12-28 12:25:43 +08:00
ibuler
827246ed4c Update ansible remote tmp 2017-12-28 12:03:02 +08:00
ibuler
f58c45f7be [Update] 修改run celery 2017-12-28 11:39:12 +08:00
ibuler
84fa7b5f17 [Bugfix] 修改启动脚本,celery beat可能不存在 2017-12-28 10:52:40 +08:00
ibuler
8e9ad7d645 [Update] 修改runserver运行 2017-12-28 01:18:50 +08:00
ibuler
825edadc13 [Update] Add build no 2017-12-28 01:08:39 +08:00
ibuler
1c20f519a9 [Bugfix] 修改小的bug 2017-12-27 11:22:44 +08:00
ibuler
0848893f1e [Bugfix] 修复时间日期搜索的bug,select2模块自适应长度 2017-12-27 01:29:23 +08:00
ibuler
3d705dbeaa [Bugfix] 修复一些bug 2017-12-27 00:14:46 +08:00
ibuler
22b7b84a45 [Update] 修改创建默认集群,组等名称为Default 2017-12-26 22:14:37 +08:00
ibuler
6a6d0cf279 [Update] Change user model 2017-12-26 02:01:19 +08:00
ibuler
a39e0a1db9 [Docker] For docker update 2017-12-26 01:54:10 +08:00
ibuler
f4beccddae [Update] 修改注册流程 2017-12-25 12:22:49 +08:00
ibuler
8b081cd6b0 [Update] 修改 运行脚本 2017-12-25 00:36:14 +08:00
ibuler
209200dc4f [Update] 修改migrations 2017-12-24 23:23:05 +08:00
ibuler
d0ef1e715e [Add] Add initial migrations 2017-12-24 23:21:05 +08:00
ibuler
bf9bb1b973 [Update] 修改ops task运行 2017-12-24 18:53:07 +08:00
ibuler
30efec1b09 [Update] 修改 task 运行机制 2017-12-22 21:42:12 +08:00
ibuler
4893c4664d [Update] 修改task定时运行机制 2017-12-22 02:08:29 +08:00
ibuler
47040a61c8 [Bugfix] User first login 2017-12-21 19:33:16 +08:00
ibuler
da113b99af [Update] Remove IDE python version file 2017-12-21 19:30:18 +08:00
ibuler
146ddc3ee0 [Update] Remove docker file 2017-12-21 19:26:51 +08:00
ibuler
d33ae9d9d9 [Update] login add cookie test 2017-12-21 19:15:12 +08:00
ibuler
d51b3eff6a [Update] 修改settings和配置文件 2017-12-21 18:54:29 +08:00
ibuler
ec45c56868 [Change] 修改media地址 2017-12-21 16:04:24 +08:00
ibuler
e1b23a7cb4 [Bugfix] 修复无法记录日志的bug 2017-12-21 15:28:21 +08:00
ibuler
76df1de634 [Bugfix] 修复一些明显的bug 2017-12-21 11:31:13 +08:00
ibuler
5a92972120 [Bugfix] 修复ops一些功能的bug 2017-12-20 11:30:15 +08:00
ibuler
3f89701b84 [Bugfix] 修复授权和资产的一部分bug 2017-12-19 19:38:09 +08:00
ibuler
b0eace6ad8 [Bugfix] 基本完成assets模块 2017-12-19 12:41:00 +08:00
ibuler
b4e1ac1953 [Bugfix] 修复资产模块中一些bug 2017-12-18 22:48:19 +08:00
ibuler
a308000d2e [Bugfix] 修改users模块一些bug 2017-12-18 18:38:30 +08:00
ibuler
e1163895e2 [Update] 系统用户api允许app user获取 2017-12-16 17:21:30 +08:00
ibuler
2f638f5938 [Merge] 2017-12-16 17:18:16 +08:00
ibuler
1b6fd4d13a [Bugfix] 修改普通用户获取资产详情的bug 2017-12-16 17:16:40 +08:00
i317280
fb6a187639 feat: find a bug 2017-12-16 16:58:10 +08:00
ibuler
0f64d39cc5 Merge branch 'new_api' of github.com:jumpserver/jumpserver into new_api 2017-12-15 18:56:21 +08:00
ibuler
5e1eff19b7 [Change] Add terminal migrations force 2017-12-15 18:55:36 +08:00
ibuler
8da8c14ace [Update] 修改requirements 2017-12-15 18:53:21 +08:00
ibuler
6cee62696c [Feature] 翻译,并增加设置导航 2017-12-15 17:38:46 +08:00
ibuler
11fa3e08e9 [Bugfix] 修改ts_to_date bug 2017-12-15 17:08:22 +08:00
ibuler
2d0be8f996 [git status 2017-12-15 17:07:52 +08:00
ibuler
b97d5b0960 [Feature] assets task 修改 2017-12-15 15:50:15 +08:00
ibuler
08e1788426 [Feature] 打算拆分下载和上传为独立模块,时间有限暂时放弃 2017-12-14 21:27:14 +08:00
ibuler
160b01ec12 Merge branch 'new_api' into ops 2017-12-13 18:10:41 +08:00
ibuler
17ddb3bbbd [Feture] 使用信号解耦 2017-12-13 17:21:08 +08:00
liuzheng712
ef1bbc29b5 fix: update the terminal app 2017-12-13 00:34:04 +08:00
ibuler
ffa7e58025 [Bugfix] Terminal status报异常 2017-12-12 16:05:21 +08:00
ibuler
18fbfb449d [Feature] 修改url pattern 精确匹配uuid 2017-12-12 15:45:01 +08:00
ibuler
cb57002682 [Change] 去掉前端html中的hardcode 99991937 2017-12-12 14:38:51 +08:00
ibuler
722863428d [Feature] 添加context_processor 2017-12-12 14:28:12 +08:00
ibuler
99b4c66b5e [Feature] 添加signals 解耦代码 2017-12-12 12:19:45 +08:00
ibuler
cbc000696e [Feature] 修改adminuser systemuser cluster及他们的关系 2017-12-11 17:08:43 +08:00
ibuler
0c9e24dc59 [Feture] 添加ops 页面 2017-12-11 00:29:25 +08:00
ibuler
18fd04d63c [Stash] Test case 通不过,import error 2017-12-08 10:15:27 +08:00
ibuler
27a1849b1d [Change] 修改idc => cluster 2017-12-07 16:25:50 +08:00
ibuler
32fd9bb42f Merge branch 'new_api' into ops 2017-12-07 13:28:29 +08:00
ibuler
15f6d5c9c0 [Bugfix] terminal tasks main()运行时,可能数据库还不存在 2017-12-07 13:28:11 +08:00
ibuler
2b3551f1fc [Feature] 修改ansible和ops 2017-12-07 13:01:33 +08:00
ibuler
e57121a780 [Feature] 优化Ops ansible api 2017-12-06 18:31:51 +08:00
ibuler
ec8106e43d [Feature] 完成登陆日志 2017-12-05 12:24:31 +08:00
ibuler
a5f9735906 [Update] 更新index view 2017-12-04 20:15:47 +08:00
ibuler
71a3079221 [Feature] 离线session完成 2017-12-04 16:41:00 +08:00
ibuler
9b6696bb6e [Feture] session detail页面,包含命令列表 2017-12-04 00:21:26 +08:00
ibuler
01558c985a [Feture] 添加session 列表,并支持kill session 2017-12-03 20:42:36 +08:00
ibuler
bf8fa95597 [Update] 修改session 2017-12-01 21:22:32 +08:00
ibuler
94462bddb3 [Bugfix] 修改api view name 2017-12-01 17:55:19 +08:00
ibuler
1920a0f03d [Bugfix] 修改nav小bug 2017-12-01 17:37:46 +08:00
ibuler
f74422e4bb [Bugfix] 更改application models后导致 terminalstatus报错 2017-12-01 17:35:28 +08:00
ibuler
3120cef335 [Change] 修改导航列表 2017-12-01 17:29:57 +08:00
ibuler
61a8d95f46 [Change] Rename applications -> terminal 2017-12-01 17:28:47 +08:00
ibuler
19051d36dc [Update] 修改一些bug 2017-12-01 17:00:55 +08:00
ibuler
7910292e0f [Feature] 修改命令上传api 2017-11-29 19:27:04 +08:00
ibuler
26607bc327 [Copyright] 修改copyrite 2017-11-23 14:35:16 +08:00
ibuler
e7f38ec894 [Change] 全部使用uuid作为主键 2017-11-23 14:08:01 +08:00
ibuler
d80cbe270a [Update] 修改用户获取自己授权资产的api,和查询用户授权资产组等api的Url和结构 2017-11-23 11:26:17 +08:00
ibuler
818ead85ca [Feature] 增加上传replay log的api 2017-11-22 10:54:59 +08:00
ibuler
7f9ce57318 修改 terminal上报接口和api 2017-11-14 09:44:16 +08:00
ibuler
3639b190e3 Update perm api 2017-11-01 23:23:11 +08:00
ibuler
034f0a02b1 Update terminal api 2017-10-31 11:34:20 +08:00
ibuler
30c4fc9514 App user get user perms 2017-10-22 17:53:46 +08:00
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
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
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
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
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
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
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
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
ibuler
44c69ded78 干掉ldap前 2015-08-30 14:03:10 +08:00
root
1e170714c0 修改用户添加视图 2015-08-29 00:09:36 +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
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
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
ibuler
fdcaa358e5 modify some api.py bug 2015-06-13 00:36:10 +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
ibuler
e979c2753b modify 1 2015-06-08 23:46:40 +08:00
819 changed files with 58301 additions and 27177 deletions

7
.dockerignore Normal file
View File

@@ -0,0 +1,7 @@
.git
logs/*
data/*
.github
tmp/*
django.db
celerybeat.pid

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

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

71
.gitignore vendored
View File

@@ -1,43 +1,34 @@
*.py[cod]
.idea
test.py
# C extensions
*.so
# Packages
*.egg
*.egg-info
.DS_Store
*.pyc
*.pyo
*.swp
.env
env
env*
venv
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
__pycache__
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
*.egg
*.egg-info
_mailinglist
dump.rdb
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
node_modules
logs
keys
jumpserver.conf
nohup.out
.cache/
.idea/
db.sqlite3
config.py
migrations/
*.log
host_rsa_key
*.bat
tags
jumpserver.iml
.python-version
tmp/*
sessions/*
media
celerybeat.pid
django.db
celerybeat-schedule.db
data/static
docs/_build/

View File

@@ -1,4 +1,4 @@
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
@@ -336,4 +336,4 @@ 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.
Public License instead of this License.

View File

@@ -1,34 +1,61 @@
#欢迎使用Jumpserver
**Jumpserver**是一款由python编写开源的跳板机(堡垒机)系统,实现了跳板机应有的功能
## Jumpserver
[![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/)
----
> **统计管理** 统一管理用户
>
> **授权** 授权用户登录特定主机
>
> **审计** 审计用户操作
>
> **web管理** 漂亮的web管理界面
Jumpserver是全球首款完全开源的堡垒机使用GNU GPL v2.0开源协议,是符合 4A 的专业运维审计系统。
## 主要模块
#### 用户管理 ####
负责用户管理,添加用户,编辑用户,建立部门,建立用户组等
#### 资产管理 ####
负责资产管理添加资产编辑资产建立IDC建立用户组等
#### 授权管理 ####
负责授权用户登录某些特定主机授权sudo查看授权申请
#### 日志审计 ####
负责用户操作的审计,监控用户操作,统计用户操作记录,中断用户操作
#### 上传下载 ####
负责用户文件上传下载
Jumpserver使用Python / Django 进行开发,遵循 Web 2.0 规范,配备了业界领先的 Web Terminal 解决方案,交互界面美观、用户体验好。
[官网](http://www.jumpserver.org)
Jumpserver采纳分布式架构支持多机房跨区域部署中心节点提供 API各机房部署登录节点可横向扩展、无并发限制。
[demo站点](http://demo.jumpserver.org)
改变世界,从一点点开始。
[更新log](http://laoguang.blog.51cto.com/6013350/1635853)
----
[部署文档](http://laoguang.blog.51cto.com/6013350/1636273)
### 功能
- 统一认证
- 资产管理
- 统一授权
- 审计
- 支持LDAP认证
- Web terminal
- SSH Server
- 支持Windows RDP
### 开始使用
快速开始文档 [Docker安装](http://docs.jumpserver.org/zh/latest/quickstart.html)
一步一步安装文档 [详细部署](http://docs.jumpserver.org/zh/latest/step_by_step.html)
也可以查看我们完整文档包括了使用和开发 [文档](http://docs.jumpserver.org)
### Demo 和 截图
我们提供了DEMO和截图可以让你快速了解Jumpserver
[DEMO](http://demo.jumpserver.org)
[截图](http://docs.jumpserver.org/zh/docs/snapshot.html)
### SDK
我们还编写了一些SDK供你其它系统快速和Jumpserver APi交互
- [python](https://github.com/jumpserver/jumpserver-python-sdk) Jumpserver其它组件使用这个SDK完成交互
- [java](https://github.com/KaiJunYan/jumpserver-java-sdk.git) 恺珺同学提供的Java版本的SDK
### License & Copyright
Copyright (c) 2014-2018 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.

5
apps/__init__.py Normal file
View File

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

View File

@@ -0,0 +1,6 @@
from .admin_user import *
from .asset import *
from .label import *
from .system_user import *
from .node import *
from .domain import *

View File

@@ -0,0 +1,83 @@
# ~*~ coding: utf-8 ~*~
# Copyright (C) 2014-2018 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 django.db import transaction
from rest_framework import generics
from rest_framework.response import Response
from rest_framework_bulk import BulkModelViewSet
from common.mixins import IDInFilterMixin
from common.utils import get_logger
from ..hands import IsSuperUser
from ..models import AdminUser, Asset
from .. import serializers
from ..tasks import test_admin_user_connectability_manual
logger = get_logger(__file__)
__all__ = [
'AdminUserViewSet', 'ReplaceNodesAdminUserApi',
'AdminUserTestConnectiveApi', 'AdminUserAuthApi',
]
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 AdminUserAuthApi(generics.UpdateAPIView):
queryset = AdminUser.objects.all()
serializer_class = serializers.AdminUserAuthSerializer
permission_classes = (IsSuperUser,)
class ReplaceNodesAdminUserApi(generics.UpdateAPIView):
queryset = AdminUser.objects.all()
serializer_class = serializers.ReplaceNodeAdminUserSerializer
permission_classes = (IsSuperUser,)
def update(self, request, *args, **kwargs):
admin_user = self.get_object()
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
nodes = serializer.validated_data['nodes']
assets = []
for node in nodes:
assets.extend([asset.id for asset in node.get_all_assets()])
with transaction.atomic():
Asset.objects.filter(id__in=assets).update(admin_user=admin_user)
return Response({"msg": "ok"})
else:
return Response({'error': serializer.errors}, status=400)
class AdminUserTestConnectiveApi(generics.RetrieveAPIView):
"""
Test asset admin user connectivity
"""
queryset = AdminUser.objects.all()
permission_classes = (IsSuperUser,)
def retrieve(self, request, *args, **kwargs):
admin_user = self.get_object()
task = test_admin_user_connectability_manual.delay(admin_user)
return Response({"task": task.id})

107
apps/assets/api/asset.py Normal file
View File

@@ -0,0 +1,107 @@
# -*- coding: utf-8 -*-
#
from rest_framework import generics
from rest_framework.response import Response
from rest_framework_bulk import BulkModelViewSet
from rest_framework_bulk import ListBulkCreateUpdateDestroyAPIView
from rest_framework.pagination import LimitOffsetPagination
from django.shortcuts import get_object_or_404
from django.db.models import Q
from common.mixins import IDInFilterMixin
from common.utils import get_logger
from ..hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \
NodePermissionUtil
from ..models import Asset, SystemUser, AdminUser, Node
from .. import serializers
from ..tasks import update_asset_hardware_info_manual, \
test_asset_connectability_manual
from ..utils import LabelFilter
logger = get_logger(__file__)
__all__ = [
'AssetViewSet', 'UserAssetListView', 'AssetListUpdateApi',
'AssetRefreshHardwareApi', 'AssetAdminUserTestApi'
]
class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet):
"""
API endpoint that allows Asset to be viewed or edited.
"""
filter_fields = ("hostname", "ip")
search_fields = filter_fields
ordering_fields = ("hostname", "ip", "port", "cpu_cores")
queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer
pagination_class = LimitOffsetPagination
permission_classes = (IsSuperUserOrAppUser,)
def get_queryset(self):
queryset = super().get_queryset()
admin_user_id = self.request.query_params.get('admin_user_id')
node_id = self.request.query_params.get("node_id")
if admin_user_id:
admin_user = get_object_or_404(AdminUser, id=admin_user_id)
queryset = queryset.filter(admin_user=admin_user)
if node_id:
node = get_object_or_404(Node, id=node_id)
if not node.is_root():
queryset = queryset.filter(
nodes__key__regex='{}(:[0-9]+)*$'.format(node.key),
).distinct()
return queryset
class UserAssetListView(generics.ListAPIView):
queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer
permission_classes = (IsValidUser,)
def get_queryset(self):
assets_granted = NodePermissionUtil.get_user_assets(self.request.user).keys()
queryset = self.queryset.filter(
id__in=[asset.id for asset in assets_granted]
)
return queryset
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
"""
Asset bulk update api
"""
queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer
permission_classes = (IsSuperUser,)
class AssetRefreshHardwareApi(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)
task = update_asset_hardware_info_manual.delay(asset)
return Response({"task": task.id})
class AssetAdminUserTestApi(generics.RetrieveAPIView):
"""
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)
task = test_asset_connectability_manual.delay(asset)
return Response({"task": task.id})

55
apps/assets/api/domain.py Normal file
View File

@@ -0,0 +1,55 @@
# ~*~ coding: utf-8 ~*~
from rest_framework_bulk import BulkModelViewSet
from rest_framework.views import APIView, Response
from rest_framework.generics import RetrieveAPIView
from django.views.generic.detail import SingleObjectMixin
from common.utils import get_logger
from ..hands import IsSuperUser, IsSuperUserOrAppUser
from ..models import Domain, Gateway
from ..utils import test_gateway_connectability
from .. import serializers
logger = get_logger(__file__)
__all__ = ['DomainViewSet', 'GatewayViewSet', "GatewayTestConnectionApi"]
class DomainViewSet(BulkModelViewSet):
queryset = Domain.objects.all()
permission_classes = (IsSuperUser,)
serializer_class = serializers.DomainSerializer
def get_serializer_class(self):
if self.request.query_params.get('gateway'):
return serializers.DomainWithGatewaySerializer
return super().get_serializer_class()
def get_permissions(self):
if self.request.query_params.get('gateway'):
self.permission_classes = (IsSuperUserOrAppUser,)
return super().get_permissions()
class GatewayViewSet(BulkModelViewSet):
filter_fields = ("domain",)
search_fields = filter_fields
queryset = Gateway.objects.all()
permission_classes = (IsSuperUser,)
serializer_class = serializers.GatewaySerializer
class GatewayTestConnectionApi(SingleObjectMixin, APIView):
permission_classes = (IsSuperUser,)
model = Gateway
object = None
def get(self, request, *args, **kwargs):
self.object = self.get_object(Gateway.objects.all())
ok, e = test_gateway_connectability(self.object)
if ok:
return Response("ok")
else:
return Response({"failed": e}, status=404)

38
apps/assets/api/label.py Normal file
View File

@@ -0,0 +1,38 @@
# ~*~ coding: utf-8 ~*~
# Copyright (C) 2014-2018 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_bulk import BulkModelViewSet
from django.db.models import Count
from common.utils import get_logger
from ..hands import IsSuperUser
from ..models import Label
from .. import serializers
logger = get_logger(__file__)
__all__ = ['LabelViewSet']
class LabelViewSet(BulkModelViewSet):
queryset = Label.objects.annotate(asset_count=Count("assets"))
permission_classes = (IsSuperUser,)
serializer_class = serializers.LabelSerializer
def list(self, request, *args, **kwargs):
if request.query_params.get("distinct"):
self.serializer_class = serializers.LabelDistinctSerializer
self.queryset = self.queryset.values("name").distinct()
return super().list(request, *args, **kwargs)

231
apps/assets/api/node.py Normal file
View File

@@ -0,0 +1,231 @@
# ~*~ coding: utf-8 ~*~
# Copyright (C) 2014-2018 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, mixins
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_bulk import BulkModelViewSet
from django.utils.translation import ugettext_lazy as _
from django.shortcuts import get_object_or_404
from common.utils import get_logger, get_object_or_none
from ..hands import IsSuperUser
from ..models import Node
from ..tasks import update_assets_hardware_info_util, test_asset_connectability_util
from .. import serializers
logger = get_logger(__file__)
__all__ = [
'NodeViewSet', 'NodeChildrenApi',
'NodeAssetsApi', 'NodeWithAssetsApi',
'NodeAddAssetsApi', 'NodeRemoveAssetsApi',
'NodeReplaceAssetsApi',
'NodeAddChildrenApi', 'RefreshNodeHardwareInfoApi',
'TestNodeConnectiveApi'
]
class NodeViewSet(BulkModelViewSet):
queryset = Node.objects.all()
permission_classes = (IsSuperUser,)
serializer_class = serializers.NodeSerializer
def perform_create(self, serializer):
child_key = Node.root().get_next_child_key()
serializer.validated_data["key"] = child_key
serializer.save()
class NodeWithAssetsApi(generics.ListAPIView):
permission_classes = (IsSuperUser,)
serializers = serializers.NodeSerializer
def get_node(self):
pk = self.kwargs.get('pk') or self.request.query_params.get('node')
if not pk:
node = Node.root()
else:
node = get_object_or_404(Node, pk)
return node
def get_queryset(self):
queryset = []
node = self.get_node()
children = node.get_children()
assets = node.get_assets()
queryset.extend(list(children))
for asset in assets:
node = Node()
node.id = asset.id
node.parent = node.id
node.value = asset.hostname
queryset.append(node)
return queryset
class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
queryset = Node.objects.all()
permission_classes = (IsSuperUser,)
serializer_class = serializers.NodeSerializer
instance = None
def post(self, request, *args, **kwargs):
if not request.data.get("value"):
request.data["value"] = _("New node {}").format(
Node.root().get_next_child_key().split(":")[-1]
)
return super().post(request, *args, **kwargs)
def create(self, request, *args, **kwargs):
instance = self.get_object()
value = request.data.get("value")
node = instance.create_child(value=value)
return Response(
{"id": node.id, "key": node.key, "value": node.value},
status=201,
)
def get_object(self):
pk = self.kwargs.get('pk') or self.request.query_params.get('id')
if not pk:
node = Node.root()
else:
node = get_object_or_404(Node, pk=pk)
return node
def get_queryset(self):
queryset = []
query_all = self.request.query_params.get("all")
query_assets = self.request.query_params.get('assets')
node = self.get_object()
if node == Node.root():
queryset.append(node)
if query_all:
children = node.get_all_children()
else:
children = node.get_children()
queryset.extend(list(children))
if query_assets:
assets = node.get_assets()
for asset in assets:
node_fake = Node()
node_fake.id = asset.id
node_fake.parent = node
node_fake.value = asset.hostname
node_fake.is_asset = True
queryset.append(node_fake)
return queryset
def get(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
class NodeAssetsApi(generics.ListAPIView):
permission_classes = (IsSuperUser,)
serializer_class = serializers.AssetSerializer
def get_queryset(self):
node_id = self.kwargs.get('pk')
query_all = self.request.query_params.get('all')
instance = get_object_or_404(Node, pk=node_id)
if query_all:
return instance.get_all_assets()
else:
return instance.get_assets()
class NodeAddChildrenApi(generics.UpdateAPIView):
queryset = Node.objects.all()
permission_classes = (IsSuperUser,)
serializer_class = serializers.NodeAddChildrenSerializer
instance = None
def put(self, request, *args, **kwargs):
instance = self.get_object()
nodes_id = request.data.get("nodes")
children = [get_object_or_none(Node, id=pk) for pk in nodes_id]
for node in children:
if not node:
continue
node.parent = instance
node.save()
return Response("OK")
class NodeAddAssetsApi(generics.UpdateAPIView):
serializer_class = serializers.NodeAssetsSerializer
queryset = Node.objects.all()
permission_classes = (IsSuperUser,)
instance = None
def perform_update(self, serializer):
assets = serializer.validated_data.get('assets')
instance = self.get_object()
instance.assets.add(*tuple(assets))
class NodeRemoveAssetsApi(generics.UpdateAPIView):
serializer_class = serializers.NodeAssetsSerializer
queryset = Node.objects.all()
permission_classes = (IsSuperUser,)
instance = None
def perform_update(self, serializer):
assets = serializer.validated_data.get('assets')
instance = self.get_object()
if instance != Node.root():
instance.assets.remove(*tuple(assets))
class NodeReplaceAssetsApi(generics.UpdateAPIView):
serializer_class = serializers.NodeAssetsSerializer
queryset = Node.objects.all()
permission_classes = (IsSuperUser,)
instance = None
def perform_update(self, serializer):
assets = serializer.validated_data.get('assets')
instance = self.get_object()
for asset in assets:
asset.nodes.set([instance])
class RefreshNodeHardwareInfoApi(APIView):
permission_classes = (IsSuperUser,)
model = Node
def get(self, request, *args, **kwargs):
node_id = kwargs.get('pk')
node = get_object_or_404(self.model, id=node_id)
assets = node.assets.all()
task_name = _("更新节点资产硬件信息: {}".format(node.name))
task = update_assets_hardware_info_util.delay(assets, task_name=task_name)
return Response({"task": task.id})
class TestNodeConnectiveApi(APIView):
permission_classes = (IsSuperUser,)
model = Node
def get(self, request, *args, **kwargs):
node_id = kwargs.get('pk')
node = get_object_or_404(self.model, id=node_id)
assets = node.assets.all()
task_name = _("测试节点下资产是否可连接: {}".format(node.name))
task = test_asset_connectability_util.delay(assets, task_name=task_name)
return Response({"task": task.id})

View File

@@ -0,0 +1,75 @@
# ~*~ coding: utf-8 ~*~
# Copyright (C) 2014-2018 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 common.utils import get_logger
from ..hands import IsSuperUser, IsSuperUserOrAppUser
from ..models import SystemUser
from .. import serializers
from ..tasks import push_system_user_to_assets_manual, \
test_system_user_connectability_manual
logger = get_logger(__file__)
__all__ = [
'SystemUserViewSet', 'SystemUserAuthInfoApi',
'SystemUserPushApi', 'SystemUserTestConnectiveApi'
]
class SystemUserViewSet(BulkModelViewSet):
"""
System user api set, for add,delete,update,list,retrieve resource
"""
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserSerializer
permission_classes = (IsSuperUserOrAppUser,)
class SystemUserAuthInfoApi(generics.RetrieveUpdateAPIView):
"""
Get system user auth info
"""
queryset = SystemUser.objects.all()
permission_classes = (IsSuperUserOrAppUser,)
serializer_class = serializers.SystemUserAuthSerializer
class SystemUserPushApi(generics.RetrieveAPIView):
"""
Push system user to cluster assets api
"""
queryset = SystemUser.objects.all()
permission_classes = (IsSuperUser,)
def retrieve(self, request, *args, **kwargs):
system_user = self.get_object()
task = push_system_user_to_assets_manual.delay(system_user)
return Response({"task": task.id})
class SystemUserTestConnectiveApi(generics.RetrieveAPIView):
"""
Push system user to cluster assets api
"""
queryset = SystemUser.objects.all()
permission_classes = (IsSuperUser,)
def retrieve(self, request, *args, **kwargs):
system_user = self.get_object()
task = test_system_user_connectability_manual.delay(system_user)
return Response({"task": task.id})

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

@@ -0,0 +1,11 @@
from __future__ import unicode_literals
from django.apps import AppConfig
class AssetsConfig(AppConfig):
name = 'assets'
def ready(self):
from . import signals_handler
super().ready()

38
apps/assets/const.py Normal file
View File

@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
#
UPDATE_ASSETS_HARDWARE_TASKS = [
{
'name': "setup",
'action': {
'module': 'setup'
}
}
]
ADMIN_USER_CONN_CACHE_KEY = "ADMIN_USER_CONN_{}"
TEST_ADMIN_USER_CONN_TASKS = [
{
"name": "ping",
"action": {
"module": "ping",
}
}
]
ASSET_ADMIN_CONN_CACHE_KEY = "ASSET_ADMIN_USER_CONN_{}"
SYSTEM_USER_CONN_CACHE_KEY = "SYSTEM_USER_CONN_{}"
TEST_SYSTEM_USER_CONN_TASKS = [
{
"name": "ping",
"action": {
"module": "ping",
}
}
]
TASK_OPTIONS = {
'timeout': 10,
'forks': 10,
}

View File

@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
#
from .asset import *
from .label import *
from .user import *
from .domain import *

152
apps/assets/forms/asset.py Normal file
View File

@@ -0,0 +1,152 @@
# -*- coding: utf-8 -*-
#
from django import forms
from django.utils.translation import gettext_lazy as _
from ..models import Asset, AdminUser
from common.utils import get_logger
logger = get_logger(__file__)
__all__ = ['AssetCreateForm', 'AssetUpdateForm', 'AssetBulkUpdateForm']
class AssetCreateForm(forms.ModelForm):
class Meta:
model = Asset
fields = [
'hostname', 'ip', 'public_ip', 'port', 'comment',
'nodes', 'is_active', 'admin_user', 'labels', 'platform',
'domain',
]
widgets = {
'nodes': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Nodes')
}),
'admin_user': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Admin user')
}),
'labels': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Label')
}),
'port': forms.TextInput(),
'domain': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Domain')
}),
}
labels = {
'nodes': _("Node"),
}
help_texts = {
'hostname': '* required',
'ip': '* required',
'port': '* required',
'admin_user': _(
'root or other NOPASSWD sudo privilege user existed in asset,'
'If asset is windows or other set any one, more see admin user left menu'
),
'platform': _("* required Must set exact system platform, Windows, Linux ..."),
'domain': _("If your have some network not connect with each other, you can set domain")
}
class AssetUpdateForm(forms.ModelForm):
class Meta:
model = Asset
fields = [
'hostname', 'ip', 'port', 'nodes', 'is_active', 'platform',
'public_ip', 'number', 'comment', 'admin_user', 'labels',
'domain',
]
widgets = {
'nodes': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Node')
}),
'admin_user': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Admin user')
}),
'labels': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Label')
}),
'port': forms.TextInput(),
'domain': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Domain')
}),
}
labels = {
'nodes': _("Node"),
}
help_texts = {
'hostname': '* required',
'ip': '* required',
'port': '* required',
'cluster': '* required',
'admin_user': _(
'root or other NOPASSWD sudo privilege user existed in asset,'
'If asset is windows or other set any one, more see admin user left menu'
),
'platform': _("* required Must set exact system platform, Windows, Linux ..."),
'domain': _("If your have some network not connect with each other, you can set domain")
}
class AssetBulkUpdateForm(forms.ModelForm):
assets = forms.ModelMultipleChoiceField(
required=True, help_text='* required',
label=_('Select assets'), queryset=Asset.objects.all(),
widget=forms.SelectMultiple(
attrs={
'class': 'select2',
'data-placeholder': _('Select assets')
}
)
)
port = forms.IntegerField(
label=_('Port'), required=False, min_value=1, max_value=65535,
)
admin_user = forms.ModelChoiceField(
required=False, queryset=AdminUser.objects.all(),
label=_("Admin user"),
widget=forms.Select(
attrs={
'class': 'select2',
'data-placeholder': _('Admin user')
}
)
)
class Meta:
model = Asset
fields = [
'assets', 'port', 'admin_user', 'labels', 'nodes', 'platform'
]
widgets = {
'labels': forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Label')}
),
'nodes': forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Node')}
),
}
def save(self, commit=True):
changed_fields = []
for field in self._meta.fields:
if self.data.get(field) not in [None, '']:
changed_fields.append(field)
cleaned_data = {k: v for k, v in self.cleaned_data.items()
if k in changed_fields}
assets = cleaned_data.pop('assets')
labels = cleaned_data.pop('labels', [])
nodes = cleaned_data.pop('nodes')
assets = Asset.objects.filter(id__in=[asset.id for asset in assets])
assets.update(**cleaned_data)
if labels:
for label in labels:
label.assets.add(*tuple(assets))
if nodes:
for node in nodes:
node.assets.add(*tuple(assets))
return assets

View File

@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
#
from django import forms
from django.utils.translation import gettext_lazy as _
from ..models import Domain, Asset, Gateway
from .user import PasswordAndKeyAuthForm
__all__ = ['DomainForm', 'GatewayForm']
class DomainForm(forms.ModelForm):
assets = forms.ModelMultipleChoiceField(
queryset=Asset.objects.all(), label=_('Asset'), required=False,
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select assets')}
)
)
class Meta:
model = Domain
fields = ['name', 'comment', 'assets']
def __init__(self, *args, **kwargs):
if kwargs.get('instance', None):
initial = kwargs.get('initial', {})
initial['assets'] = kwargs['instance'].assets.all()
super().__init__(*args, **kwargs)
def save(self, commit=True):
instance = super().save(commit=commit)
assets = self.cleaned_data['assets']
instance.assets.set(assets)
return instance
class GatewayForm(PasswordAndKeyAuthForm):
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
instance = super().save()
password = self.cleaned_data.get('password')
private_key, public_key = super().gen_keys()
instance.set_auth(password=password, private_key=private_key)
return instance
class Meta:
model = Gateway
fields = [
'name', 'ip', 'port', 'username', 'protocol', 'domain', 'password',
'private_key_file', 'is_active', 'comment',
]
widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
}
help_texts = {
'name': '* required',
'username': '* required',
}

View File

@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
#
from django import forms
from django.utils.translation import gettext_lazy as _
from ..models import Label, Asset
__all__ = ['LabelForm']
class LabelForm(forms.ModelForm):
assets = forms.ModelMultipleChoiceField(
queryset=Asset.objects.all(), label=_('Asset'), required=False,
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select assets')}
)
)
class Meta:
model = Label
fields = ['name', 'value', 'assets']
def __init__(self, *args, **kwargs):
if kwargs.get('instance', None):
initial = kwargs.get('initial', {})
initial['assets'] = kwargs['instance'].assets.all()
super().__init__(*args, **kwargs)
def save(self, commit=True):
label = super().save(commit=commit)
assets = self.cleaned_data['assets']
label.assets.set(assets)
return label

128
apps/assets/forms/user.py Normal file
View File

@@ -0,0 +1,128 @@
# -*- coding: utf-8 -*-
#
from django import forms
from django.utils.translation import gettext_lazy as _
from ..models import AdminUser, SystemUser
from common.utils import validate_ssh_private_key, ssh_pubkey_gen, get_logger
logger = get_logger(__file__)
__all__ = [
'FileForm', 'SystemUserForm', 'AdminUserForm', 'PasswordAndKeyAuthForm',
]
class FileForm(forms.Form):
file = forms.FileField()
class PasswordAndKeyAuthForm(forms.ModelForm):
# Form field name can not start with `_`, so redefine it,
password = forms.CharField(
widget=forms.PasswordInput, max_length=128,
strip=True, required=False,
help_text=_('Password or private key passphrase'),
label=_("Password"),
)
# Need use upload private key file except paste private key content
private_key_file = forms.FileField(required=False, label=_("Private key"))
def clean_private_key_file(self):
private_key_file = self.cleaned_data['private_key_file']
password = self.cleaned_data['password']
if private_key_file:
key_string = private_key_file.read()
private_key_file.seek(0)
if not validate_ssh_private_key(key_string, password):
raise forms.ValidationError(_('Invalid private key'))
return private_key_file
def validate_password_key(self):
password = self.cleaned_data['password']
private_key_file = self.cleaned_data.get('private_key_file', '')
if not password and not private_key_file:
raise forms.ValidationError(_(
'Password and private key file must be input one'
))
def gen_keys(self):
password = self.cleaned_data.get('password', '') or None
private_key_file = self.cleaned_data['private_key_file']
public_key = private_key = None
if private_key_file:
private_key = private_key_file.read().strip().decode('utf-8')
public_key = ssh_pubkey_gen(private_key=private_key, password=password)
return private_key, public_key
class AdminUserForm(PasswordAndKeyAuthForm):
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
admin_user = super().save(commit=commit)
password = self.cleaned_data.get('password', '') or None
private_key, public_key = super().gen_keys()
admin_user.set_auth(password=password, public_key=public_key, private_key=private_key)
return admin_user
def clean(self):
super().clean()
if not self.instance:
super().validate_password_key()
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(PasswordAndKeyAuthForm):
# Admin user assets define, let user select, save it in form not in view
auto_generate_key = forms.BooleanField(initial=True, required=False)
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
system_user = super().save()
password = self.cleaned_data.get('password', '') or None
auto_generate_key = self.cleaned_data.get('auto_generate_key', False)
private_key, public_key = super().gen_keys()
if auto_generate_key:
logger.info('Auto generate key and set system user auth')
system_user.auto_gen_auth()
else:
system_user.set_auth(password=password, private_key=private_key, public_key=public_key)
return system_user
def clean(self):
super().clean()
auto_generate = self.cleaned_data.get('auto_generate_key')
if not self.instance and not auto_generate:
super().validate_password_key()
class Meta:
model = SystemUser
fields = [
'name', 'username', 'protocol', 'auto_generate_key',
'password', 'private_key_file', 'auto_push', 'sudo',
'comment', 'shell', 'priority',
]
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'),
'priority': _('High level will be using login asset as default, if user was granted more than 2 system user'),
}

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

@@ -0,0 +1,17 @@
"""
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-2018 by Jumpserver Team.
:license: GPL v2, see LICENSE for more details.
"""
from common.mixins import AdminUserRequiredMixin
from common.permissions import IsAppUser, IsSuperUser, IsValidUser, IsSuperUserOrAppUser
from users.models import User, UserGroup
from perms.utils import NodePermissionUtil

View File

@@ -0,0 +1,168 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-12-21 16:06
from __future__ import unicode_literals
import assets.models.utils
from django.db import migrations, models
import django.db.models.deletion
import uuid
def add_default_group(apps, schema_editor):
group_model = apps.get_model("assets", "AssetGroup")
db_alias = schema_editor.connection.alias
group_model.objects.using(db_alias).create(
name="Default"
)
def add_default_cluster(apps, schema_editor):
cluster_model = apps.get_model("assets", "Cluster")
db_alias = schema_editor.connection.alias
cluster_model.objects.using(db_alias).create(
name="Default"
)
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='AdminUser',
fields=[
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('name', models.CharField(max_length=128, unique=True, verbose_name='Name')),
('username', models.CharField(max_length=16, verbose_name='Username')),
('_password', models.CharField(blank=True, max_length=256, null=True, verbose_name='Password')),
('_private_key', models.TextField(blank=True, max_length=4096, null=True, validators=[assets.models.utils.private_key_validator], verbose_name='SSH private key')),
('_public_key', models.TextField(blank=True, max_length=4096, verbose_name='SSH public key')),
('comment', models.TextField(blank=True, verbose_name='Comment')),
('date_created', models.DateTimeField(auto_now_add=True)),
('date_updated', models.DateTimeField(auto_now=True)),
('created_by', models.CharField(max_length=32, null=True, verbose_name='Created by')),
('become', models.BooleanField(default=True)),
('become_method', models.CharField(choices=[('sudo', 'sudo'), ('su', 'su')], default='sudo', max_length=4)),
('become_user', models.CharField(default='root', max_length=64)),
('_become_pass', models.CharField(default='', max_length=128)),
],
options={
'ordering': ['name'],
},
),
migrations.CreateModel(
name='Asset',
fields=[
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('ip', models.GenericIPAddressField(db_index=True, verbose_name='IP')),
('hostname', models.CharField(max_length=128, unique=True, verbose_name='Hostname')),
('port', models.IntegerField(default=22, verbose_name='Port')),
('is_active', models.BooleanField(default=True, verbose_name='Is active')),
('type', models.CharField(blank=True, choices=[('Server', 'Server'), ('VM', 'VM'), ('Switch', 'Switch'), ('Router', 'Router'), ('Firewall', 'Firewall'), ('Storage', 'Storage')], default='Server', max_length=16, null=True, verbose_name='Asset type')),
('env', models.CharField(blank=True, choices=[('Prod', 'Production'), ('Dev', 'Development'), ('Test', 'Testing')], default='Prod', max_length=8, null=True, verbose_name='Asset environment')),
('status', models.CharField(blank=True, choices=[('In use', 'In use'), ('Out of use', 'Out of use')], default='In use', max_length=12, null=True, verbose_name='Asset status')),
('public_ip', models.GenericIPAddressField(blank=True, null=True, verbose_name='Public IP')),
('remote_card_ip', models.CharField(blank=True, max_length=16, null=True, verbose_name='Remote control card IP')),
('cabinet_no', models.CharField(blank=True, max_length=32, null=True, verbose_name='Cabinet number')),
('cabinet_pos', models.IntegerField(blank=True, null=True, verbose_name='Cabinet position')),
('number', models.CharField(blank=True, max_length=32, null=True, verbose_name='Asset number')),
('vendor', models.CharField(blank=True, max_length=64, null=True, verbose_name='Vendor')),
('model', models.CharField(blank=True, max_length=54, null=True, verbose_name='Model')),
('sn', models.CharField(blank=True, max_length=128, null=True, verbose_name='Serial number')),
('cpu_model', models.CharField(blank=True, max_length=64, null=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(blank=True, max_length=64, null=True, verbose_name='Memory')),
('disk_total', models.CharField(blank=True, max_length=1024, null=True, verbose_name='Disk total')),
('disk_info', models.CharField(blank=True, max_length=1024, null=True, verbose_name='Disk info')),
('platform', models.CharField(blank=True, max_length=128, null=True, verbose_name='Platform')),
('os', models.CharField(blank=True, max_length=128, null=True, verbose_name='OS')),
('os_version', models.CharField(blank=True, max_length=16, null=True, verbose_name='OS version')),
('os_arch', models.CharField(blank=True, max_length=16, null=True, verbose_name='OS arch')),
('hostname_raw', models.CharField(blank=True, max_length=128, null=True, verbose_name='Hostname raw')),
('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')),
('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')),
('comment', models.TextField(blank=True, default='', max_length=128, verbose_name='Comment')),
('admin_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.AdminUser', verbose_name='Admin user')),
],
),
migrations.CreateModel(
name='AssetGroup',
fields=[
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('name', models.CharField(max_length=64, unique=True, verbose_name='Name')),
('created_by', models.CharField(blank=True, max_length=32, 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')),
],
options={
'ordering': ['name'],
},
),
migrations.CreateModel(
name='Cluster',
fields=[
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('name', models.CharField(max_length=32, verbose_name='Name')),
('bandwidth', models.CharField(blank=True, max_length=32, verbose_name='Bandwidth')),
('contact', models.CharField(blank=True, max_length=128, verbose_name='Contact')),
('phone', models.CharField(blank=True, max_length=32, verbose_name='Phone')),
('address', models.CharField(blank=True, max_length=128, 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(blank=True, max_length=32, verbose_name='Operator')),
('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
('comment', models.TextField(blank=True, verbose_name='Comment')),
('admin_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.AdminUser', verbose_name='Admin user')),
],
options={
'ordering': ['name'],
},
),
migrations.CreateModel(
name='SystemUser',
fields=[
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('name', models.CharField(max_length=128, unique=True, verbose_name='Name')),
('username', models.CharField(max_length=16, verbose_name='Username')),
('_password', models.CharField(blank=True, max_length=256, null=True, verbose_name='Password')),
('_private_key', models.TextField(blank=True, max_length=4096, null=True, validators=[assets.models.utils.private_key_validator], verbose_name='SSH private key')),
('_public_key', models.TextField(blank=True, max_length=4096, verbose_name='SSH public key')),
('comment', models.TextField(blank=True, verbose_name='Comment')),
('date_created', models.DateTimeField(auto_now_add=True)),
('date_updated', models.DateTimeField(auto_now=True)),
('created_by', models.CharField(max_length=32, null=True, verbose_name='Created by')),
('priority', models.IntegerField(default=10, verbose_name='Priority')),
('protocol', models.CharField(choices=[('ssh', 'ssh')], default='ssh', max_length=16, verbose_name='Protocol')),
('auto_push', models.BooleanField(default=True, verbose_name='Auto push')),
('sudo', models.TextField(default='/sbin/ifconfig', verbose_name='Sudo')),
('shell', models.CharField(default='/bin/bash', max_length=64, verbose_name='Shell')),
('cluster', models.ManyToManyField(blank=True, to='assets.Cluster', verbose_name='Cluster')),
],
options={
'ordering': ['name'],
},
),
migrations.AddField(
model_name='asset',
name='cluster',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='assets', to='assets.Cluster', verbose_name='Cluster'),
),
migrations.AddField(
model_name='asset',
name='groups',
field=models.ManyToManyField(blank=True, related_name='assets', to='assets.AssetGroup', verbose_name='Asset groups'),
),
migrations.AlterUniqueTogether(
name='asset',
unique_together=set([('ip', 'port')]),
),
migrations.RunPython(add_default_cluster),
migrations.RunPython(add_default_group),
]

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from .user import AdminUser, SystemUser
from .label import Label
from .cluster import *
from .group import *
from .domain import *
from .node import *
from .asset import *
from .utils import *

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

@@ -0,0 +1,190 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import uuid
import logging
import random
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.core.cache import cache
from ..const import ASSET_ADMIN_CONN_CACHE_KEY
from .user import AdminUser, SystemUser
__all__ = ['Asset']
logger = logging.getLogger(__name__)
def default_cluster():
from .cluster import Cluster
name = "Default"
defaults = {"name": name}
cluster, created = Cluster.objects.get_or_create(
defaults=defaults, name=name
)
return cluster.id
def default_node():
try:
from .node import Node
return Node.root()
except:
return None
class Asset(models.Model):
# Important
PLATFORM_CHOICES = (
('Linux', 'Linux'),
('Unix', 'Unix'),
('MacOS', 'MacOS'),
('BSD', 'BSD'),
('Windows', 'Windows'),
('Other', 'Other'),
)
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
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'))
platform = models.CharField(max_length=128, choices=PLATFORM_CHOICES, default='Linux', verbose_name=_('Platform'))
domain = models.ForeignKey("assets.Domain", null=True, blank=True, related_name='assets', verbose_name=_("Domain"), on_delete=models.SET_NULL)
nodes = models.ManyToManyField('assets.Node', default=default_node, related_name='assets', verbose_name=_("Nodes"))
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
# Auth
admin_user = models.ForeignKey('assets.AdminUser', on_delete=models.PROTECT, null=True, verbose_name=_("Admin user"))
# Some information
public_ip = models.GenericIPAddressField(max_length=32, blank=True, null=True, verbose_name=_('Public IP'))
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'))
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'))
labels = models.ManyToManyField('assets.Label', blank=True, related_name='assets', verbose_name=_("Labels"))
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 __str__(self):
return '{0.hostname}({0.ip})'.format(self)
@property
def is_valid(self):
warning = ''
if not self.is_active:
warning += ' inactive'
else:
return True, ''
return False, warning
def is_unixlike(self):
if self.platform not in ("Windows",):
return True
else:
return False
def get_nodes(self):
from .node import Node
return self.nodes.all() or [Node.root()]
@property
def hardware_info(self):
if self.cpu_count:
return '{} Core {} {}'.format(
self.cpu_count * self.cpu_cores,
self.memory, self.disk_total
)
else:
return ''
@property
def is_connective(self):
if not self.is_unixlike():
return True
val = cache.get(ASSET_ADMIN_CONN_CACHE_KEY.format(self.hostname))
if val == 1:
return True
else:
return False
def to_json(self):
info = {
'id': self.id,
'hostname': self.hostname,
'ip': self.ip,
'port': self.port,
}
if self.domain and self.domain.gateway_set.all():
info["gateways"] = [d.id for d in self.domain.gateway_set.all()]
return info
def get_auth_info(self):
if self.admin_user:
return {
'username': self.admin_user.username,
'password': self.admin_user.password,
'private_key': self.admin_user.private_key_file,
'become': self.admin_user.become_info,
}
def _to_secret_json(self):
"""
Ansible use it create inventory, First using asset user,
otherwise using cluster admin user
Todo: May be move to ops implements it
"""
data = self.to_json()
if self.admin_user:
admin_user = self.admin_user
data.update({
'username': admin_user.username,
'password': admin_user.password,
'private_key': admin_user.private_key_file,
'become': admin_user.become_info,
'groups': [node.value for node in self.nodes.all()],
})
return data
class Meta:
unique_together = ('ip', 'port')
verbose_name = _("Asset")
@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()),
port=22,
created_by='Fake')
try:
asset.save()
asset.system_users = [choice(SystemUser.objects.all()) for i in range(3)]
logger.debug('Generate fake asset : %s' % asset.ip)
except IntegrityError:
print('Error continue')
continue

126
apps/assets/models/base.py Normal file
View File

@@ -0,0 +1,126 @@
# -*- coding: utf-8 -*-
#
import os
import uuid
from hashlib import md5
import sshpubkeys
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from common.utils import get_signer, ssh_key_string_to_obj, ssh_key_gen
from .utils import private_key_validator
signer = get_signer()
class AssetUser(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
username = models.CharField(max_length=128, 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, ])
_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)
date_updated = models.DateTimeField(auto_now=True)
created_by = models.CharField(max_length=128, null=True, verbose_name=_('Created by'))
@property
def password(self):
if self._password:
return signer.unsign(self._password)
else:
return None
@password.setter
def password(self, password_raw):
raise AttributeError("Using set_auth do that")
# self._password = signer.sign(password_raw)
@property
def private_key(self):
if self._private_key:
return signer.unsign(self._private_key)
@private_key.setter
def private_key(self, private_key_raw):
raise AttributeError("Using set_auth do that")
# self._private_key = signer.sign(private_key_raw)
@property
def private_key_obj(self):
if self._private_key:
key_str = signer.unsign(self._private_key)
return ssh_key_string_to_obj(key_str, password=self.password)
else:
return None
@property
def private_key_file(self):
if not self.private_key_obj:
return None
project_dir = settings.PROJECT_DIR
tmp_dir = os.path.join(project_dir, 'tmp')
key_str = signer.unsign(self._private_key)
key_name = '.' + md5(key_str.encode('utf-8')).hexdigest()
key_path = os.path.join(tmp_dir, key_name)
if not os.path.exists(key_path):
self.private_key_obj.write_private_key_file(key_path)
os.chmod(key_path, 0o400)
return key_path
@property
def public_key(self):
key = signer.unsign(self._public_key)
if key:
return key
else:
return None
@property
def public_key_obj(self):
if self.public_key:
try:
return sshpubkeys.SSHKey(self.public_key)
except TabError:
pass
return None
def set_auth(self, password=None, private_key=None, public_key=None):
update_fields = []
if password:
self._password = signer.sign(password)
update_fields.append('_password')
if private_key:
self._private_key = signer.sign(private_key)
update_fields.append('_private_key')
if public_key:
self._public_key = signer.sign(public_key)
update_fields.append('_public_key')
if update_fields:
self.save(update_fields=update_fields)
def auto_gen_auth(self):
password = str(uuid.uuid4())
private_key, public_key = ssh_key_gen(
username=self.name, password=password
)
self.set_auth(password=password,
private_key=private_key,
public_key=public_key)
def _to_secret_json(self):
"""Push system user use it"""
return {
'name': self.name,
'username': self.username,
'password': self.password,
'public_key': self.public_key,
'private_key': self.private_key_file,
}
class Meta:
abstract = True

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import logging
import uuid
from django.db import models
from django.utils.translation import ugettext_lazy as _
__all__ = ['Cluster']
logger = logging.getLogger(__name__)
class Cluster(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=32, verbose_name=_('Name'))
admin_user = models.ForeignKey('assets.AdminUser', null=True, blank=True, on_delete=models.SET_NULL, verbose_name=_("Admin user"))
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 __str__(self):
return self.name
@classmethod
def initial(cls):
return cls.objects.get_or_create(name=_('Default'), created_by=_('System'), comment=_('Default Cluster'))[0]
class Meta:
ordering = ['name']
verbose_name = _("Cluster")
@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):
cluster = 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:
cluster.save()
logger.debug('Generate fake asset group: %s' % cluster.name)
except IntegrityError:
print('Error continue')
continue

View File

@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
#
import uuid
import random
from django.db import models
from django.utils.translation import ugettext_lazy as _
from .base import AssetUser
__all__ = ['Domain', 'Gateway']
class Domain(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
comment = models.TextField(blank=True, verbose_name=_('Comment'))
date_created = models.DateTimeField(auto_now_add=True, null=True,
verbose_name=_('Date created'))
def __str__(self):
return self.name
def has_gateway(self):
return self.gateway_set.filter(is_active=True).exists()
@property
def gateways(self):
return self.gateway_set.filter(is_active=True)
def random_gateway(self):
return random.choice(self.gateways)
class Gateway(AssetUser):
SSH_PROTOCOL = 'ssh'
RDP_PROTOCOL = 'rdp'
PROTOCOL_CHOICES = (
(SSH_PROTOCOL, 'ssh'),
(RDP_PROTOCOL, 'rdp'),
)
ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True)
port = models.IntegerField(default=22, verbose_name=_('Port'))
protocol = models.CharField(choices=PROTOCOL_CHOICES, max_length=16, default=SSH_PROTOCOL, verbose_name=_("Protocol"))
domain = models.ForeignKey(Domain, verbose_name=_("Domain"))
comment = models.CharField(max_length=128, blank=True, null=True, verbose_name=_("Comment"))
is_active = models.BooleanField(default=True, verbose_name=_("Is active"))
def __str__(self):
return self.name

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
import uuid
from django.db import models
import logging
from django.utils.translation import ugettext_lazy as _
__all__ = ['AssetGroup']
logger = logging.getLogger(__name__)
class AssetGroup(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=64, unique=True, verbose_name=_('Name'))
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, verbose_name=_('Date created'))
comment = models.TextField(blank=True, verbose_name=_('Comment'))
def __str__(self):
return self.name
class Meta:
ordering = ['name']
verbose_name = _("Asset group")
@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

View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
#
import uuid
from django.db import models
from django.utils.translation import ugettext_lazy as _
class Label(models.Model):
SYSTEM_CATEGORY = "S"
USER_CATEGORY = "U"
CATEGORY_CHOICES = (
("S", _("System")),
("U", _("User"))
)
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, verbose_name=_("Name"))
value = models.CharField(max_length=128, verbose_name=_("Value"))
category = models.CharField(max_length=128, choices=CATEGORY_CHOICES, default=USER_CATEGORY, verbose_name=_("Category"))
is_active = models.BooleanField(default=True, verbose_name=_("Is active"))
comment = models.TextField(blank=True, null=True, verbose_name=_("Comment"))
date_created = models.DateTimeField(
auto_now_add=True, null=True, blank=True, verbose_name=_('Date created')
)
@classmethod
def get_queryset_group_by_name(cls):
names = cls.objects.values_list('name', flat=True)
for name in names:
yield name, cls.objects.filter(name=name)
def __str__(self):
return "{}:{}".format(self.name, self.value)
class Meta:
db_table = "assets_label"
unique_together = ('name', 'value')

124
apps/assets/models/node.py Normal file
View File

@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
#
import uuid
from django.db import models
from django.utils.translation import ugettext_lazy as _
__all__ = ['Node']
class Node(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
key = models.CharField(unique=True, max_length=64, verbose_name=_("Key")) # '1:1:1:1'
value = models.CharField(max_length=128, unique=True, verbose_name=_("Value"))
child_mark = models.IntegerField(default=0)
date_create = models.DateTimeField(auto_now_add=True)
is_asset = False
def __str__(self):
return self.full_value
@property
def name(self):
return self.value
@property
def full_value(self):
if self == self.__class__.root():
return self.value
else:
return '{} / {}'.format(self.parent.full_value, self.value)
@property
def level(self):
return len(self.key.split(':'))
def get_next_child_key(self):
mark = self.child_mark
self.child_mark += 1
self.save()
return "{}:{}".format(self.key, mark)
def create_child(self, value):
child_key = self.get_next_child_key()
child = self.__class__.objects.create(key=child_key, value=value)
return child
def get_children(self):
return self.__class__.objects.filter(key__regex=r'{}:[0-9]+$'.format(self.key))
def get_all_children(self):
return self.__class__.objects.filter(key__startswith='{}:'.format(self.key))
def get_family(self):
children = list(self.get_all_children())
children.append(self)
return children
def get_assets(self):
from .asset import Asset
assets = Asset.objects.filter(nodes__id=self.id)
return assets
def get_active_assets(self):
return self.get_assets().filter(is_active=True)
def get_all_assets(self):
from .asset import Asset
if self.is_root():
assets = Asset.objects.all()
else:
nodes = self.get_family()
assets = Asset.objects.filter(nodes__in=nodes).distinct()
return assets
def has_assets(self):
return self.get_all_assets()
def get_all_active_assets(self):
return self.get_all_assets().filter(is_active=True)
def is_root(self):
return self.key == '0'
@property
def parent(self):
if self.key == "0":
return self.__class__.root()
elif not self.key.startswith("0"):
return self.__class__.root()
parent_key = ":".join(self.key.split(":")[:-1])
try:
parent = self.__class__.objects.get(key=parent_key)
except Node.DoesNotExist:
return self.__class__.root()
else:
return parent
@parent.setter
def parent(self, parent):
self.key = parent.get_next_child_key()
@property
def ancestor(self):
if self.parent == self.__class__.root():
return [self.__class__.root()]
else:
return [self.parent, *tuple(self.parent.ancestor)]
@property
def ancestor_with_node(self):
ancestor = self.ancestor
ancestor.insert(0, self)
return ancestor
@classmethod
def root(cls):
obj, created = cls.objects.get_or_create(
key='0', defaults={"key": '0', 'value': "ROOT"}
)
return obj

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

@@ -0,0 +1,169 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import logging
import uuid
from django.core.cache import cache
from django.db import models
from django.utils.translation import ugettext_lazy as _
from common.utils import get_signer
from ..const import SYSTEM_USER_CONN_CACHE_KEY
from .base import AssetUser
__all__ = ['AdminUser', 'SystemUser',]
logger = logging.getLogger(__name__)
signer = get_signer()
class AdminUser(AssetUser):
"""
A privileged user that ansible can use it to push system user and so on
"""
BECOME_METHOD_CHOICES = (
('sudo', 'sudo'),
('su', 'su'),
)
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)
def __str__(self):
return self.name
@property
def become_pass(self):
password = signer.unsign(self._become_pass)
if password:
return password
else:
return ""
@become_pass.setter
def become_pass(self, password):
self._become_pass = signer.sign(password)
@property
def become_info(self):
if self.become:
info = {
"method": self.become_method,
"user": self.become_user,
"pass": self.become_pass,
}
else:
info = None
return info
def get_related_assets(self):
assets = self.asset_set.all()
return assets
@property
def assets_amount(self):
return self.get_related_assets().count()
class Meta:
ordering = ['name']
verbose_name = _("Admin user")
@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(AssetUser):
SSH_PROTOCOL = 'ssh'
RDP_PROTOCOL = 'rdp'
PROTOCOL_CHOICES = (
(SSH_PROTOCOL, 'ssh'),
(RDP_PROTOCOL, 'rdp'),
)
nodes = models.ManyToManyField('assets.Node', blank=True, verbose_name=_("Nodes"))
assets = models.ManyToManyField('assets.Asset', blank=True, verbose_name=_("Assets"))
priority = models.IntegerField(default=10, verbose_name=_("Priority"))
protocol = models.CharField(max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol'))
auto_push = models.BooleanField(default=True, verbose_name=_('Auto push'))
sudo = models.TextField(default='/bin/whoami', verbose_name=_('Sudo'))
shell = models.CharField(max_length=64, default='/bin/bash', verbose_name=_('Shell'))
def __str__(self):
return '{0.name}({0.username})'.format(self)
def to_json(self):
return {
'id': self.id,
'name': self.name,
'username': self.username,
'protocol': self.protocol,
'priority': self.priority,
'auto_push': self.auto_push,
}
def get_assets(self):
assets = set(self.assets.all())
return assets
@property
def assets_connective(self):
_result = cache.get(SYSTEM_USER_CONN_CACHE_KEY.format(self.name), {})
return _result
@property
def unreachable_assets(self):
return list(self.assets_connective.get('dark', {}).keys())
@property
def reachable_assets(self):
return self.assets_connective.get('contacted', [])
def is_need_push(self):
if self.auto_push and self.protocol == self.__class__.SSH_PROTOCOL:
return True
else:
return False
class Meta:
ordering = ['name']
verbose_name = _("System user")
@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,35 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from django.core.exceptions import ValidationError
from common.utils import validate_ssh_private_key
__all__ = ['init_model', 'generate_fake']
def init_model():
from . import SystemUser, AdminUser, Asset
for cls in [SystemUser, AdminUser, Asset]:
if hasattr(cls, 'initial'):
cls.initial()
def generate_fake():
from . import SystemUser, AdminUser, Asset
for cls in [SystemUser, AdminUser, Asset]:
if hasattr(cls, 'generate_fake'):
cls.generate_fake()
def private_key_validator(value):
if not validate_ssh_private_key(value):
raise ValidationError(
_('%(value)s is not an even number'),
params={'value': value},
)
if __name__ == '__main__':
pass

View File

@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
#
from .asset import *
from .admin_user import *
from .label import *
from .system_user import *
from .node import *
from .domain import *

View File

@@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
#
from django.core.cache import cache
from rest_framework import serializers
from ..models import Node, AdminUser
from ..const import ADMIN_USER_CONN_CACHE_KEY
from .base import AuthSerializer
class AdminUserSerializer(serializers.ModelSerializer):
"""
管理用户
"""
assets_amount = serializers.SerializerMethodField()
unreachable_amount = serializers.SerializerMethodField()
reachable_amount = serializers.SerializerMethodField()
class Meta:
model = AdminUser
fields = '__all__'
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
return [f for f in fields if not f.startswith('_')]
@staticmethod
def get_unreachable_amount(obj):
data = cache.get(ADMIN_USER_CONN_CACHE_KEY.format(obj.name))
if data:
return len(data.get('dark'))
else:
return 0
@staticmethod
def get_reachable_amount(obj):
data = cache.get(ADMIN_USER_CONN_CACHE_KEY.format(obj.name))
if data:
return len(data.get('contacted'))
else:
return 0
@staticmethod
def get_assets_amount(obj):
return obj.assets_amount
class AdminUserAuthSerializer(AuthSerializer):
class Meta:
model = AdminUser
fields = ['password', 'private_key']
class ReplaceNodeAdminUserSerializer(serializers.ModelSerializer):
"""
管理用户更新关联到的集群
"""
nodes = serializers.PrimaryKeyRelatedField(
many=True, queryset=Node.objects.all()
)
class Meta:
model = AdminUser
fields = ['id', 'nodes']

View File

@@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from rest_framework_bulk.serializers import BulkListSerializer
from common.mixins import BulkSerializerMixin
from ..models import Asset
from .system_user import AssetSystemUserSerializer
class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
"""
资产的数据结构
"""
class Meta:
model = Asset
list_serializer_class = BulkListSerializer
fields = '__all__'
validators = [] # If not set to [], partial bulk update will be error
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend([
'hardware_info', 'is_connective',
])
return fields
class AssetGrantedSerializer(serializers.ModelSerializer):
"""
被授权资产的数据结构
"""
system_users_granted = AssetSystemUserSerializer(many=True, read_only=True)
system_users_join = serializers.SerializerMethodField()
class Meta:
model = Asset
fields = (
"id", "hostname", "ip", "port", "system_users_granted",
"is_active", "system_users_join", "os", 'domain',
"platform", "comment"
)
@staticmethod
def get_system_users_join(obj):
system_users = [s.username for s in obj.system_users_granted]
return ', '.join(system_users)
class MyAssetGrantedSerializer(AssetGrantedSerializer):
"""
普通用户获取授权的资产定义的数据结构
"""
class Meta:
model = Asset
fields = (
"id", "hostname", "system_users_granted",
"is_active", "system_users_join",
"os", "platform", "comment",
)

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from common.utils import ssh_pubkey_gen
class AuthSerializer(serializers.ModelSerializer):
password = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=1024)
private_key = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=4096)
def gen_keys(self, private_key=None, password=None):
if private_key is None:
return None, None
public_key = ssh_pubkey_gen(private_key=private_key, password=password)
return private_key, public_key
def save(self, **kwargs):
password = self.validated_data.pop('password', None) or None
private_key = self.validated_data.pop('private_key', None) or None
self.instance = super().save(**kwargs)
if password or private_key:
private_key, public_key = self.gen_keys(private_key, password)
self.instance.set_auth(password=password, private_key=private_key,
public_key=public_key)
return self.instance

View File

@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from ..models import Domain, Gateway
class DomainSerializer(serializers.ModelSerializer):
asset_count = serializers.SerializerMethodField()
gateway_count = serializers.SerializerMethodField()
class Meta:
model = Domain
fields = '__all__'
@staticmethod
def get_asset_count(obj):
return obj.assets.count()
@staticmethod
def get_gateway_count(obj):
return obj.gateway_set.all().count()
class GatewaySerializer(serializers.ModelSerializer):
class Meta:
model = Gateway
fields = [
'id', 'name', 'ip', 'port', 'protocol', 'username',
'domain', 'is_active', 'date_created', 'date_updated',
'created_by', 'comment',
]
class GatewayWithAuthSerializer(GatewaySerializer):
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend(
['password', 'private_key']
)
return fields
class DomainWithGatewaySerializer(serializers.ModelSerializer):
gateways = GatewayWithAuthSerializer(many=True, read_only=True)
class Meta:
model = Domain
fields = '__all__'

View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from rest_framework_bulk.serializers import BulkListSerializer
from ..models import Label
class LabelSerializer(serializers.ModelSerializer):
asset_count = serializers.SerializerMethodField()
class Meta:
model = Label
fields = '__all__'
list_serializer_class = BulkListSerializer
@staticmethod
def get_asset_count(obj):
return obj.assets.count()
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend(['get_category_display'])
return fields
class LabelDistinctSerializer(serializers.ModelSerializer):
value = serializers.SerializerMethodField()
class Meta:
model = Label
fields = ("name", "value")
@staticmethod
def get_value(obj):
labels = Label.objects.filter(name=obj["name"])
return ', '.join([label.value for label in labels])

View File

@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
from rest_framework import serializers
from rest_framework_bulk.serializers import BulkListSerializer
from common.mixins import BulkSerializerMixin
from ..models import Asset, Node
from .asset import AssetGrantedSerializer
class NodeGrantedSerializer(BulkSerializerMixin, serializers.ModelSerializer):
"""
授权资产组
"""
assets_granted = AssetGrantedSerializer(many=True, read_only=True)
assets_amount = serializers.SerializerMethodField()
parent = serializers.SerializerMethodField()
name = serializers.SerializerMethodField()
class Meta:
model = Node
fields = [
'id', 'key', 'name', 'value', 'parent',
'assets_granted', 'assets_amount',
]
@staticmethod
def get_assets_amount(obj):
return len(obj.assets_granted)
@staticmethod
def get_name(obj):
return obj.name
@staticmethod
def get_parent(obj):
return obj.parent.id
class NodeSerializer(serializers.ModelSerializer):
parent = serializers.SerializerMethodField()
assets_amount = serializers.SerializerMethodField()
class Meta:
model = Node
fields = ['id', 'key', 'value', 'parent', 'assets_amount', 'is_asset']
list_serializer_class = BulkListSerializer
@staticmethod
def get_parent(obj):
return obj.parent.id
@staticmethod
def get_assets_amount(obj):
return obj.get_all_assets().count()
def get_fields(self):
fields = super().get_fields()
field = fields["key"]
field.required = False
return fields
class NodeAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = Node
fields = ['assets']
class NodeAddChildrenSerializer(serializers.Serializer):
nodes = serializers.ListField()

View File

@@ -0,0 +1,68 @@
from rest_framework import serializers
from ..models import SystemUser
from .base import AuthSerializer
class SystemUserSerializer(serializers.ModelSerializer):
"""
系统用户
"""
unreachable_amount = serializers.SerializerMethodField()
reachable_amount = serializers.SerializerMethodField()
unreachable_assets = serializers.SerializerMethodField()
reachable_assets = serializers.SerializerMethodField()
assets_amount = serializers.SerializerMethodField()
class Meta:
model = SystemUser
exclude = ('_password', '_private_key', '_public_key')
@staticmethod
def get_unreachable_assets(obj):
return obj.unreachable_assets
@staticmethod
def get_reachable_assets(obj):
return obj.reachable_assets
def get_unreachable_amount(self, obj):
return len(self.get_unreachable_assets(obj))
def get_reachable_amount(self, obj):
return len(self.get_reachable_assets(obj))
@staticmethod
def get_assets_amount(obj):
return len(obj.get_assets())
class SystemUserAuthSerializer(AuthSerializer):
"""
系统用户认证信息
"""
class Meta:
model = SystemUser
fields = [
"id", "name", "username", "protocol",
"password", "private_key",
]
class AssetSystemUserSerializer(serializers.ModelSerializer):
"""
查看授权的资产系统用户的数据结构这个和AssetSerializer不同字段少
"""
class Meta:
model = SystemUser
fields = ('id', 'name', 'username', 'priority', 'protocol', 'comment',)
class SystemUserSimpleSerializer(serializers.ModelSerializer):
"""
系统用户最基本信息的数据结构
"""
class Meta:
model = SystemUser
fields = ('id', 'name', 'username')

5
apps/assets/signals.py Normal file
View File

@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
#
from django.dispatch import Signal
on_app_ready = Signal()

View File

@@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
#
from collections import defaultdict
from django.db.models.signals import post_save, m2m_changed
from django.dispatch import receiver
from common.utils import get_logger
from .models import Asset, SystemUser, Node
from .tasks import update_assets_hardware_info_util, \
test_asset_connectability_util, push_system_user_to_assets
logger = get_logger(__file__)
def update_asset_hardware_info_on_created(asset):
logger.debug("Update asset `{}` hardware info".format(asset))
update_assets_hardware_info_util.delay([asset])
def test_asset_conn_on_created(asset):
logger.debug("Test asset `{}` connectability".format(asset))
test_asset_connectability_util.delay([asset])
def set_asset_root_node(asset):
logger.debug("Set asset default node: {}".format(Node.root()))
asset.nodes.add(Node.root())
@receiver(post_save, sender=Asset, dispatch_uid="my_unique_identifier")
def on_asset_created_or_update(sender, instance=None, created=False, **kwargs):
if created:
logger.info("Asset `{}` create signal received".format(instance))
update_asset_hardware_info_on_created(instance)
test_asset_conn_on_created(instance)
@receiver(post_save, sender=SystemUser, dispatch_uid="my_unique_identifier")
def on_system_user_update(sender, instance=None, created=True, **kwargs):
if instance and not created:
logger.info("System user `{}` update signal received".format(instance))
assets = instance.assets.all()
push_system_user_to_assets.delay(instance, assets)
@receiver(m2m_changed, sender=SystemUser.nodes.through)
def on_system_user_nodes_change(sender, instance=None, **kwargs):
if instance and kwargs["action"] == "post_add":
assets = set()
nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
for node in nodes:
assets.update(set(node.get_all_assets()))
instance.assets.add(*tuple(assets))
@receiver(m2m_changed, sender=SystemUser.assets.through)
def on_system_user_assets_change(sender, instance=None, **kwargs):
if instance and kwargs["action"] == "post_add":
assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
push_system_user_to_assets(instance, assets)
@receiver(m2m_changed, sender=Asset.nodes.through)
def on_asset_node_changed(sender, instance=None, **kwargs):
if isinstance(instance, Asset) and kwargs['action'] == 'post_add':
logger.debug("Asset node change signal received")
nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
system_users_assets = defaultdict(set)
system_users = SystemUser.objects.filter(nodes__in=nodes)
for system_user in system_users:
system_users_assets[system_user].update({instance})
for system_user, assets in system_users_assets.items():
system_user.assets.add(*tuple(assets))
@receiver(m2m_changed, sender=Asset.nodes.through)
def on_node_assets_changed(sender, instance=None, **kwargs):
if isinstance(instance, Node) and kwargs['action'] == 'post_add':
logger.debug("Node assets change signal received")
assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
system_users = SystemUser.objects.filter(nodes=instance)
for system_user in system_users:
system_user.assets.add(*tuple(assets))

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

@@ -0,0 +1,415 @@
# ~*~ coding: utf-8 ~*~
import json
import re
import os
from celery import shared_task
from django.core.cache import cache
from django.utils.translation import ugettext as _
from common.utils import get_object_or_none, capacity_convert, \
sum_capacity, encrypt_password, get_logger
from ops.celery.utils import register_as_period_task, after_app_shutdown_clean, \
after_app_ready_start
from ops.celery import app as celery_app
from .models import SystemUser, AdminUser, Asset
from . import const
FORKS = 10
TIMEOUT = 60
logger = get_logger(__file__)
CACHE_MAX_TIME = 60*60*60
disk_pattern = re.compile(r'^hd|sd|xvd|vd')
PERIOD_TASK = os.environ.get("PERIOD_TASK", "on")
@shared_task
def set_assets_hardware_info(result, **kwargs):
"""
Using ops task run result, to update asset info
@shared_task must be exit, because we using it as a task callback, is must
be a celery task also
:param result:
:param kwargs: {task_name: ""}
:return:
"""
result_raw = result[0]
assets_updated = []
for hostname, info in result_raw.get('ok', {}).items():
info = info.get('setup', {}).get('ansible_facts', {})
if not info:
logger.error("Get asset info failed: {}".format(hostname))
continue
asset = get_object_or_none(Asset, hostname=hostname)
if not asset:
continue
___vendor = info.get('ansible_system_vendor', 'Unknown')
___model = info.get('ansible_product_name', 'Unknown')
___sn = info.get('ansible_product_serial', 'Unknown')
for ___cpu_model in info.get('ansible_processor', []):
if ___cpu_model.endswith('GHz') or ___cpu_model.startswith("Intel"):
break
else:
___cpu_model = 'Unknown'
___cpu_model = ___cpu_model[:64]
___cpu_count = info.get('ansible_processor_count', 0)
___cpu_cores = info.get('ansible_processor_cores', None) or len(info.get('ansible_processor', []))
___memory = '%s %s' % capacity_convert('{} MB'.format(info.get('ansible_memtotal_mb')))
disk_info = {}
for dev, dev_info in info.get('ansible_devices', {}).items():
if disk_pattern.match(dev) and 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.get('ansible_system', 'Unknown')
___os = info.get('ansible_distribution', 'Unknown')
___os_version = info.get('ansible_distribution_version', 'Unknown')
___os_arch = info.get('ansible_architecture', 'Unknown')
___hostname_raw = info.get('ansible_hostname', 'Unknown')
for k, v in locals().items():
if k.startswith('___'):
setattr(asset, k.strip('_'), v)
asset.save()
assets_updated.append(asset)
return assets_updated
@shared_task
def update_assets_hardware_info_util(assets, task_name=None):
"""
Using ansible api to update asset hardware info
:param assets: asset seq
:param task_name: task_name running
:return: result summary ['contacted': {}, 'dark': {}]
"""
from ops.utils import update_or_create_ansible_task
if task_name is None:
# task_name = _("Update some assets hardware info")
task_name = _("更新资产硬件信息")
tasks = const.UPDATE_ASSETS_HARDWARE_TASKS
hostname_list = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()]
if not hostname_list:
logger.info("Not hosts get, may be asset is not active or not unixlike platform")
return {}
task, created = update_or_create_ansible_task(
task_name, hosts=hostname_list, tasks=tasks, pattern='all',
options=const.TASK_OPTIONS, run_as_admin=True, created_by='System',
)
result = task.run()
# Todo: may be somewhere using
# Manual run callback function
set_assets_hardware_info(result)
return result
@shared_task
def update_asset_hardware_info_manual(asset):
# task_name = _("Update asset hardware info")
task_name = _("更新资产硬件信息")
return update_assets_hardware_info_util([asset], task_name=task_name)
@celery_app.task
@register_as_period_task(interval=3600)
@after_app_ready_start
@after_app_shutdown_clean
def update_assets_hardware_info_period():
"""
Update asset hardware period task
:return:
"""
if PERIOD_TASK != "on":
logger.debug("Period task disabled, update assets hardware info pass")
return
from ops.utils import update_or_create_ansible_task
# task_name = _("Update assets hardware info period")
task_name = _("定期更新资产硬件信息")
hostname_list = [
asset.hostname for asset in Asset.objects.all()
if asset.is_active and asset.is_unixlike()
]
tasks = const.UPDATE_ASSETS_HARDWARE_TASKS
# Only create, schedule by celery beat
update_or_create_ansible_task(
task_name, hosts=hostname_list, tasks=tasks, pattern='all',
options=const.TASK_OPTIONS, run_as_admin=True, created_by='System',
interval=60*60*24, is_periodic=True, callback=set_assets_hardware_info.name,
)
## ADMIN USER CONNECTIVE ##
@shared_task
def set_admin_user_connectability_info(result, **kwargs):
admin_user = kwargs.get("admin_user")
task_name = kwargs.get("task_name")
if admin_user is None and task_name is not None:
admin_user = task_name.split(":")[-1]
raw, summary = result
cache_key = const.ADMIN_USER_CONN_CACHE_KEY.format(admin_user)
cache.set(cache_key, summary, CACHE_MAX_TIME)
for i in summary.get('contacted', []):
asset_conn_cache_key = const.ASSET_ADMIN_CONN_CACHE_KEY.format(i)
cache.set(asset_conn_cache_key, 1, CACHE_MAX_TIME)
for i, msg in summary.get('dark', {}).items():
asset_conn_cache_key = const.ASSET_ADMIN_CONN_CACHE_KEY.format(i)
cache.set(asset_conn_cache_key, 0, CACHE_MAX_TIME)
logger.error(msg)
@shared_task
def test_admin_user_connectability_util(admin_user, task_name):
"""
Test asset admin user can connect or not. Using ansible api do that
:param admin_user:
:param task_name:
:return:
"""
from ops.utils import update_or_create_ansible_task
assets = admin_user.get_related_assets()
hosts = [asset.hostname for asset in assets
if asset.is_active and asset.is_unixlike()]
if not hosts:
return
tasks = const.TEST_ADMIN_USER_CONN_TASKS
task, created = update_or_create_ansible_task(
task_name=task_name, hosts=hosts, tasks=tasks, pattern='all',
options=const.TASK_OPTIONS, run_as_admin=True, created_by='System',
)
result = task.run()
set_admin_user_connectability_info(result, admin_user=admin_user.name)
return result
@celery_app.task
@register_as_period_task(interval=3600)
@after_app_ready_start
@after_app_shutdown_clean
def test_admin_user_connectability_period():
"""
A period task that update the ansible task period
"""
if PERIOD_TASK != "on":
logger.debug("Period task disabled, test admin user connectability pass")
return
admin_users = AdminUser.objects.all()
for admin_user in admin_users:
# task_name = _("Test admin user connectability period: {}".format(admin_user.name))
task_name = _("定期测试管理账号可连接性: {}".format(admin_user.name))
test_admin_user_connectability_util(admin_user, task_name)
@shared_task
def test_admin_user_connectability_manual(admin_user):
# task_name = _("Test admin user connectability: {}").format(admin_user.name)
task_name = _("测试管理行号可连接性: {}").format(admin_user.name)
return test_admin_user_connectability_util(admin_user, task_name)
@shared_task
def test_asset_connectability_util(assets, task_name=None):
from ops.utils import update_or_create_ansible_task
if task_name is None:
# task_name = _("Test assets connectability")
task_name = _("测试资产可连接性")
hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()]
if not hosts:
logger.info("No hosts, passed")
return {}
tasks = const.TEST_ADMIN_USER_CONN_TASKS
task, created = update_or_create_ansible_task(
task_name=task_name, hosts=hosts, tasks=tasks, pattern='all',
options=const.TASK_OPTIONS, run_as_admin=True, created_by='System',
)
result = task.run()
summary = result[1]
for k in summary.get('dark'):
cache.set(const.ASSET_ADMIN_CONN_CACHE_KEY.format(k), 0, CACHE_MAX_TIME)
for k in summary.get('contacted'):
cache.set(const.ASSET_ADMIN_CONN_CACHE_KEY.format(k), 1, CACHE_MAX_TIME)
return summary
@shared_task
def test_asset_connectability_manual(asset):
summary = test_asset_connectability_util([asset])
if summary.get('dark'):
return False, summary['dark']
else:
return True, ""
## System user connective ##
@shared_task
def set_system_user_connectablity_info(result, **kwargs):
summary = result[1]
task_name = kwargs.get("task_name")
system_user = kwargs.get("system_user")
if system_user is None:
system_user = task_name.split(":")[-1]
cache_key = const.SYSTEM_USER_CONN_CACHE_KEY.format(system_user)
cache.set(cache_key, summary, CACHE_MAX_TIME)
@shared_task
def test_system_user_connectability_util(system_user, task_name):
"""
Test system cant connect his assets or not.
:param system_user:
:param task_name:
:return:
"""
from ops.utils import update_or_create_ansible_task
assets = system_user.get_assets()
hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()]
tasks = const.TEST_SYSTEM_USER_CONN_TASKS
if not hosts:
logger.info("No hosts, passed")
return {}
task, created = update_or_create_ansible_task(
task_name, hosts=hosts, tasks=tasks, pattern='all',
options=const.TASK_OPTIONS,
run_as=system_user.name, created_by="System",
)
result = task.run()
set_system_user_connectablity_info(result, system_user=system_user.name)
return result
@shared_task
def test_system_user_connectability_manual(system_user):
task_name = _("Test system user connectability: {}").format(system_user)
return test_system_user_connectability_util(system_user, task_name)
@shared_task
@register_as_period_task(interval=3600)
@after_app_ready_start
@after_app_shutdown_clean
def test_system_user_connectability_period():
if PERIOD_TASK != "on":
logger.debug("Period task disabled, test system user connectability pass")
return
system_users = SystemUser.objects.all()
for system_user in system_users:
# task_name = _("Test system user connectability period: {}".format(system_user))
task_name = _("定期测试系统用户可连接性: {}".format(system_user))
test_system_user_connectability_util(system_user, task_name)
#### Push system user tasks ####
def get_push_system_user_tasks(system_user):
# Set root as system user is dangerous
if system_user.username == "root":
return []
tasks = []
if system_user.password:
tasks.append({
'name': 'Add user {}'.format(system_user.username),
'action': {
'module': 'user',
'args': 'name={} shell={} state=present password={}'.format(
system_user.username, system_user.shell,
encrypt_password(system_user.password, salt="K3mIlKK"),
),
}
})
if system_user.public_key:
tasks.append({
'name': 'Set {} authorized key'.format(system_user.username),
'action': {
'module': 'authorized_key',
'args': "user={} state=present key='{}'".format(
system_user.username, system_user.public_key
)
}
})
if system_user.sudo:
tasks.append({
'name': 'Set {} sudo setting'.format(system_user.username),
'action': {
'module': 'lineinfile',
'args': "dest=/etc/sudoers state=present regexp='^{0} ALL=' "
"line='{0} ALL=(ALL) NOPASSWD: {1}' "
"validate='visudo -cf %s'".format(
system_user.username,
system_user.sudo,
)
}
})
return tasks
@shared_task
def push_system_user_util(system_users, assets, task_name):
from ops.utils import update_or_create_ansible_task
tasks = []
for system_user in system_users:
if not system_user.is_need_push():
msg = "push system user `{}` passed, may be not auto push or ssh " \
"protocol is not ssh".format(system_user.name)
logger.info(msg)
continue
tasks.extend(get_push_system_user_tasks(system_user))
if not tasks:
logger.info("Not tasks, passed")
return {}
hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()]
if not hosts:
logger.info("Not hosts, passed")
return {}
task, created = update_or_create_ansible_task(
task_name=task_name, hosts=hosts, tasks=tasks, pattern='all',
options=const.TASK_OPTIONS, run_as_admin=True, created_by='System'
)
return task.run()
@shared_task
def push_system_user_to_assets_manual(system_user):
assets = system_user.get_assets()
task_name = "推送系统用户到入资产: {}".format(system_user.name)
return push_system_user_util([system_user], assets, task_name=task_name)
@shared_task
def push_system_user_to_assets(system_user, assets):
task_name = _("推送系统用户到入资产: {}").format(system_user.name)
return push_system_user_util.delay([system_user], assets, task_name)
# @shared_task
# @register_as_period_task(interval=3600)
# @after_app_ready_start
# # @after_app_shutdown_clean
# def push_system_user_period():
# for system_user in SystemUser.objects.all():
# push_system_user_related_nodes(system_user)

View File

@@ -0,0 +1,41 @@
{% 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,125 @@
{% extends '_modal.html' %}
{% load i18n %}
{% load static %}
{% block modal_class %}modal-lg{% endblock %}
{% block modal_id %}asset_list_modal{% endblock %}
{% block modal_title%}{% trans "Asset list" %}{% endblock %}
{% block modal_body %}
<link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<style>
.inmodal .modal-header {
padding: 10px 10px;
text-align: center;
}
#assetTree2.ztree * {
background-color: #f8fafb;
}
#assetTree2.ztree {
background-color: #f8fafb;
}
</style>
<div class="wrapper wrapper-content">
<div class="row">
<div class="col-lg-3" id="split-left" style="padding-left: 3px">
<div class="ibox float-e-margins">
<div class="ibox-content mailbox-content" style="padding-top: 0;padding-left: 1px">
<div class="file-manager ">
<div id="assetTree2" class="ztree">
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<div class="col-lg-9 animated fadeInRight" id="split-right">
<div class="mail-box-header">
<table class="table table-striped table-bordered table-hover " id="asset_list_modal_table" style="width: 100%">
<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>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
var zTree2, asset_table2 = 0;
function initTable2() {
var options = {
ele: $('#asset_list_modal_table'),
ajax_url: '{% url "api-assets:asset-list" %}',
columns: [
{data: "id"}, {data: "hostname" }, {data: "ip" }
],
pageLength: 10
};
asset_table2 = jumpserver.initServerSideDataTable(options);
return asset_table2
}
function onSelected2(event, treeNode) {
var url = asset_table2.ajax.url();
url = setUrlParam(url, "node_id", treeNode.id);
setCookie('node_selected', treeNode.id);
asset_table2.ajax.url(url);
asset_table2.ajax.reload();
}
function initTree2() {
var setting = {
view: {
dblClickExpand: false,
showLine: true
},
data: {
simpleData: {
enable: true
}
},
callback: {
onSelected: onSelected2
}
};
var zNodes = [];
$.get("{% url 'api-assets:node-list' %}", function(data, status){
$.each(data, function (index, value) {
value["pId"] = value["parent"];
value["open"] = true;
value["name"] = value["value"] + ' (' + value['assets_amount'] + ')';
value['value'] = value['value'];
});
zNodes = data;
$.fn.zTree.init($("#assetTree2"), setting, zNodes);
zTree2 = $.fn.zTree.getZTreeObj("assetTree2");
});
}
$(document).ready(function(){
initTable2();
initTree2();
})
</script>
{% endblock %}
{% block modal_button %}
{{ block.super }}
{% endblock %}
{% block modal_confirm_id %}btn_asset_modal_confirm{% 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>{{ 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 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.priority layout="horizontal" %}
{% bootstrap_field form.protocol layout="horizontal" %}
{% block auth %}
<h3>{% trans 'Auth' %}</h3>
<div class="auto-generate">
<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>
<div class="auth-fields">
{% bootstrap_field form.password layout="horizontal" %}
{% bootstrap_field form.private_key_file layout="horizontal" %}
</div>
<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>
{% endblock %}
<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 auto_generate_key = '#'+'{{ form.auto_generate_key.id_for_label }}';
var protocol_id = '#' + '{{ form.protocol.id_for_label }}';
var password_id = '#' + '{{ form.password.id_for_label }}';
var private_key_id = '#' + '{{ form.private_key_file.id_for_label }}';
var sudo_id = '#' + '{{ form.sudo.id_for_label }}';
var shell_id = '#' + '{{ form.shell.id_for_label }}';
var need_change_field = [auto_generate_key, private_key_id, sudo_id, shell_id] ;
function authFieldsDisplay() {
if ($(auto_generate_key).prop('checked')) {
$('.auth-fields').addClass('hidden');
} else {
$('.auth-fields').removeClass('hidden');
}
}
function protocolChange() {
if ($(protocol_id).attr('value') === 'rdp') {
$.each(need_change_field, function (index, value) {
$(value).addClass('hidden')
});
$(password_id).removeClass('hidden')
} else {
$.each(need_change_field, function (index, value) {
$(value).removeClass('hidden')
});
}
}
$(document).ready(function () {
$('.select2').select2();
authFieldsDisplay();
protocolChange();
$(auto_generate_key).change(function () {
authFieldsDisplay();
});
})
</script>
{% endblock %}

View File

@@ -0,0 +1,137 @@
{% 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:admin-user-detail' pk=admin_user.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li class="active">
<a href="{% url 'assets:admin-user-assets' pk=admin_user.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Assets list' %} </a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-8" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left">{% trans 'Asset list of ' %} <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 table-striped table-bordered table-hover" id="asset_list_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 'Reachable' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-4" 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 'Test connective' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs btn-test-connective" style="width: 54px">{% trans 'Test' %}</button>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
function initTable() {
var options = {
ele: $('#asset_list_table'),
buttons: [],
order: [],
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=DEFAULT_PK %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', 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>')
}
}}],
ajax_url: '{% url "api-assets:asset-list" %}?admin_user_id={{ admin_user.id }}',
columns: [
{data: function(){return ""}}, {data: "hostname" }, {data: "ip" },
{data: "port" }, {data: "is_connective" }],
op_html: $('#actions').html()
};
jumpserver.initServerSideDataTable(options);
}
$(document).ready(function () {
initTable();
})
.on('click', '.btn-test-connective', function () {
var the_url = "{% url 'api-assets:admin-user-connective' pk=admin_user.id %}";
var success = function (data) {
var task_id = data.task;
var url = '{% url "ops:celery-task-log" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", task_id);
window.open(url, '', 'width=800,height=600')
};
APIUpdateAttr({
url: the_url,
method: 'GET',
success: success,
flash_message: false
});
})
</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>{{ 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">
{% 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,171 @@
{% 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:admin-user-detail' pk=admin_user.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li>
<a href="{% url 'assets:admin-user-assets' pk=admin_user.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Assets list' %} </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>{% trans 'Update' %}</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-danger btn-delete-admin-user">
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-8" 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>
<div class="col-sm-4" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Replace node assets admin user with this' %}
</div>
<div class="panel-body">
<table class="table group_edit" id="table-clusters">
<tbody>
<form>
<tr>
<td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Select nodes' %}" id="nodes_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for node in nodes %}
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node.value }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td colspan="2" class="no-borders">
<button type="button" class="btn btn-primary btn-sm" id="btn-change-admin-user">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
function replaceNodeAssetsAdminUser(nodes) {
var the_url = "{% url 'api-assets:replace-nodes-admin-user' pk=admin_user.id %}";
var body = {
nodes: nodes
};
var success = function(data) {
// remove all the selected groups from select > option and rendered ul element;
$('.select2-selection__rendered').empty();
$('#nodes_selected').val('');
$.map(jumpserver.nodes_selected, function(value, index) {
$('#opt_' + index).remove();
});
// clear jumpserver.groups_selected
jumpserver.nodes_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
jumpserver.nodes_selected = {};
$(document).ready(function () {
$('.select2').select2()
.on('select2:select', function(evt) {
var data = evt.params.data;
jumpserver.nodes_selected[data.id] = data.text;
}).on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.nodes_selected[data.id]
});
})
.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=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
var redirect_url = "{% url 'assets:admin-user-list' %}";
objectDelete($this, name, the_url, redirect_url);
})
.on('click', '#btn-change-admin-user', function () {
if (Object.keys(jumpserver.nodes_selected).length === 0) {
return false;
}
var nodes = [];
$.map(jumpserver.nodes_selected, function(value, index) {
nodes.push(index);
});
replaceNodeAssetsAdminUser(nodes);
})
</script>
{% endblock %}

View File

@@ -0,0 +1,112 @@
{% extends '_base_list.html' %}
{% load i18n static %}
{% block table_search %}
{% endblock %}
{% block help_message %}
<div class="alert alert-info help-message">
管理用户是服务器的root或拥有 NOPASSWD: ALL sudo权限的用户Jumpserver使用该用户来 `推送系统用户`、`获取资产硬件信息`等。
Windows或其它硬件可以随意设置一个
</div>
{% endblock %}
{% block table_container %}
<div class="uc pull-left 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' %}</th>
<th class="text-center">{% trans 'Reachable' %}</th>
<th class="text-center">{% trans 'Unreachable' %}</th>
<th class="text-center">{% trans 'Ratio' %}</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=DEFAULT_PK %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
}},
{targets: 4, createdCell: function (td, cellData) {
var innerHtml = "";
if (cellData !== 0) {
innerHtml = "<span class='text-navy'>" + cellData + "</span>";
} else {
innerHtml = "<span>" + cellData + "</span>";
}
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData +'">' + innerHtml + '</span>');
}},
{targets: 5, createdCell: function (td, cellData) {
var innerHtml = "";
if (cellData !== 0) {
innerHtml = "<span class='text-danger'>" + cellData + "</span>";
} else {
innerHtml = "<span>" + cellData + "</span>";
}
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
}},
{targets: 6, createdCell: function (td, cellData, rowData) {
var val = 0;
var innerHtml = "";
var total = rowData.assets_amount;
var reachable = rowData.reachable_amount;
if (total !== 0) {
val = reachable/total * 100;
}
if (val === 100) {
innerHtml = "<span class='text-navy'>" + val + "% </span>";
} else {
var num = new Number(val);
innerHtml = "<span class='text-danger'>" + num.toFixed(1) + "% </span>";
}
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
}},
{targets: 8, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:admin-user-update" pk=DEFAULT_PK %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
$(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: "reachable_amount"}, {data: "unreachable_amount"}, {data: "id"}, {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=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', 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,90 @@
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% load asset_tags %}
{% load common_tags %}
{% 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.port layout="horizontal" %}
{% bootstrap_field form.platform layout="horizontal" %}
{% bootstrap_field form.public_ip layout="horizontal" %}
{% bootstrap_field form.domain layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Auth' %}</h3>
{% bootstrap_field form.admin_user layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Node' %}</h3>
{% bootstrap_field form.nodes layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Labels' %}</h3>
<div class="form-group {% if form.errors.labels %} has-error {% endif %}">
<label for="{{ form.labels.id_for_label }}" class="col-md-2 control-label">{% trans 'Label' %}</label>
<div class="col-md-9">
<select name="labels" class="select2 labels" data-placeholder="{% trans 'Label' %}" style="width: 100%" multiple="" tabindex="4" id="{{ form.labels.id_for_label }}">
{% for name, labels in form.labels.field.queryset|group_labels %}
<optgroup label="{{ name }}">
{% for label in labels %}
{% if label in form.labels.initial %}
<option value="{{ label.id }}" selected>{{ label.value }}</option>
{% else %}
<option value="{{ label.id }}">{{ label.value }}</option>
{% endif %}
{% endfor %}
</optgroup>
{% endfor %}
</select>
{% if form.errors.labels %}
{% for e in form.errors.labels %}
<div class="help-block">{{ e }}</div>
{% endfor %}
{% endif %}
</div>
</div>
<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>
function format(item) {
var group = item.element.parentElement.label;
return group + ':' + item.text;
}
$(document).ready(function () {
$('.select2').select2({
allowClear: true
});
$(".labels").select2({
allowClear: true,
templateSelection: format
});
})
</script>
{% endblock %}

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">
<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>{% trans 'Update' %}</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-danger btn-delete-asset">
<i class="fa fa-trash-o"></i>{% trans '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|default:"" }}</b></td>
</tr>
<tr>
<td>{% trans 'Port' %}:</td>
<td><b>{{ asset.port }}</b></td>
</tr>
<tr>
<td>{% trans 'Admin user' %}:</td>
<td><b>{{ asset.admin_user }}</b></td>
</tr>
<tr>
<td>{% trans 'Vendor' %}:</td>
<td><b>{{ asset.vendor|default:"" }}</b></td>
</tr>
<tr>
<td>{% trans 'Model' %}:</td>
<td><b>{{ asset.model|default:"" }}</b></td>
</tr>
<tr>
<td>{% trans 'CPU' %}:</td>
<td><b>{{ asset.cpu_model|default:"" }} {{ asset.cpu_count|default:"" }}*{{ asset.cpu_cores|default:"" }}</b></td>
</tr>
<tr>
<td>{% trans 'Memory' %}:</td>
<td><b>{{ asset.memory|default:"" }}</b></td>
</tr>
<tr>
<td>{% trans 'Disk' %}:</td>
<td><b>{{ asset.disk_total|default:"" }}</b></td>
</tr>
<tr>
<td>{% trans 'Platform' %}:</td>
<td><b>{{ asset.platform|default:"" }}</b></td>
</tr>
<tr>
<td>{% trans 'OS' %}:</td>
<td><b>{{ asset.os|default:"" }} {{ asset.os_version|default:"" }} {{ asset.os_arch|default:"" }}</b></td>
</tr>
<tr>
<td>{% trans 'Is active' %}:</td>
<td><b>{{ asset.is_active|yesno:"Yes,No" }}</b></td>
</tr>
<tr>
<td>{% trans 'Serial number' %}:</td>
<td><b>{{ asset.sn|default:"" }}</b></td>
</tr>
<tr>
<td>{% trans 'Asset number' %}:</td>
<td><b>{{ asset.number|default:"" }}</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>
{% if asset.is_unixlike %}
<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 connective' %}:</td>
<td>
<span class="pull-right">
<button type="button" class="btn btn-primary btn-xs" id="btn-test-is-alive" style="width: 54px">{% trans 'Test' %}</button>
</span>
</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Nodes' %}
</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 'Nodes' %}" id="groups_selected" class="select2 groups" style="width: 100%" multiple="" tabindex="4">
{% for node in nodes_remain %}
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node.name }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td colspan="2" class="no-borders">
<button type="button" class="btn btn-info btn-sm" id="btn-update-nodes">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
{% for node in asset.nodes.all %}
<tr>
<td ><b class="bdg_node" data-gid={{ node.id }}>{{ node.name }}</b></td>
<td>
<button class="btn btn-danger pull-right btn-xs btn-leave-node" 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 'Labels' %}
</div>
<div class="panel-body">
<ul class="tag-list" style="padding: 0">
{% for label in asset.labels.all %}
<li ><a href=""><i class="fa fa-tag"></i> {{ label.name }}:{{ label.value }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
jumpserver.nodes_selected = {};
function updateAssetNodes(nodes) {
var the_url = "{% url 'api-assets:asset-detail' pk=asset.id %}";
var body = {
nodes: Object.assign([], nodes)
};
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.nodes_selected, function(group_name, index) {
$('#opt_' + index).remove();
// change tr html of user groups.
$('#add-asset2group tbody').append(
'<tr>' +
'<td><b class="bdg_node" data-gid="' + index + '">' + group_name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn-leave-node" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
// clear jumpserver.groups_selected
jumpserver.nodes_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) {
console.log(data);
var task_id = data.task;
var url = '{% url "ops:celery-task-log" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", task_id);
window.open(url, '', 'width=800,height=600')
};
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.nodes_selected[data.id] = data.text;
}).on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.nodes_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-update-nodes', function () {
if (Object.keys(jumpserver.nodes_selected).length === 0) {
return false;
}
var nodes = $('.bdg_node').map(function() {
return $(this).data('gid');
}).get();
$.map(jumpserver.nodes_selected, function(value, index) {
nodes.push(index);
$('#opt_' + index).remove();
});
updateAssetNodes(nodes)
}).on('click', '.btn-leave-node', function() {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_node');
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_node').map(function () {
return $(this).data('gid');
}).get();
updateAssetNodes(groups)
}).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=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
var redirect_url = "{% url 'assets:asset-list' %}";
objectDelete($this, name, the_url, redirect_url);
}).on('click', '#btn_refresh_asset', function () {
refreshAssetHardware()
}).on('click', '#btn-test-is-alive', function () {
var the_url = "{% url 'api-assets:asset-alive-test' pk=asset.id %}";
var success = function(data) {
var task_id = data.task;
var url = '{% url "ops:celery-task-log" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", task_id);
window.open(url, '', 'width=800,height=600')
};
APIUpdateAttr({
url: the_url,
method: 'GET',
success: success
});
})
</script>
{% endblock %}

View File

@@ -0,0 +1,714 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block help_message %}
<div class="alert alert-info help-message">
左侧是资产树,右击可以新建、删除、更改树节点,授权资产也是以节点方式组织的,右侧是属于该节点下的资产
</div>
{% endblock %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<style type="text/css">
div#rMenu {
position:absolute;
visibility:hidden;
text-align: left;
top: 100%;
left: 0;
z-index: 1000;
float: left;
padding: 5px 0;
margin: 2px 0 0;
list-style: none;
background-clip: padding-box;
}
div#rMenu li{
margin: 1px 0;
cursor: pointer;
{#list-style: none outside none;#}
}
.dropdown a:hover {
background-color: #f1f1f1
}
</style>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content">
<div class="row">
<div class="col-lg-3" id="split-left" style="padding-left: 3px">
<div class="ibox float-e-margins">
<div class="ibox-content mailbox-content" style="padding-top: 0;padding-left: 1px">
<div class="file-manager ">
<div id="assetTree" class="ztree">
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<div class="col-lg-9 animated fadeInRight" id="split-right">
<div class="tree-toggle">
<div class="btn btn-sm btn-primary tree-toggle-btn" onclick="toggle()">
<i class="fa fa-angle-left fa-x" id="toggle-icon"></i>
</div>
</div>
<div class="mail-box-header">
<div class="uc pull-left m-r-5"><a class="btn btn-sm btn-primary btn-create-asset"> {% trans "Create asset" %} </a></div>
<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>
<div class="btn-group" style="float: right">
<button data-toggle="dropdown" class="btn btn-default btn-sm dropdown-toggle">{% trans 'Label' %} <span class="caret"></span></button>
<ul class="dropdown-menu labels">
{% for label in labels %}
<li><a style="font-weight: bolder">{{ label.name }}:{{ label.value }}</a></li>
{% endfor %}
</ul>
</div>
<table class="table table-striped table-bordered table-hover " id="asset_list_table" style="width: 100%">
<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 'Hardware' %}</th>
<th class="text-center">{% trans 'Active' %}</th>
<th class="text-center">{% trans 'Reachable' %}</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="remove">{% trans 'Remove from this node' %}</option>
<option value="deactive">{% trans 'Deactive selected' %}</option>
<option value="active">{% trans 'Active 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>
</div>
</div>
</div>
</div>
<div id="rMenu">
<ul class="dropdown-menu">
<li class="divider"></li>
<li id="m_create" tabindex="-1" onclick="addTreeNode();"><a><i class="fa fa-plus-square-o"></i> {% trans 'Add node' %}</a></li>
<li id="m_del" tabindex="-1" onclick="editTreeNode();"><a><i class="fa fa-pencil-square-o"></i> {% trans 'Rename node' %}</a></li>
<li id="m_del" tabindex="-1" onclick="removeTreeNode();"><a><i class="fa fa-minus-square"></i> {% trans 'Delete node' %}</a></li>
<li class="divider"></li>
<li id="menu_asset_add" class="btn-add-asset" data-toggle="modal" data-target="#asset_list_modal" tabindex="0"><a><i class="fa fa-copy"></i> {% trans 'Add assets to node' %}</a></li>
<li id="menu_asset_move" class="btn-move-asset" data-toggle="modal" data-target="#asset_list_modal" tabindex="0"><a><i class="fa fa-cut"></i> {% trans 'Move assets to node' %}</a></li>
<li class="divider"></li>
<li id="menu_refresh_hardware_info" class="btn-refresh-hardware" tabindex="-1"><a><i class="fa fa-refresh"></i> {% trans 'Refresh node hardware info' %}</a></li>
<li id="menu_test_connective" class="btn-test-connective" tabindex="-1"><a><i class="fa fa-chain"></i> {% trans 'Test node connective' %}</a></li>
</ul>
</div>
{% include 'assets/_asset_import_modal.html' %}
{% include 'assets/_asset_list_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script>
var zTree, rMenu, asset_table, show = 0;
var update_node_action = "";
function initTable() {
var options = {
ele: $('#asset_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
{% url 'assets:asset-detail' pk=DEFAULT_PK as the_url %}
var detail_btn = '<a href="{{ the_url }}">' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData, rowData) {
$(td).html(rowData.hardware_info)
}},
{targets: 4, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 5, createdCell: function (td, cellData) {
if (cellData === '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: 6, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace("{{ DEFAULT_PK }}", cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}',
columns: [
{data: "id"}, {data: "hostname" }, {data: "ip" },
{data: "cpu_cores"}, {data: "is_active", orderable: false },
{data: "is_connective", orderable: false}, {data: "id", orderable: false }
],
op_html: $('#actions').html()
};
asset_table = jumpserver.initServerSideDataTable(options);
return asset_table
}
function addTreeNode() {
hideRMenu();
var parentNode = zTree.getSelectedNodes()[0];
if (!parentNode){
return
}
var url = "{% url 'api-assets:node-children' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", parentNode.id );
$.post(url, {}, function (data, status){
if (status === "success") {
var newNode = {
name: data["value"],
id: data["id"],
pId: parentNode.id
};
newNode.checked = zTree.getSelectedNodes()[0].checked;
zTree.addNodes(parentNode, 0, newNode);
} else {
alert("{% trans 'Create node failed' %}")
}
});
}
function removeTreeNode() {
hideRMenu();
var current_node = zTree.getSelectedNodes()[0];
if (!current_node){
return
}
if (current_node.children && current_node.children.length > 0) {
toastr.error("{% trans 'Have child node, cancel' %}");
} else if (current_node.assets_amount !== 0) {
toastr.error("{% trans 'Have assets, cancel' %}");
} else {
var url = "{% url 'api-assets:node-detail' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", current_node.id );
$.ajax({
url: url,
method: "DELETE",
success: function () {
zTree.removeNode(current_node);
}
});
}
}
function editTreeNode() {
hideRMenu();
var current_node = zTree.getSelectedNodes()[0];
if (!current_node){
return
}
if (current_node.value) {
current_node.name = current_node.value;
}
zTree.editName(current_node);
}
function OnRightClick(event, treeId, treeNode) {
if (!treeNode && event.target.tagName.toLowerCase() !== "button" && $(event.target).parents("a").length === 0) {
zTree.cancelSelectedNode();
showRMenu("root", event.clientX, event.clientY);
} else if (treeNode && !treeNode.noR) {
zTree.selectNode(treeNode);
showRMenu("node", event.clientX, event.clientY);
}
}
function showRMenu(type, x, y) {
$("#rMenu ul").show();
x -= 220;
rMenu.css({"top":y+"px", "left":x+"px", "visibility":"visible"});
$("body").bind("mousedown", onBodyMouseDown);
}
function beforeClick(treeId, treeNode, clickFlag) {
return true;
}
function hideRMenu() {
if (rMenu) rMenu.css({"visibility": "hidden"});
$("body").unbind("mousedown", onBodyMouseDown);
}
function onBodyMouseDown(event){
if (!(event.target.id === "rMenu" || $(event.target).parents("#rMenu").length>0)) {
rMenu.css({"visibility" : "hidden"});
}
}
function onRename(event, treeId, treeNode, isCancel){
var url = "{% url 'api-assets:node-detail' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", treeNode.id);
var data = {"value": treeNode.name};
if (isCancel){
return
}
APIUpdateAttr({
url: url,
body: JSON.stringify(data),
method: "PATCH"
})
}
function onSelected(event, treeNode) {
var url = asset_table.ajax.url();
url = setUrlParam(url, "node_id", treeNode.id);
setCookie('node_selected', treeNode.id);
asset_table.ajax.url(url);
asset_table.ajax.reload();
}
function selectQueryNode() {
var query_node_id = $.getUrlParam("node");
var cookie_node_id = getCookie('node_selected');
var node;
var node_id;
if (query_node_id !== null) {
node_id = query_node_id
} else if (cookie_node_id !== null) {
node_id = cookie_node_id;
}
node = zTree.getNodesByParam("id", node_id, null);
if (node){
zTree.selectNode(node[0]);
}
}
function beforeDrag() {
return true
}
function beforeDrop(treeId, treeNodes, targetNode, moveType) {
var treeNodesNames = [];
$.each(treeNodes, function (index, value) {
treeNodesNames.push(value.value);
});
var msg = "你想移动节点: `" + treeNodesNames.join(",") + "` 到 `" + targetNode.value + "` 下吗?";
if (confirm(msg)){
return true
} else {
return false
}
}
function onDrag(event, treeId, treeNodes) {
}
function onDrop(event, treeId, treeNodes, targetNode, moveType) {
var treeNodesIds = [];
$.each(treeNodes, function (index, value) {
treeNodesIds.push(value.id);
});
var the_url = "{% url 'api-assets:node-add-children' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", targetNode.id);
var body = {nodes: treeNodesIds};
APIUpdateAttr({
url: the_url,
method: "PUT",
body: JSON.stringify(body)
})
}
function initTree() {
var setting = {
view: {
dblClickExpand: false,
showLine: true
},
data: {
simpleData: {
enable: true
}
},
edit: {
enable: true,
showRemoveBtn: false,
showRenameBtn: false,
drag: {
isCopy: true,
isMove: true
}
},
callback: {
onRightClick: OnRightClick,
beforeClick: beforeClick,
onRename: onRename,
onSelected: onSelected,
beforeDrag: beforeDrag,
onDrag: onDrag,
beforeDrop: beforeDrop,
onDrop: onDrop
}
};
var zNodes = [];
$.get("{% url 'api-assets:node-list' %}", function(data, status){
$.each(data, function (index, value) {
value["pId"] = value["parent"];
{#if (value["key"] === "0") {#}
value["open"] = true;
{# }#}
value["name"] = value["value"] + ' (' + value['assets_amount'] + ')';
value['value'] = value['value'];
});
zNodes = data;
$.fn.zTree.init($("#assetTree"), setting, zNodes);
zTree = $.fn.zTree.getZTreeObj("assetTree");
rMenu = $("#rMenu");
selectQueryNode();
});
}
function toggle() {
if (show === 0) {
$("#split-left").hide(500, function () {
$("#split-right").attr("class", "col-lg-12");
$("#toggle-icon").attr("class", "fa fa-angle-right fa-x");
show = 1;
});
} else {
$("#split-right").attr("class", "col-lg-9");
$("#toggle-icon").attr("class", "fa fa-angle-left fa-x");
$("#split-left").show(500);
show = 0;
}
}
$(document).ready(function(){
initTable();
initTree();
})
.on('click', '.labels li', function () {
var val = $(this).text();
$("#asset_list_table_filter input").val(val);
asset_table.search(val).draw();
})
.on('click', '.btn_export', function () {
var $data_table = $('#asset_list_table').DataTable();
var rows = $data_table.rows('.selected').data();
var nodes = zTree.getSelectedNodes();
var current_node;
if (nodes && nodes.length === 1) {
current_node = nodes[0];
}
var assets = [];
$.each(rows, function (index, obj) {
assets.push(obj.id)
});
$.ajax({
url: "{% url "assets:asset-export" %}",
method: 'POST',
data: JSON.stringify({assets_id: assets, node_id: current_node.id}),
dataType: "json",
success: function (data, textStatus) {
window.open(data.redirect)
},
error: function () {
toastr.error('Export failed');
}
})
})
.on('click', '#btn_asset_import', function () {
var $form = $('#fm_asset_import');
var action = $form.attr("action");
var nodes = zTree.getSelectedNodes();
var current_node;
if (nodes && nodes.length ===1 ){
current_node = nodes[0];
action = setUrlParam(action, 'node_id', current_node.id);
{#action += "?node_id=" + current_node.id;#}
$form.attr("action", action)
}
$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-create-asset', function () {
var url = "{% url 'assets:asset-create' %}";
var nodes = zTree.getSelectedNodes();
var current_node;
if (nodes && nodes.length ===1 ){
current_node = nodes[0];
url += "?node_id=" + current_node.id;
}
window.open(url, '_self');
})
.on('click', '.btn-refresh-hardware', function () {
var url = "{% url 'api-assets:node-refresh-hardware-info' pk=DEFAULT_PK %}";
var nodes = zTree.getSelectedNodes();
var current_node;
if (nodes && nodes.length ===1 ){
current_node = nodes[0];
} else {
return null;
}
var the_url = url.replace("{{ DEFAULT_PK }}", current_node.id);
function success(data) {
rMenu.css({"visibility" : "hidden"});
var task_id = data.task;
var url = '{% url "ops:celery-task-log" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", task_id);
window.open(url, '', 'width=800,height=600')
}
APIUpdateAttr({
url: the_url,
method: "GET",
success: success,
flash_message: false
});
})
.on('click', '.btn-test-connective', function () {
var url = "{% url 'api-assets:node-test-connective' pk=DEFAULT_PK %}";
var nodes = zTree.getSelectedNodes();
var current_node;
if (nodes && nodes.length ===1 ){
current_node = nodes[0];
} else {
return null;
}
var the_url = url.replace("{{ DEFAULT_PK }}", current_node.id);
function success(data) {
rMenu.css({"visibility" : "hidden"});
var task_id = data.task;
var url = '{% url "ops:celery-task-log" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", task_id);
window.open(url, '', 'width=800,height=600')
}
APIUpdateAttr({
url: the_url,
method: "GET",
success: success,
flash_message: false
});
})
.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=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", 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_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 data = [];
$.each(id_list, function(index, object_id) {
var obj = {"pk": object_id, "is_active": false};
data.push(obj);
});
function success() {
asset_table.ajax.reload()
}
APIUpdateAttr({
url: the_url,
method: 'PATCH',
body: JSON.stringify(data),
success: success
});
}
function doActive() {
var data = [];
$.each(id_list, function(index, object_id) {
var obj = {"pk": object_id, "is_active": true};
data.push(obj);
});
function success() {
asset_table.ajax.reload()
}
APIUpdateAttr({
url: the_url,
method: 'PATCH',
body: JSON.stringify(data),
success: success
});
}
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(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
}
function doRemove() {
var current_node;
var nodes = zTree.getSelectedNodes();
if (nodes && nodes.length === 1) {
current_node = nodes[0]
} else {
return
}
var data = {
'assets': id_list
};
var success = function () {
asset_table.ajax.reload()
};
APIUpdateAttr({
'url': '/api/assets/v1/nodes/' + current_node.id + '/assets/remove/',
'method': 'PUT',
'body': JSON.stringify(data),
'success': success
})
}
switch(action) {
case 'deactive':
doDeactive();
break;
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
case 'active':
doActive();
break;
case 'remove':
doRemove();
break;
default:
break;
}
$(".ipt_check_all").prop("checked", false)
})
.on('click', '#btn_asset_modal_confirm', function () {
var assets_selected = asset_table2.selected;
var current_node;
var nodes = zTree.getSelectedNodes();
if (nodes && nodes.length === 1) {
current_node = nodes[0]
} else {
return
}
var data = {
'assets': assets_selected
};
var success = function () {
asset_table2.selected = [];
asset_table2.ajax.reload()
};
var url = '';
if (update_node_action === "move") {
url = "{% url 'api-assets:node-replace-assets' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", current_node.id);
} else {
url = "{% url 'api-assets:node-add-assets' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", current_node.id);
}
APIUpdateAttr({
'url': url,
'method': 'PUT',
'body': JSON.stringify(data),
'success': success
})
}).on('hidden.bs.modal', '#asset_list_modal', function () {
window.location.reload();
}).on('click', '#menu_asset_add', function () {
update_node_action = "add"
}).on('click', '#menu_asset_move', function () {
update_node_action = "move"
})
</script>
{% endblock %}

View File

@@ -0,0 +1,94 @@
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% load asset_tags %}
{% load common_tags %}
{% 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.port layout="horizontal" %}
{% bootstrap_field form.platform layout="horizontal" %}
{% bootstrap_field form.public_ip layout="horizontal" %}
{% bootstrap_field form.domain layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Auth' %}</h3>
{% bootstrap_field form.admin_user layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Node' %}</h3>
{% bootstrap_field form.nodes layout="horizontal" %}
<div class="hr-line-dashed"></div>
<h3>{% trans 'Labels' %}</h3>
<div class="form-group">
<label for="{{ form.labels.id_for_label }}" class="col-md-2 control-label">{% trans 'Label' %}</label>
<div class="col-md-9">
<select name="labels" class="select2 labels" data-placeholder="{% trans 'Label' %}" style="width: 100%" multiple="" tabindex="4" id="{{ form.labels.id_for_label }}">
{% for name, labels in form.labels.field.queryset|group_labels %}
<optgroup label="{{ name }}">
{% for label in labels %}
{% if label in form.labels.initial %}
<option value="{{ label.id }}" selected>{{ label.value }}</option>
{% else %}
<option value="{{ label.id }}">{{ label.value }}</option>
{% endif %}
{% endfor %}
</optgroup>
{% endfor %}
</select>
</div>
</div>
<div class="hr-line-dashed"></div>
<h3>{% trans 'Configuration' %}</h3>
{% bootstrap_field form.number 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-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>
function format(item) {
var group = item.element.parentElement.label;
return group + ':' + item.text;
}
$(document).ready(function () {
$('.select2').select2({
allowClear: true
});
$(".labels").select2({
allowClear: true,
templateSelection: format
});
})
</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,42 @@
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% block form %}
<form id="groupForm" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.assets layout="horizontal" %}
{% 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-default" type="reset"> {% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form>
{% include 'assets/_asset_list_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script type="text/javascript">
$(document).ready(function () {
console.log($.fn.select2.defaults);
$('.select2').select2().off("select2:open");
}).on('click', '.select2-selection__rendered', function (e) {
e.preventDefault();
$("#asset_list_modal").modal();
})
.on('click', '#btn_asset_modal_confirm', function () {
var assets = asset_table2.selected;
$.each(assets, function (id, data) {
$('.select2').val(assets).trigger('change');
});
$("#asset_list_modal").modal('hide');
})
</script>
{% endblock %}

View File

@@ -0,0 +1,132 @@
{% 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:domain-detail' pk=object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li>
<a href="{% url 'assets:domain-gateway-list' pk=object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Gateway' %} </a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'assets:domain-update' pk=object.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-danger btn-del">
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-9" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label"><b>{{ object.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>{{ object.name }}</b></td>
</tr>
<tr>
<td>{% trans 'Asset' %}:</td>
<td><b>{{ object.assets.count }}</b></td>
</tr>
<tr>
<td>{% trans 'Gateway' %}:</td>
<td><b>{{ object.gateway_set.count }}</b></td>
</tr>
<tr>
<td>{% trans 'Date created' %}:</td>
<td><b>{{ object.date_created }}</b></td>
</tr>
<tr>
<td>{% trans 'Created by' %}:</td>
<td><b>{{ object.created_by }}</b></td>
</tr>
<tr>
<td>{% trans 'Comment' %}:</td>
<td><b>{{ object.comment }}</b></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
function initTable() {
var options = {
ele: $('#domain_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:domain-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
}},
{targets: 5, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:domain-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:domain-list" %}',
columns: [
{data: "id"}, {data: "name" }, {data: "asset_count" },
{data: "gateway_count" }, {data: "comment" }, {data: "id"}
],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
}
$(document).ready(function(){
initTable();
})
.on('click', '.btn-delete', function () {
var $this = $(this);
var $data_table = $('#domain_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:domain-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
});
</script>
{% endblock %}

View File

@@ -0,0 +1,126 @@
{% 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:domain-detail' pk=object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li class="active">
<a href="{% url 'assets:domain-detail' pk=object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Gateway' %} </a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-12" style="padding-left: 0;">
<div class="" id="content_start">
</div>
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left"><b>{% trans 'Gateway list' %}</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">
<div class="uc pull-left m-r-5">
<a href="{% url 'assets:domain-gateway-create' pk=object.id %}" class="btn btn-sm btn-primary"> {% trans "Create gateway" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="domain_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 'IP' %}</th>
<th class="text-center">{% trans 'Port' %}</th>
<th class="text-center">{% trans 'Protocol' %}</th>
<th class="text-center">{% trans 'Username' %}</th>
<th class="text-center">{% trans 'Comment' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
function initTable() {
var options = {
ele: $('#domain_list_table'),
columnDefs: [
{targets: 7, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:domain-gateway-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var test_btn = '<a class="btn btn-xs btn-warning m-l-xs btn-test" data-uid="{{ DEFAULT_PK }}">{% trans "Test connection" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
$(td).html(update_btn + test_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:gateway-list" %}?domain={{ object.id }}',
columns: [
{data: "id"}, {data: "name" }, {data: 'ip'}, {data: 'port'},
{data: "protocol"}, {data: "username" }, {data: "comment" }, {data: "id"}
],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
}
$(document).ready(function(){
initTable();
})
.on('click', '.btn-delete', function () {
var $this = $(this);
var $data_table = $('#domain_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:gateway-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
}).on('click', '.btn-test', function () {
var $this = $(this);
var uid = $this.data('uid');
var the_url = '{% url "api-assets:test-gateway-connective" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
APIUpdateAttr({
url: the_url,
method: "GET",
success_message: "可连接",
fail_message: "连接失败"
})
})
</script>
{% endblock %}

View File

@@ -0,0 +1,74 @@
{% extends '_base_list.html' %}
{% load i18n static %}
{% block table_search %}{% endblock %}
{% block table_container %}
<div class="uc pull-left m-r-5">
<a href="{% url 'assets:domain-create' %}" class="btn btn-sm btn-primary"> {% trans "Create domain" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="domain_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 'Gateway' %}</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>
function initTable() {
var options = {
ele: $('#domain_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:domain-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData, rowData) {
var gateway_list_btn = '<a href="{% url "assets:domain-gateway-list" pk=DEFAULT_PK %}">' + cellData + '</a>';
gateway_list_btn = gateway_list_btn.replace("{{ DEFAULT_PK }}", rowData.id);
$(td).html(gateway_list_btn);
}},
{targets: 5, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:domain-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:domain-list" %}',
columns: [
{data: "id"}, {data: "name" }, {data: "asset_count" },
{data: "gateway_count" }, {data: "comment" }, {data: "id"}
],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
}
$(document).ready(function(){
initTable();
})
.on('click', '.btn-delete', function () {
var $this = $(this);
var $data_table = $('#domain_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:domain-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
});
</script>
{% endblock %}

View File

@@ -0,0 +1,68 @@
{% 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>{{ 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 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.ip layout="horizontal" %}
{% bootstrap_field form.port layout="horizontal" %}
{% bootstrap_field form.protocol layout="horizontal" %}
{% bootstrap_field form.domain layout="horizontal" %}
{% block auth %}
<h3>{% trans 'Auth' %}</h3>
<div class="auth-fields">
{% bootstrap_field form.username layout="horizontal" %}
{% bootstrap_field form.password layout="horizontal" %}
{% bootstrap_field form.private_key_file layout="horizontal" %}
</div>
{% endblock %}
<h3>{% trans 'Other' %}</h3>
{% bootstrap_field form.is_active 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 %}

View File

@@ -0,0 +1,47 @@
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% block form %}
<form id="groupForm" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.value layout="horizontal" %}
{% bootstrap_field form.assets 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>
{% include 'assets/_asset_list_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script type="text/javascript">
$(document).ready(function () {
$('.select2').select2({
closeOnSelect: false
})
}).on('click', '.select2-selection__rendered', function (e) {
e.preventDefault();
$("#asset_list_modal").modal();
})
.on('click', '#btn_asset_modal_confirm', function () {
var assets = asset_table2.selected;
$('.select2 option:selected').each(function (i, data) {
assets.push($(data).attr('value'))
});
$.each(assets, function (id, data) {
$('.select2').val(assets).trigger('change');
});
$("#asset_list_modal").modal('hide');
})
</script>
{% endblock %}

View File

@@ -0,0 +1,70 @@
{% extends '_base_list.html' %}
{% load i18n static %}
{% block table_search %}{% endblock %}
{% block table_container %}
<div class="uc pull-left m-r-5">
<a href="{% url 'assets:label-create' %}" class="btn btn-sm btn-primary"> {% trans "Create label" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="label_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 'Value' %}</th>
<th class="text-center">{% trans 'Asset' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
function initTable() {
var options = {
ele: $('#label_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
{# var detail_btn = '<a href="{% url "assets:label-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';#}
var detail_btn = '<a>' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:label-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:label-list" %}?sort=name',
columns: [
{data: "id"}, {data: "name" }, {data: "value" },
{data: "asset_count" }, {data: "id"}
],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
}
$(document).ready(function(){
initTable();
})
.on('click', '.btn-delete', function () {
var $this = $(this);
var $data_table = $('#label_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:label-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
});
</script>
{% endblock %}

View File

@@ -0,0 +1,166 @@
{% 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 'Assets' %}
</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-8" 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>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-4" 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 'Push system user now' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs btn-push" style="width: 54px">{% trans 'Push' %}</button>
</span>
</td>
</tr>
<tr>
<td width="50%">{% trans 'Test assets connective' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs btn-test-connective" style="width: 54px">{% trans 'Test' %}</button>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
function initAssetsTable() {
var unreachable = {{ system_user.unreachable_assets|safe}};
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=DEFAULT_PK %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData) {
if (unreachable.indexOf(cellData) >= 0) {
$(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" %}?system_user_id={{ system_user.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" }, {data: "hostname" }],
op_html: $('#actions').html()
};
jumpserver.initServerSideDataTable(options);
}
$(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];
});
initAssetsTable();
})
.on('click', '.btn-push', function () {
var the_url = "{% url 'api-assets:system-user-push' pk=system_user.id %}";
var error = function (data) {
alert(data)
};
APIUpdateAttr({
url: the_url,
error: error,
method: 'GET',
success_message: "{% trans "Task has been send, Go to ops task list seen result" %}"
});
})
.on('click', '.btn-test-connective', function () {
var the_url = "{% url 'api-assets:system-user-connective' pk=system_user.id %}";
var error = function (data) {
alert(data)
};
APIUpdateAttr({
url: the_url,
error: error,
method: 'GET',
success_message: "{% trans "Task has been send, seen left assets status" %}"
});
})
</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,323 @@
{% 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>{% trans 'Update' %}</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-danger btn-del">
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-8" 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 '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-4" 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 'Auto push' %}:</td>
<td>
<span class="pull-right">
<div class="switch">
<div class="onoffswitch">
<input type="checkbox" {% if system_user.auto_push %} checked {% endif %} class="onoffswitch-checkbox" id="btn-auto-push">
<label class="onoffswitch-label" for="btn-auto-push">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
</div>
</span>
</td>
</tr>
<tr class="no-borders-tr">
{% if system_user.auto_push %}
<td width="50%">{% trans 'Push system user now' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs btn-push" style="width: 54px">{% trans 'Push' %}</button>
</span>
</td>
</tr>
<tr>
{% endif %}
<td width="50%">{% trans 'Test assets connective' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs btn-test-connective" style="width: 54px">{% trans 'Test' %}</button>
</span>
</td>
</tr>
{# <tr>#}
{# <td width="50%">{% trans 'Change auth period' %}:</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 'Nodes' %}
</div>
<div class="panel-body">
<table class="table node_edit" id="add-asset2group">
<tbody>
<form>
<tr>
<td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Add to node' %}" id="node_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for node in nodes_remain %}
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td colspan="2" class="no-borders">
<button type="button" class="btn btn-info btn-sm" id="btn-add-to-node">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
{% for node in system_user.nodes.all %}
<tr>
<td ><b class="bdg_node" data-gid={{ node.id }}>{{ node }}</b></td>
<td>
<button class="btn btn-danger pull-right btn-xs btn-remove-from-node" type="button"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
function updateSystemUserNode(nodes) {
var the_url = "{% url 'api-assets:system-user-detail' pk=system_user.id %}";
var body = {
nodes: Object.assign([], nodes)
};
var success = function(data) {
// remove all the selected groups from select > option and rendered ul element;
$('.select2-selection__rendered').empty();
$('#node_selected').val('');
$.map(jumpserver.nodes_selected, function(node_name, index) {
$('#opt_' + index).remove();
// change tr html of user groups.
$('.node_edit tbody').append(
'<tr>' +
'<td><b class="bdg_node" data-gid="' + index + '">' + node_name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn-remove-from-node" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
// clear jumpserver.groups_selected
jumpserver.nodes_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
jumpserver.nodes_selected = {};
$(document).ready(function () {
$('.select2').select2()
.on('select2:select', function(evt) {
var data = evt.params.data;
jumpserver.nodes_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.nodes_selected[data.id];
});
})
.on('click', '#btn-auto-push', function () {
var checked = $(this).prop('checked');
var the_url = "{% url 'api-assets:system-user-detail' pk=system_user.id %}";
var body = {
'auto_push': checked
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body)
});
})
.on('click', '#btn-add-to-node', function() {
if (Object.keys(jumpserver.nodes_selected).length === 0) {
return false;
}
var nodes = $('.bdg_node').map(function() {
return $(this).data('gid');
}).get();
$.map(jumpserver.nodes_selected, function(value, index) {
nodes.push(index);
});
updateSystemUserNode(nodes);
})
.on('click', '.btn-remove-from-node', function() {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_node');
var gid = $badge.data('gid');
var node_name = $badge.html() || $badge.text();
$('#groups_selected').append(
'<option value="' + gid + '" id="opt_' + gid + '">' + node_name + '</option>'
);
$tr.remove();
var nodes = $('.bdg_node').map(function () {
return $(this).data('gid');
}).get();
updateSystemUserNode(nodes);
}).on('click', '.btn-del', function () {
var $this = $(this);
var name = "{{ system_user.name}}";
var uid = "{{ system_user.id }}";
var the_url = '{% url "api-assets:system-user-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
var redirect_url = "{% url 'assets:system-user-list' %}";
objectDelete($this, name, the_url, redirect_url);
})
.on('click', '.btn-push', function () {
var the_url = "{% url 'api-assets:system-user-push' pk=system_user.id %}";
var success = function (data) {
var task_id = data.task;
var url = '{% url "ops:celery-task-log" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", task_id);
window.open(url, '', 'width=800,height=600')
};
APIUpdateAttr({
url: the_url,
method: 'GET',
success: success,
flash_message: false
});
})
.on('click', '.btn-test-connective', function () {
var the_url = "{% url 'api-assets:system-user-connective' pk=system_user.id %}";
var success = function (data) {
var task_id = data.task;
var url = '{% url "ops:celery-task-log" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", task_id);
window.open(url, '', 'width=800,height=600')
};
APIUpdateAttr({
url: the_url,
method: 'GET',
success: success,
flash_message: false
});
})
</script>
{% endblock %}

View File

@@ -0,0 +1,174 @@
{% extends '_base_list.html' %}
{% load i18n %}
{% block help_message %}
<div class="alert alert-info help-message">
系统用户是 Jumpserver跳转登录资产时使用的用户可以理解为登录资产用户如 web, sa, dba(`ssh web@some-host`), 而不是使用某个用户的用户名跳转登录服务器(`ssh xiaoming@some-host`);
简单来说是 用户使用自己的用户名登录Jumpserver, Jumpserver使用系统用户登录资产。
系统用户创建时,如果选择了自动推送 Jumpserver会使用ansible自动推送系统用户到资产中如果资产(交换机、windows)不支持ansible, 请手动填写账号密码。
目前还不支持Windows的自动推送
</div>
{% endblock %}
{% block table_search %}
{% endblock %}
{% block table_container %}
<div class="uc pull-left 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 'Protocol' %}</th>
<th class="text-center">{% trans 'Asset' %}</th>
<th class="text-center">{% trans 'Reachable' %}</th>
<th class="text-center">{% trans 'Unreachable' %}</th>
<th class="text-center">{% trans 'Ratio' %}</th>
<th class="text-center">{% trans 'Comment' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
{% endblock %}
{% block custom_foot_js %}
<script>
function initTable() {
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=DEFAULT_PK %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
}},
{targets: 5, createdCell: function (td, cellData) {
var innerHtml = "";
if (cellData !== 0) {
innerHtml = "<span class='text-navy'>" + cellData + "</span>";
} else {
innerHtml = "<span>" + cellData + "</span>";
}
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData +'">' + innerHtml + '</span>');
}},
{targets: 6, createdCell: function (td, cellData) {
var innerHtml = "";
if (cellData !== 0) {
innerHtml = "<span class='text-danger'>" + cellData + "</span>";
} else {
innerHtml = "<span>" + cellData + "</span>";
}
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
}},
{targets: 7, createdCell: function (td, cellData, rowData) {
var val = 0;
var innerHtml = "";
var total = rowData.assets_amount;
var reachable = rowData.reachable_amount;
if (total !== 0) {
val = reachable/total * 100;
}
if (val === 100) {
innerHtml = "<span class='text-navy'>" + val + "% </span>";
} else {
var num = new Number(val);
innerHtml = "<span class='text-danger'>" + num.toFixed(1) + "% </span>";
}
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
}},
{targets: 9, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:system-user-update" pk=DEFAULT_PK %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
$(td).html(update_btn + del_btn)
}}],
ajax_url: '{% url "api-assets:system-user-list" %}',
columns: [
{data: "id" }, {data: "name" }, {data: "username" }, {data: "protocol"}, {data: "assets_amount" },
{data: "reachable_amount"}, {data: "unreachable_amount"}, {data: "id"}, {data: "comment" }, {data: "id" }
],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
}
$(document).ready(function(){
initTable();
})
.on('click', '.btn_admin_user_delete', function () {
var $this = $(this);
var $data_table = $('#cluster_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=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', 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,24 @@
{% extends 'assets/_system_user.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% block auth %}
<h3>{% trans 'Auth' %}</h3>
{% bootstrap_field form.password layout="horizontal" %}
{% bootstrap_field form.private_key_file layout="horizontal" %}
<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>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
$('.select2').select2();
})
</script>
{% endblock %}

View File

@@ -0,0 +1,171 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
<script src="{% static 'js/jquery.form.min.js' %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content">
<div class="row">
<div class="col-lg-3" id="split-left" style="padding-left: 3px">
<div class="ibox float-e-margins">
<div class="ibox-content mailbox-content" style="padding-top: 0;padding-left: 1px">
<div class="file-manager ">
<div id="assetTree" class="ztree">
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<div class="col-lg-9 animated fadeInRight" id="split-right">
<div class="tree-toggle">
<div class="btn btn-sm btn-primary tree-toggle-btn" onclick="toggle()">
<i class="fa fa-angle-left fa-x" id="toggle-icon"></i>
</div>
</div>
<div class="mail-box-header">
<div class="btn-group" style="float: right">
<button data-toggle="dropdown" class="btn btn-default btn-sm dropdown-toggle">{% trans 'Label' %} <span class="caret"></span></button>
<ul class="dropdown-menu labels">
{% for label in labels %}
<li><a style="font-weight: bolder">{{ label.name }}:{{ label.value }}</a></li>
{% endfor %}
</ul>
</div>
<table class="table table-striped table-bordered table-hover " id="user_assets_table" style="width: 100%">
<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 'Active' %}</th>
<th class="text-center">{% trans 'System users' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
var zTree, rMenu, asset_table;
var inited = false;
var url;
function initTable() {
if (inited){
return
} else {
inited = true;
}
var options = {
ele: $('#user_assets_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
{% url 'assets:asset-detail' pk=DEFAULT_PK as the_url %}
var detail_btn = '<a href="{{ the_url }}">' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', 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) {
var users = [];
$.each(cellData, function (id, data) {
users.push(data.name);
});
$(td).html(users.join(', '))
}}
],
ajax_url: url,
columns: [
{data: "id"}, {data: "hostname" }, {data: "ip" },
{data: "is_active", orderable: false },
{data: "system_users_granted", orderable: false}
]
};
asset_table = jumpserver.initDataTable(options);
return asset_table
}
function onSelected(event, treeNode) {
console.log("select");
url = '{% url "api-perms:my-node-assets" node_id=DEFAULT_PK %}';
url = url.replace("{{ DEFAULT_PK }}", treeNode.id);
initTable();
setCookie('node_selected', treeNode.id);
asset_table.ajax.url(url);
asset_table.ajax.reload();
}
function selectQueryNode() {
var query_node_id = $.getUrlParam("node");
var cookie_node_id = getCookie('node_selected');
var node;
var node_id;
if (query_node_id !== null) {
node_id = query_node_id
} else if (cookie_node_id !== null) {
node_id = cookie_node_id;
}
node = zTree.getNodesByParam("id", node_id, null);
if (node){
zTree.selectNode(node[0]);
}
}
function initTree() {
var setting = {
view: {
dblClickExpand: false,
showLine: true
},
data: {
simpleData: {
enable: true
}
},
callback: {
onSelected: onSelected
}
};
var zNodes = [];
$.get("{% url 'api-perms:my-nodes' %}", function(data, status){
$.each(data, function (index, value) {
value["pId"] = value["parent"];
if (value["key"] === "0") {
value["open"] = true;
}
value["name"] = value["value"]
});
zNodes = data;
$.fn.zTree.init($("#assetTree"), setting, zNodes);
zTree = $.fn.zTree.getZTreeObj("assetTree");
rMenu = $("#rMenu");
selectQueryNode();
});
}
$(document).ready(function () {
initTree();
});
</script>
{% endblock %}

View File

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

View File

@@ -0,0 +1,12 @@
from collections import defaultdict
from django import template
register = template.Library()
@register.filter
def group_labels(queryset):
grouped = defaultdict(list)
for label in queryset:
grouped[label.name].append(label)
return [(name, labels) for name, labels in grouped.items()]

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,52 @@
# coding:utf-8
from django.conf.urls import url
from .. import api
from rest_framework_bulk.routes import BulkRouter
app_name = 'assets'
router = BulkRouter()
router.register(r'v1/assets', api.AssetViewSet, 'asset')
router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user')
router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user')
router.register(r'v1/labels', api.LabelViewSet, 'label')
router.register(r'v1/nodes', api.NodeViewSet, 'node')
router.register(r'v1/domain', api.DomainViewSet, 'domain')
router.register(r'v1/gateway', api.GatewayViewSet, 'gateway')
urlpatterns = [
url(r'^v1/assets-bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'),
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/auth-info/', api.SystemUserAuthInfoApi.as_view(),
name='system-user-auth-info'),
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/refresh/$',
api.AssetRefreshHardwareApi.as_view(), name='asset-refresh'),
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/alive/$',
api.AssetAdminUserTestApi.as_view(), name='asset-alive-test'),
url(r'^v1/assets/user-assets/$',
api.UserAssetListView.as_view(), name='user-asset-list'),
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$',
api.ReplaceNodesAdminUserApi.as_view(), name='replace-nodes-admin-user'),
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/auth/$',
api.AdminUserAuthApi.as_view(), name='admin-user-auth'),
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$',
api.AdminUserTestConnectiveApi.as_view(), name='admin-user-connective'),
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/push/$',
api.SystemUserPushApi.as_view(), name='system-user-push'),
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$',
api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$', api.NodeChildrenApi.as_view(), name='node-children'),
url(r'^v1/nodes/children/$', api.NodeChildrenApi.as_view(), name='node-children-2'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/add/$', api.NodeAddChildrenApi.as_view(), name='node-add-children'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', api.NodeAssetsApi.as_view(), name='node-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$', api.NodeAddAssetsApi.as_view(), name='node-add-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/replace/$', api.NodeReplaceAssetsApi.as_view(), name='node-replace-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$', api.NodeRemoveAssetsApi.as_view(), name='node-remove-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/refresh-hardware-info/$', api.RefreshNodeHardwareInfoApi.as_view(), name='node-refresh-hardware-info'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$', api.TestNodeConnectiveApi.as_view(), name='node-test-connective'),
url(r'^v1/gateway/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$', api.GatewayTestConnectionApi.as_view(), name='test-gateway-connective'),
]
urlpatterns += router.urls

View File

@@ -0,0 +1,53 @@
# 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-9a-zA-Z\-]{36})/$', views.AssetDetailView.as_view(), name='asset-detail'),
url(r'^asset/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.AssetUpdateView.as_view(), name='asset-update'),
url(r'^asset/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.AssetDeleteView.as_view(), name='asset-delete'),
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 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-9a-zA-Z\-]{36})/$', views.AdminUserDetailView.as_view(), name='admin-user-detail'),
url(r'^admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.AdminUserUpdateView.as_view(), name='admin-user-update'),
url(r'^admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.AdminUserDeleteView.as_view(), name='admin-user-delete'),
url(r'^admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', views.AdminUserAssetsView.as_view(), name='admin-user-assets'),
# 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-9a-zA-Z\-]{36})/$', views.SystemUserDetailView.as_view(), name='system-user-detail'),
url(r'^system-user/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.SystemUserUpdateView.as_view(), name='system-user-update'),
url(r'^system-user/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.SystemUserDeleteView.as_view(), name='system-user-delete'),
url(r'^system-user/(?P<pk>[0-9a-zA-Z\-]{36})/asset/$', views.SystemUserAssetView.as_view(), name='system-user-asset'),
url(r'^label/$', views.LabelListView.as_view(), name='label-list'),
url(r'^label/create/$', views.LabelCreateView.as_view(), name='label-create'),
url(r'^label/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.LabelUpdateView.as_view(), name='label-update'),
url(r'^label/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.LabelDeleteView.as_view(), name='label-delete'),
url(r'^domain/$', views.DomainListView.as_view(), name='domain-list'),
url(r'^domain/create/$', views.DomainCreateView.as_view(), name='domain-create'),
url(r'^domain/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.DomainDetailView.as_view(), name='domain-detail'),
url(r'^domain/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.DomainUpdateView.as_view(), name='domain-update'),
url(r'^domain/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.DomainDeleteView.as_view(), name='domain-delete'),
url(r'^domain/(?P<pk>[0-9a-zA-Z\-]{36})/gateway/$', views.DomainGatewayListView.as_view(), name='domain-gateway-list'),
url(r'^domain/(?P<pk>[0-9a-zA-Z\-]{36})/gateway/create/$', views.DomainGatewayCreateView.as_view(), name='domain-gateway-create'),
url(r'^domain/gateway/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.DomainGatewayUpdateView.as_view(), name='domain-gateway-update'),
]

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

@@ -0,0 +1,81 @@
# ~*~ coding: utf-8 ~*~
#
import paramiko
from common.utils import get_object_or_none
from .models import Asset, SystemUser, Label
def get_assets_by_id_list(id_list):
return Asset.objects.filter(id__in=id_list)
def get_assets_by_hostname_list(hostname_list):
return Asset.objects.filter(hostname__in=hostname_list)
def get_system_user_by_name(name):
system_user = get_object_or_none(SystemUser, name=name)
return system_user
class LabelFilter:
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
query_keys = self.request.query_params.keys()
all_label_keys = Label.objects.values_list('name', flat=True)
valid_keys = set(all_label_keys) & set(query_keys)
labels_query = {}
for key in valid_keys:
labels_query[key] = self.request.query_params.get(key)
conditions = []
for k, v in labels_query.items():
query = {'labels__name': k, 'labels__value': v}
conditions.append(query)
if conditions:
for kwargs in conditions:
queryset = queryset.filter(**kwargs)
return queryset
def test_gateway_connectability(gateway):
"""
Test system cant connect his assets or not.
:param gateway:
:return:
"""
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
proxy_command = [
"ssh", "{}@{}".format(gateway.username, gateway.ip),
"-p", str(gateway.port), "-W", "127.0.0.1:{}".format(gateway.port),
]
if gateway.password:
proxy_command.insert(0, "sshpass -p '{}'".format(gateway.password))
if gateway.private_key:
proxy_command.append("-i {}".format(gateway.private_key_file))
try:
sock = paramiko.ProxyCommand(" ".join(proxy_command))
except paramiko.ProxyCommandFailure as e:
return False, str(e)
try:
client.connect("127.0.0.1", port=gateway.port,
username=gateway.username,
password=gateway.password,
key_filename=gateway.private_key_file,
sock=sock,
timeout=5
)
except (paramiko.SSHException, paramiko.ssh_exception.SSHException,
paramiko.AuthenticationException, TimeoutError) as e:
return False, str(e)
finally:
client.close()
return True, None

View File

@@ -0,0 +1,6 @@
# coding:utf-8
from .asset import *
from .system_user import *
from .admin_user import *
from .label import *
from .domain import *

View File

@@ -0,0 +1,116 @@
# coding:utf-8
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.conf import settings
from django.urls import reverse_lazy
from django.views.generic import TemplateView, ListView
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin
from common.const import create_success_msg, update_success_msg
from .. import forms
from ..models import AdminUser, Node
from ..hands import AdminUserRequiredMixin
__all__ = [
'AdminUserCreateView', 'AdminUserDetailView',
'AdminUserDeleteView', 'AdminUserListView',
'AdminUserUpdateView', 'AdminUserAssetsView',
]
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().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')
success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create admin user')
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class AdminUserUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
model = AdminUser
form_class = forms.AdminUserForm
template_name = 'assets/admin_user_create_update.html'
success_url = reverse_lazy('assets:admin-user-list')
success_message = update_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Update admin user'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class AdminUserDetailView(AdminUserRequiredMixin, DetailView):
model = AdminUser
template_name = 'assets/admin_user_detail.html'
context_object_name = 'admin_user'
object = None
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Admin user detail'),
'nodes': Node.objects.all()
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class AdminUserAssetsView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
paginate_by = settings.DISPLAY_PER_PAGE
template_name = 'assets/admin_user_assets.html'
context_object_name = 'admin_user'
object = None
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=AdminUser.objects.all())
return super().get(request, *args, **kwargs)
def get_queryset(self):
self.queryset = self.object.asset_set.all()
return self.queryset
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Admin user detail'),
"total_amount": len(self.queryset),
'unreachable_amount': len([asset for asset in self.queryset if asset.is_connective is False])
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class AdminUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = AdminUser
template_name = 'delete_confirm.html'
success_url = reverse_lazy('assets:admin-user-list')

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

@@ -0,0 +1,342 @@
# 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 django.conf import settings
from django.db import transaction
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
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import 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 redirect
from django.contrib.messages.views import SuccessMessageMixin
from common.mixins import JSONResponseMixin
from common.utils import get_object_or_none, get_logger, is_uuid
from common.const import create_success_msg, update_success_msg
from .. import forms
from ..models import Asset, AdminUser, SystemUser, Label, Node, Domain
from ..hands import AdminUserRequiredMixin
__all__ = [
'AssetListView', 'AssetCreateView', 'AssetUpdateView',
'UserAssetListView', 'AssetBulkUpdateView', 'AssetDetailView',
'AssetDeleteView', 'AssetExportView', 'BulkImportAssetView',
]
logger = get_logger(__file__)
class AssetListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/asset_list.html'
def get_context_data(self, **kwargs):
Node.root()
context = {
'app': _('Assets'),
'action': _('Asset list'),
'labels': Label.objects.all().order_by('name'),
'nodes': Node.objects.all().order_by('-key'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class UserAssetListView(LoginRequiredMixin, TemplateView):
template_name = 'assets/user_asset_list.html'
def get_context_data(self, **kwargs):
context = {
'action': _('My assets'),
'system_users': SystemUser.objects.all(),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class AssetCreateView(AdminUserRequiredMixin, SuccessMessageMixin, 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):
# print("form valid")
# asset = form.save()
# asset.created_by = self.request.user.username or 'Admin'
# asset.date_created = timezone.now()
# asset.save()
# return super().form_valid(form)
def get_form(self, form_class=None):
form = super().get_form(form_class=form_class)
node_id = self.request.GET.get("node_id")
if node_id:
node = get_object_or_none(Node, id=node_id)
else:
node = Node.root()
form["nodes"].initial = node
return form
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create asset'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
def get_success_message(self, cleaned_data):
return create_success_msg % ({"name": cleaned_data["hostname"]})
# class AssetModalListView(AdminUserRequiredMixin, ListView):
# paginate_by = settings.DISPLAY_PER_PAGE
# model = Asset
# context_object_name = 'asset_modal_list'
# template_name = 'assets/_asset_list_modal.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().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')
id_list = None
form = None
def get(self, request, *args, **kwargs):
assets_id = self.request.GET.get('assets_id', '')
self.id_list = [i for i in assets_id.split(',')]
if kwargs.get('form'):
self.form = kwargs['form']
elif assets_id:
self.form = self.form_class(
initial={'assets': self.id_list}
)
else:
self.form = self.form_class()
return super().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):
context = {
'app': _('Assets'),
'action': _('Bulk update asset'),
'form': self.form,
'assets_selected': self.id_list,
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class AssetUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, 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().get_context_data(**kwargs)
def get_success_message(self, cleaned_data):
return update_success_msg % ({"name": cleaned_data["hostname"]})
class AssetDeleteView(AdminUserRequiredMixin, DeleteView):
model = Asset
template_name = '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):
nodes_remain = Node.objects.exclude(assets=self.object)
context = {
'app': _('Assets'),
'action': _('Asset detail'),
'nodes_remain': nodes_remain,
}
kwargs.update(context)
return super().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 []
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]
writer.writerow(header)
for asset in assets:
data = [getattr(asset, field.name) for field in fields]
writer.writerow(data)
return response
def post(self, request, *args, **kwargs):
try:
assets_id = json.loads(request.body).get('assets_id', [])
assets_node_id = json.loads(request.body).get('node_id', None)
except ValueError:
return HttpResponse('Json object not valid', status=400)
if not assets_id and assets_node_id:
assets_node = get_object_or_none(Node, id=assets_node_id)
assets = assets_node.get_all_assets()
for asset in assets:
assets_id.append(asset.id)
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):
node_id = self.request.GET.get("node_id")
node = get_object_or_none(Node, id=node_id) if node_id else Node.root()
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}
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_raw = dict(zip(attr, row))
asset_dict = dict()
for k, v in asset_dict_raw.items():
v = v.strip()
if k == 'is_active':
v = False if v in ['False', 0, 'false'] else True
elif k == 'admin_user':
v = get_object_or_none(AdminUser, name=v)
elif k in ['port', 'cpu_count', 'cpu_cores']:
try:
v = int(v)
except ValueError:
v = ''
elif k == 'domain':
v = get_object_or_none(Domain, name=v)
if v != '':
asset_dict[k] = v
asset = get_object_or_none(Asset, id=asset_dict.pop('id', 0))
if not asset:
try:
if len(Asset.objects.filter(hostname=asset_dict.get('hostname'))):
raise Exception(_('already exists'))
with transaction.atomic():
asset = Asset.objects.create(**asset_dict)
if node:
asset.nodes.set([node])
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 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)))
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)

154
apps/assets/views/domain.py Normal file
View File

@@ -0,0 +1,154 @@
# -*- coding: utf-8 -*-
#
from django.views.generic import TemplateView, CreateView, \
UpdateView, DeleteView, DetailView
from django.views.generic.detail import SingleObjectMixin
from django.utils.translation import ugettext_lazy as _
from django.urls import reverse_lazy, reverse
from common.mixins import AdminUserRequiredMixin
from common.const import create_success_msg, update_success_msg
from common.utils import get_object_or_none
from ..models import Domain, Gateway
from ..forms import DomainForm, GatewayForm
__all__ = (
"DomainListView", "DomainCreateView", "DomainUpdateView",
"DomainDetailView", "DomainDeleteView", "DomainGatewayListView",
"DomainGatewayCreateView", 'DomainGatewayUpdateView',
)
class DomainListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/domain_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Domain list'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class DomainCreateView(AdminUserRequiredMixin, CreateView):
model = Domain
template_name = 'assets/domain_create_update.html'
form_class = DomainForm
success_url = reverse_lazy('assets:domain-list')
success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create domain'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class DomainUpdateView(AdminUserRequiredMixin, UpdateView):
model = Domain
template_name = 'assets/domain_create_update.html'
form_class = DomainForm
success_url = reverse_lazy('assets:domain-list')
success_message = update_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Update domain'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class DomainDetailView(AdminUserRequiredMixin, DetailView):
model = Domain
template_name = 'assets/domain_detail.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Domain detail'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class DomainDeleteView(AdminUserRequiredMixin, DeleteView):
model = Domain
template_name = 'delete_confirm.html'
success_url = reverse_lazy('assets:domain-list')
class DomainGatewayListView(AdminUserRequiredMixin, SingleObjectMixin, TemplateView):
template_name = 'assets/domain_gateway_list.html'
model = Domain
object = None
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=self.model.objects.all())
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Domain gateway list'),
'object': self.get_object()
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class DomainGatewayCreateView(AdminUserRequiredMixin, CreateView):
model = Gateway
template_name = 'assets/gateway_create_update.html'
form_class = GatewayForm
success_message = create_success_msg
def get_success_url(self):
domain = self.object.domain
return reverse('assets:domain-gateway-list', kwargs={"pk": domain.id})
def get_form(self, form_class=None):
form = super().get_form(form_class=form_class)
domain_id = self.kwargs.get("pk")
domain = get_object_or_none(Domain, id=domain_id)
if domain:
form['domain'].initial = domain
return form
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create gateway'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class DomainGatewayUpdateView(AdminUserRequiredMixin, UpdateView):
model = Gateway
template_name = 'assets/gateway_create_update.html'
form_class = GatewayForm
success_message = update_success_msg
def get_success_url(self):
domain = self.object.domain
return reverse('assets:domain-gateway-list', kwargs={"pk": domain.id})
def form_valid(self, form):
response = super().form_valid(form)
print(form.cleaned_data)
return response
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Update gateway'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)

View File

@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
#
from django.views.generic import TemplateView, CreateView, \
UpdateView, DeleteView, DetailView
from django.utils.translation import ugettext_lazy as _
from django.urls import reverse_lazy
from common.mixins import AdminUserRequiredMixin
from common.const import create_success_msg, update_success_msg
from ..models import Label
from ..forms import LabelForm
__all__ = (
"LabelListView", "LabelCreateView", "LabelUpdateView",
"LabelDetailView", "LabelDeleteView",
)
class LabelListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/label_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Label list'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class LabelCreateView(AdminUserRequiredMixin, CreateView):
model = Label
template_name = 'assets/label_create_update.html'
form_class = LabelForm
success_url = reverse_lazy('assets:label-list')
success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create label'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class LabelUpdateView(AdminUserRequiredMixin, UpdateView):
model = Label
template_name = 'assets/label_create_update.html'
form_class = LabelForm
success_url = reverse_lazy('assets:label-list')
success_message = update_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Update label'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class LabelDetailView(AdminUserRequiredMixin, DetailView):
pass
class LabelDeleteView(AdminUserRequiredMixin, DeleteView):
model = Label
template_name = 'delete_confirm.html'
success_url = reverse_lazy('assets:label-list')

View File

@@ -0,0 +1,99 @@
# ~*~ coding: utf-8 ~*~
from django.utils.translation import ugettext as _
from django.views.generic import TemplateView
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
from common.const import create_success_msg, update_success_msg
from ..forms import SystemUserForm
from ..models import SystemUser, Node
from ..hands import AdminUserRequiredMixin
__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().get_context_data(**kwargs)
class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = SystemUser
form_class = SystemUserForm
template_name = 'assets/system_user_create.html'
success_url = reverse_lazy('assets:system-user-list')
success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create system user'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class SystemUserUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
model = SystemUser
form_class = SystemUserForm
template_name = 'assets/system_user_update.html'
success_url = reverse_lazy('assets:system-user-list')
success_message = update_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Update system user')
}
kwargs.update(context)
return super().get_context_data(**kwargs)
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'),
'nodes_remain': Node.objects.exclude(systemuser=self.object)
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class SystemUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = SystemUser
template_name = 'delete_confirm.html'
success_url = reverse_lazy('assets:system-user-list')
class SystemUserAssetView(AdminUserRequiredMixin, DetailView):
model = SystemUser
template_name = 'assets/system_user_asset.html'
context_object_name = 'system_user'
def get_context_data(self, **kwargs):
context = {
'app': _('assets'),
'action': _('System user asset'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)

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

@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
#
from rest_framework import viewsets
from common.permissions import IsSuperUserOrAppUser
from .models import FTPLog
from .serializers import FTPLogSerializer
class FTPLogViewSet(viewsets.ModelViewSet):
queryset = FTPLog.objects.all()
serializer_class = FTPLogSerializer
permission_classes = (IsSuperUserOrAppUser,)

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

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

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

@@ -0,0 +1,16 @@
import uuid
from django.db import models
from django.utils.translation import ugettext_lazy as _
class FTPLog(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
user = models.CharField(max_length=128, verbose_name=_('User'))
remote_addr = models.CharField(max_length=15, verbose_name=_("Remote addr"), blank=True, null=True)
asset = models.CharField(max_length=1024, verbose_name=_("Asset"))
system_user = models.CharField(max_length=128, verbose_name=_("System user"))
operate = models.CharField(max_length=16, verbose_name=_("Operate"))
filename = models.CharField(max_length=1024, verbose_name=_("Filename"))
is_success = models.BooleanField(default=True, verbose_name=_("Success"))
date_start = models.DateTimeField(auto_now_add=True)

View File

@@ -0,0 +1,13 @@
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from .models import FTPLog
class FTPLogSerializer(serializers.ModelSerializer):
class Meta:
model = FTPLog
fields = '__all__'

View File

@@ -0,0 +1,135 @@
{% extends '_base_list.html' %}
{% load i18n %}
{% load static %}
{% load terminal_tags %}
{% load common_tags %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet">
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
<style>
#search_btn {
margin-bottom: 0;
}
</style>
{% endblock %}
{% block content_left_head %}
{% 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|date:'Y-m-d' }}">
<span class="input-group-addon">to</span>
<input type="text" class="input-sm form-control" style="width: 100px;" name="date_to" value="{{ date_to|date:'Y-m-d' }}">
</div>
</div>
<div class="input-group">
<select class="select2 form-control" name="user">
<option value="">{% trans 'User' %}</option>
{% for u in user_list %}
<option value="{{ u }}" {% if u == user %} selected {% endif %}>{{ u }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<select class="select2 form-control" name="asset">
<option value="">{% trans 'Asset' %}</option>
{% for a in asset_list %}
<option value="{{ a }}" {% if a == asset %} selected {% endif %}>{{ a }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<select class="select2 form-control" name="system_user">
<option value="">{% trans 'System user' %}</option>
{% for su in system_user_list %}
<option value="{{ su }}" {% if su == system_user %} selected {% endif %}>{{ su }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<input type="text" class="form-control input-sm" name="filename" placeholder="{% trans 'Filename' %}" value="{{ filename }}">
</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"></th>
{# <th class="text-center">{% trans 'ID' %}</th>#}
<th class="text-center">{% trans 'User' %}</th>
<th class="text-center">{% trans 'Asset' %}</th>
<th class="text-center">{% trans 'System user' %}</th>
<th class="text-center">{% trans 'Remote addr' %}</th>
<th class="text-center">{% trans 'Operate' %}</th>
<th class="text-center">{% trans 'Filename' %}</th>
<th class="text-center">{% trans 'Success' %}</th>
<th class="text-center">{% trans 'Date start' %}</th>
{# <th class="text-center">{% trans 'Action' %}</th>#}
{% endblock %}
{% block table_body %}
{% for object in object_list %}
<tr class="gradeX">
<td class="text-center"><input type="checkbox" value="{{ object.id }}"></td>
{# <td class="text-center">#}
{# <a href="{% url 'terminal:object-detail' pk=object.id %}">{{ forloop.counter }}</a>#}
{# </td>#}
<td class="text-center">{{ object.user }}</td>
<td class="text-center">{{ object.asset }}</td>
<td class="text-center">{{ object.system_user }}</td>
<td class="text-center">{{ object.remote_addr|default:"" }}</td>
<td class="text-center">{{ object.operate }}</td>
<td class="text-center">{{ object.filename }}</td>
<td class="text-center">
{% if object.is_success %}
<i class="fa fa-check text-navy"></i>
{% else %}
<i class="fa fa-times text-danger"></i>
{% endif %}
</td>
<td class="text-center">{{ object.date_start }}</td>
</tr>
{% endfor %}
{% endblock %}
{% block content_bottom_left %}
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script>
$(document).ready(function() {
$('table').DataTable({
"searching": false,
"paging": false,
"bInfo" : false,
"order": []
});
$('.select2').select2({
dropdownAutoWidth: true,
width: "auto"
});
$('.input-daterange.input-group').datepicker({
format: "yyyy-mm-dd",
todayBtn: "linked",
keyboardNavigation: false,
forceParse: false,
calendarWeeks: true,
autoclose: true
});
})
</script>
{% endblock %}

View File

@@ -0,0 +1,18 @@
# ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals
from django.conf.urls import url
from rest_framework.routers import DefaultRouter
from .. import api
app_name = "audits"
router = DefaultRouter()
router.register(r'v1/ftp-log', api.FTPLogViewSet, 'ftp-log')
urlpatterns = [
# url(r'^v1/celery/task/(?P<pk>[0-9a-zA-Z\-]{36})/log/$', api.CeleryTaskLogApi.as_view(), name='celery-task-log'),
]
urlpatterns += router.urls

View File

@@ -0,0 +1,14 @@
# ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals
from django.conf.urls import url
from .. import views
__all__ = ["urlpatterns"]
app_name = "audits"
urlpatterns = [
url(r'^ftp-log/$', views.FTPLogListView.as_view(), name='ftp-log-list'),
]

54
apps/audits/views.py Normal file
View File

@@ -0,0 +1,54 @@
from django.conf import settings
from django.views.generic import ListView
from django.utils.translation import ugettext as _
from common.mixins import AdminUserRequiredMixin, DatetimeSearchMixin
from .models import FTPLog
class FTPLogListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):
model = FTPLog
template_name = 'audits/ftp_log_list.html'
paginate_by = settings.DISPLAY_PER_PAGE
user = asset = system_user = filename = ''
date_from = date_to = None
def get_queryset(self):
self.queryset = super().get_queryset()
self.user = self.request.GET.get('user')
self.asset = self.request.GET.get('asset')
self.system_user = self.request.GET.get('system_user')
self.filename = self.request.GET.get('filename', '')
filter_kwargs = dict()
filter_kwargs['date_start__gt'] = self.date_from
filter_kwargs['date_start__lt'] = self.date_to
if self.user:
filter_kwargs['user'] = self.user
if self.asset:
filter_kwargs['asset'] = self.asset
if self.system_user:
filter_kwargs['system_user'] = self.system_user
if self.filename:
filter_kwargs['filename__contains'] = self.filename
if filter_kwargs:
self.queryset = self.queryset.filter(**filter_kwargs).order_by('-date_start')
return self.queryset
def get_context_data(self, **kwargs):
context = {
'user_list': FTPLog.objects.values_list('user', flat=True).distinct(),
'asset_list': FTPLog.objects.values_list('asset', flat=True).distinct(),
'system_user_list': FTPLog.objects.values_list('system_user', flat=True).distinct(),
'date_from': self.date_from,
'date_to': self.date_to,
'user': self.user,
'asset': self.asset,
'system_user': self.system_user,
'filename': self.filename,
"app": _("Audits"),
"action": _("FTP log"),
}
kwargs.update(context)
return super().get_context_data(**kwargs)

76
apps/common/README.md Normal file
View File

@@ -0,0 +1,76 @@
# Common app
Common app provide common view, function or others.
Common app shouldn't rely on other apps, because It may lead to cycle
import.
If your want to implement some function or class, you should think
whether other app use or not. If yes, You should make in common.
If the ability more relate to your app tightness, It's mean your app
provide this ability, not common, You should write it on your app utils.
## Celery usage
Jumpserver use celery to run task async. Using redis as the broker, so
you should run a redis instance
#### Run redis
$ yum -y install redis
or
$ docker run -name jumpserver-redis -d -p 6379:6379 redis redis-server
#### Write tasks in app_name/tasks.py
ops/tasks.py
```
from __future__ import absolute_import
import time
from celery import shared_task
from common import celery_app
@shared_task
def longtime_add(x, y):
print 'long time task begins'
# sleep 5 seconds
time.sleep(5)
print 'long time task finished'
return x + y
@celery_app.task(name='hello-world')
def hello():
print 'hello world!'
```
#### Run celery in development
```
$ cd apps
$ celery -A common worker -l info
```
#### Test using task
```
$ ./manage.py shell
>>> from ops.tasks import longtime_add
>>> res = longtime_add.delay(1, 2)
>>> res.get()
```

5
apps/common/__init__.py Normal file
View File

@@ -0,0 +1,5 @@
from __future__ import absolute_import
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.

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