Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
edd60cad
Commit
edd60cad
authored
Aug 15, 2016
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of code.simcu.com:jumpserver/jumpserver
parents
e3223f74
fcd39370
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
922 additions
and
3 deletions
+922
-3
forms.py
apps/assets/forms.py
+35
-0
0001_initial.py
apps/assets/migrations/0001_initial.py
+111
-0
models.py
apps/assets/models.py
+83
-1
asset_add.html
apps/assets/templates/assets/asset_add.html
+198
-0
asset_list.html
apps/assets/templates/assets/asset_list.html
+430
-0
example.html
apps/assets/templates/assets/example.html
+0
-0
urls.py
apps/assets/urls.py
+11
-0
views.py
apps/assets/views.py
+53
-2
urls.py
apps/jumpserver/urls.py
+1
-0
No files found.
apps/assets/forms.py
0 → 100644
View file @
edd60cad
# coding:utf-8
from
django
import
forms
from
.models
import
IDC
,
Asset
,
AssetGroup
class
AssetForm
(
forms
.
ModelForm
):
class
Meta
:
model
=
Asset
fields
=
[
"ip"
,
"other_ip"
,
"hostname"
,
"port"
,
"group"
,
"username"
,
"password"
,
"idc"
,
"mac_addr"
,
"remote_card_ip"
,
"brand"
,
"cpu"
,
"memory"
,
"disk"
,
"os"
,
"cabinet_no"
,
"cabinet_pos"
,
"number"
,
"status"
,
"type"
,
"env"
,
"sn"
,
"is_active"
,
"comment"
]
class
AssetGroupForm
(
forms
.
ModelForm
):
class
Meta
:
model
=
AssetGroup
fields
=
[
"name"
,
"comment"
]
class
IdcForm
(
forms
.
ModelForm
):
class
Meta
:
model
=
IDC
fields
=
[
'name'
,
"bandwidth"
,
"operator"
,
'contact'
,
'phone'
,
'address'
,
'network'
,
'comment'
]
widgets
=
{
'name'
:
forms
.
TextInput
(
attrs
=
{
'placeholder'
:
'Name'
}),
'network'
:
forms
.
Textarea
(
attrs
=
{
'placeholder'
:
'192.168.1.0/24
\n
192.168.2.0/24'
})
}
apps/assets/migrations/0001_initial.py
0 → 100644
View file @
edd60cad
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-08-14 08:12
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
import
django.db.models.deletion
class
Migration
(
migrations
.
Migration
):
initial
=
True
dependencies
=
[
]
operations
=
[
migrations
.
CreateModel
(
name
=
'Asset'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'ip'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
verbose_name
=
'
\u4e3b\u673a
IP'
)),
(
'other_ip'
,
models
.
CharField
(
blank
=
True
,
max_length
=
255
,
null
=
True
,
verbose_name
=
'
\u5176\u4ed6
IP'
)),
(
'remote_card_ip'
,
models
.
CharField
(
blank
=
True
,
max_length
=
16
,
null
=
True
,
verbose_name
=
'
\u8fdc\u63a7\u5361
IP'
)),
(
'hostname'
,
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
'
\u4e3b\u673a\u540d
'
)),
(
'port'
,
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
'
\u7aef\u53e3\u53f7
'
)),
(
'username'
,
models
.
CharField
(
blank
=
True
,
max_length
=
16
,
null
=
True
,
verbose_name
=
'
\u7ba1\u7406\u7528\u6237\u540d
'
)),
(
'password'
,
models
.
CharField
(
blank
=
True
,
max_length
=
256
,
null
=
True
,
verbose_name
=
'
\u5bc6\u7801
'
)),
(
'mac_addr'
,
models
.
CharField
(
blank
=
True
,
max_length
=
20
,
null
=
True
,
verbose_name
=
'MAC
\u5730\u5740
'
)),
(
'brand'
,
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
null
=
True
,
verbose_name
=
'
\u786c\u4ef6\u5382\u5546\u578b\u53f7
'
)),
(
'cpu'
,
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
null
=
True
,
verbose_name
=
'CPU'
)),
(
'memory'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
null
=
True
,
verbose_name
=
'
\u5185\u5b58
'
)),
(
'disk'
,
models
.
CharField
(
blank
=
True
,
max_length
=
1024
,
null
=
True
,
verbose_name
=
'
\u786c\u76d8
'
)),
(
'os'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
null
=
True
,
verbose_name
=
'
\u7cfb\u7edf\u4fe1\u606f
'
)),
(
'cabinet_no'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'
\u673a\u67dc\u53f7
'
)),
(
'cabinet_pos'
,
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
'
\u673a\u5668\u4f4d\u7f6e
'
)),
(
'number'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'
\u8d44\u4ea7\u7f16\u53f7
'
)),
(
'sn'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
null
=
True
,
verbose_name
=
'SN
\u7f16\u53f7
'
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'
\u521b\u5efa\u8005
'
)),
(
'is_active'
,
models
.
BooleanField
(
default
=
True
,
verbose_name
=
'
\u662f\u5426\u6fc0\u6d3b
'
)),
(
'date_added'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)),
(
'comment'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
null
=
True
,
verbose_name
=
'
\u5907\u6ce8
'
)),
],
options
=
{
'db_table'
:
'asset'
,
},
),
migrations
.
CreateModel
(
name
=
'AssetExtend'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
],
),
migrations
.
CreateModel
(
name
=
'AssetGroup'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'name'
,
models
.
CharField
(
max_length
=
64
,
unique
=
True
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'
\u521b\u5efa\u8005
'
)),
(
'comment'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
null
=
True
)),
],
options
=
{
'db_table'
:
'assetgroup'
,
},
),
migrations
.
CreateModel
(
name
=
'IDC'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'name'
,
models
.
CharField
(
max_length
=
32
,
verbose_name
=
'
\u673a\u623f\u540d\u79f0
'
)),
(
'bandwidth'
,
models
.
CharField
(
blank
=
True
,
default
=
''
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'
\u673a\u623f\u5e26\u5bbd
'
)),
(
'contact'
,
models
.
CharField
(
blank
=
True
,
default
=
''
,
max_length
=
16
,
null
=
True
,
verbose_name
=
'
\u8054\u7cfb\u4eba
'
)),
(
'phone'
,
models
.
CharField
(
blank
=
True
,
default
=
''
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'
\u8054\u7cfb\u7535\u8bdd
'
)),
(
'address'
,
models
.
CharField
(
blank
=
True
,
default
=
''
,
max_length
=
128
,
null
=
True
,
verbose_name
=
'
\u673a\u623f\u5730\u5740
'
)),
(
'network'
,
models
.
TextField
(
blank
=
True
,
default
=
''
,
null
=
True
,
verbose_name
=
'IP
\u5730\u5740\u6bb5
'
)),
(
'date_added'
,
models
.
DateField
(
auto_now
=
True
,
null
=
True
)),
(
'operator'
,
models
.
CharField
(
blank
=
True
,
default
=
''
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'
\u8fd0\u8425\u5546
'
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'
\u521b\u5efa\u8005
'
)),
(
'comment'
,
models
.
CharField
(
blank
=
True
,
default
=
''
,
max_length
=
128
,
null
=
True
,
verbose_name
=
'
\u5907\u6ce8
'
)),
],
options
=
{
'db_table'
:
'idc'
,
'verbose_name'
:
'IDC
\u673a\u623f
'
,
'verbose_name_plural'
:
'IDC
\u673a\u623f
'
,
},
),
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'env'
,
field
=
models
.
ManyToManyField
(
blank
=
True
,
related_name
=
'asset_env_extend'
,
to
=
'assets.AssetExtend'
,
verbose_name
=
'
\u6240\u5c5e\u4e3b\u673a\u7ec4\u73af\u5883
'
),
),
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'group'
,
field
=
models
.
ManyToManyField
(
blank
=
True
,
to
=
'assets.AssetGroup'
,
verbose_name
=
'
\u6240\u5c5e\u4e3b\u673a\u7ec4
'
),
),
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'idc'
,
field
=
models
.
ForeignKey
(
blank
=
True
,
null
=
True
,
on_delete
=
django
.
db
.
models
.
deletion
.
SET_NULL
,
to
=
'assets.IDC'
,
verbose_name
=
'
\u673a\u623f
'
),
),
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'status'
,
field
=
models
.
ManyToManyField
(
blank
=
True
,
related_name
=
'asset_status_extend'
,
to
=
'assets.AssetExtend'
,
verbose_name
=
'
\u673a\u5668\u72b6\u6001
'
),
),
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'type'
,
field
=
models
.
ManyToManyField
(
blank
=
True
,
related_name
=
'asset_type_extend'
,
to
=
'assets.AssetExtend'
,
verbose_name
=
'
\u673a\u5668\u7c7b\u578b
'
),
),
]
apps/assets/models.py
View file @
edd60cad
# coding:utf-8
from
__future__
import
unicode_literals
from
django.db
import
models
# Create your models here.
class
AssetGroup
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
64
,
unique
=
True
)
created_by
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"创建者"
)
comment
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
)
def
__unicode__
(
self
):
return
self
.
name
class
Meta
:
db_table
=
'assetgroup'
class
IDC
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
32
,
verbose_name
=
u'机房名称'
)
bandwidth
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
default
=
''
,
verbose_name
=
u'机房带宽'
)
contact
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
,
null
=
True
,
default
=
''
,
verbose_name
=
u'联系人'
)
phone
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
default
=
''
,
verbose_name
=
u'联系电话'
)
address
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
default
=
''
,
verbose_name
=
u"机房地址"
)
network
=
models
.
TextField
(
blank
=
True
,
null
=
True
,
default
=
''
,
verbose_name
=
u"IP地址段"
)
date_added
=
models
.
DateField
(
auto_now
=
True
,
null
=
True
)
operator
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
default
=
''
,
null
=
True
,
verbose_name
=
u"运营商"
)
created_by
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"创建者"
)
comment
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
default
=
''
,
null
=
True
,
verbose_name
=
u"备注"
)
def
__unicode__
(
self
):
return
self
.
name
class
Meta
:
db_table
=
'idc'
verbose_name
=
u"IDC机房"
verbose_name_plural
=
verbose_name
class
AssetExtend
(
models
.
Model
):
pass
class
Asset
(
models
.
Model
):
ip
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
verbose_name
=
"主机IP"
)
other_ip
=
models
.
CharField
(
max_length
=
255
,
blank
=
True
,
null
=
True
,
verbose_name
=
"其他IP"
)
remote_card_ip
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'远控卡IP'
)
hostname
=
models
.
CharField
(
unique
=
True
,
max_length
=
128
,
verbose_name
=
u"主机名"
)
port
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
u"端口号"
)
group
=
models
.
ManyToManyField
(
AssetGroup
,
blank
=
True
,
verbose_name
=
u"所属主机组"
)
username
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"管理用户名"
)
password
=
models
.
CharField
(
max_length
=
256
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"密码"
)
idc
=
models
.
ForeignKey
(
IDC
,
blank
=
True
,
null
=
True
,
on_delete
=
models
.
SET_NULL
,
verbose_name
=
u'机房'
)
mac_addr
=
models
.
CharField
(
max_length
=
20
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"MAC地址"
)
brand
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'硬件厂商型号'
)
cpu
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'CPU'
)
memory
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'内存'
)
disk
=
models
.
CharField
(
max_length
=
1024
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'硬盘'
)
os
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'系统信息'
)
cabinet_no
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'机柜号'
)
cabinet_pos
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
u'机器位置'
)
number
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'资产编号'
)
status
=
models
.
ManyToManyField
(
AssetExtend
,
blank
=
True
,
related_name
=
"asset_status_extend"
,
verbose_name
=
"机器状态"
)
type
=
models
.
ManyToManyField
(
AssetExtend
,
blank
=
True
,
related_name
=
"asset_type_extend"
,
verbose_name
=
"机器类型"
)
env
=
models
.
ManyToManyField
(
AssetExtend
,
blank
=
True
,
related_name
=
"asset_env_extend"
,
verbose_name
=
"所属主机组环境"
)
sn
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"SN编号"
)
created_by
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"创建者"
)
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
u"是否激活"
)
date_added
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)
comment
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"备注"
)
def
__unicode__
(
self
):
return
self
.
ip
class
Meta
:
db_table
=
'asset'
apps/assets/templates/assets/asset_add.html
0 → 100644
View file @
edd60cad
{% extends 'base.html' %}
{% load bootstrap %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
填写资产基本信息
</h5>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<div
class=
"panel blank-panel"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li
class=
"active"
><a
href=
"{% url 'assets:asset-add' %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
单台添加
</a></li>
{#
<li><a
href=
"{% url 'asset_add_batch' %}"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
批量添加
</a></li>
#}
</ul>
</div>
<div
class=
"panel-body"
>
<div
class=
"tab-content"
>
<div
id=
"tab-1"
class=
"ibox float-e-margins tab-pane active"
>
{% if error %}
<div
class=
"alert alert-warning text-center"
>
{{ error }}
</div>
{% endif %}
{% if msg %}
<div
class=
"alert alert-success text-center"
>
{{ msg }}
</div>
{% endif %}
<form
id=
"assetForm"
method=
"post"
class=
"form-horizontal"
>
{% csrf_token %}
{{ form.hostname|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
{{ form.ip|bootstrap_horizontal }}
<p
class=
"col-sm-offset-2"
>
Tips: 如果IP地址不填写, IP默认会设置与主机名一致
</p>
{#
<div
class=
"hr-line-dashed"
></div>
#}
{#
<div
class=
"form-group"
>
#}
{#
<label
for=
"j_group"
class=
"col-sm-2 control-label"
>
管理用户
<span
class=
"red-fonts"
>
*
</span></label>
#}
{#
<div
class=
"col-sm-2"
>
#}
{#
<div
class=
"radio i-checks"
>
#}
{#
<label
style=
"padding-left: 0"
>
#}
{#
<input
type=
"checkbox"
checked=
"checked"
id=
"id_use_default_auth"
name=
"use_default_auth"
><span>
使用默认
</span>
#}
{#
</label>
#}
{#
</div>
#}
{#
</div>
#}
{#
</div>
#}
{#
<p
class=
"col-sm-offset-2"
>
Tips: 管理用户是服务器存在的root或拥有sudo的用户,用来推送系统用户
</p>
#}
{#
<div
class=
"form-group"
id=
"admin_account"
style=
"display: none"
>
#}
{#
<label
class=
"col-sm-2 control-label"
>
<span
class=
"red-fonts"
></span>
</label>
#}
{#
<div
class=
"col-sm-3"
>
#}
{#
<input
type=
"text"
placeholder=
"Username"
name=
"username"
class=
"form-control"
>
#}
{#
</div>
#}
{##}
{#
<label
class=
"col-sm-1 control-label"
>
<span
class=
"red-fonts"
></span>
</label>
#}
{#
<div
class=
"col-sm-4"
>
#}
{#
<input
type=
"password"
placeholder=
"Password"
name=
"password"
class=
"form-control"
>
#}
{#
</div>
#}
{#
</div>
#}
<div
class=
"form-group"
id=
"id_port"
>
<div
class=
"hr-line-dashed"
></div>
<label
class=
"col-sm-2 control-label"
>
端口
<span
class=
"red-fonts"
>
*
</span>
</label>
<div
class=
"col-sm-8"
>
<input
type=
"text"
placeholder=
"Port"
name=
"port"
class=
"form-control"
value=
"{{ default_port }}"
>
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
{{ form.group|bootstrap_horizontal }}
{# {{ af.is_active|bootstrap_horizontal }}#}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
><label
class=
"col-sm-2 control-label"
>
是否激活
<span
class=
"red-fonts"
>
*
</span>
</label>
<div
class=
"col-sm-8"
>
<div
class=
"radio i-checks"
>
<label>
<input
type=
"radio"
checked=
""
value=
"1"
name=
"is_active"
>
激活
</label>
<label>
<input
type=
"radio"
value=
"0"
name=
"is_active"
>
禁用
</label>
</div>
</div>
</div>
<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"
>
重置
</button>
<button
class=
"btn btn-primary"
type=
"submit"
>
提交
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block self_footer_js %}
<script>
$
(
'document'
).
ready
(
function
(){
var
check_default
=
"{{ default_setting.name }}"
;
console
.
log
(
check_default
);
if
(
check_default
!=
'default'
){
$
(
'#id_use_default_auth'
).
attr
(
'disabled'
,
true
);
$
(
'#id_use_default_auth'
).
attr
(
'checked'
,
false
);
$
(
'#admin_account'
).
css
(
'display'
,
'block'
);
}
else
{
$
(
'#id_use_default_auth'
).
click
(
function
(){
if
(
$
(
this
).
is
(
':checked'
)){
$
(
'#admin_account'
).
css
(
'display'
,
'none'
);
}
else
{
$
(
'#admin_account'
).
css
(
'display'
,
'block'
);
}
})
}
});
var
required_fields
=
[
"id_hostname"
,
"id_port"
];
required_fields
.
forEach
(
function
(
field
)
{
$
(
'label[for="'
+
field
+
'"]'
).
parent
().
addClass
(
"required"
);
});
$
(
'#assetForm'
).
validator
({
timely
:
2
,
theme
:
"yellow_right_effect"
,
rules
:
{
check_ip
:
[
/^
(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])(\.(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])){3}
$/
,
'ip地址不正确'
],
check_port
:
[
/^
\d{1,5}
$/
,
'端口号不正确'
],
use_default_auth
:
function
()
{
var
str1
=
$
(
"#id_use_default_auth"
).
is
(
":checked"
);
if
(
str1
==
true
){
var
decide
=
false
;
}
else
{
var
decide
=
true
;
}
return
decide
}
},
fields
:
{
"ip"
:
{
rule
:
"check_ip;"
,
tip
:
"输入IP"
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
},
"hostname"
:
{
rule
:
"required;length[0~53]"
,
tip
:
"填写主机名"
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
},
"port"
:
{
rule
:
"required"
,
tip
:
"输入端口号"
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
},
"username"
:
{
rule
:
"required(use_default_auth)"
,
tip
:
"输入用户名"
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
},
"password"
:
{
rule
:
"required(use_default_auth);length[0~64]"
,
tip
:
"输入密码"
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
}
},
valid
:
function
(
form
)
{
form
.
submit
();
}
});
</script>
{% endblock %}
\ No newline at end of file
apps/assets/templates/assets/asset_list.html
0 → 100644
View file @
edd60cad
{% extends 'base.html' %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-12"
>
<div
class=
"ibox float-e-margins"
id=
"all"
>
<div
class=
"ibox-title"
>
<h5>
主机详细信息列表
</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
id=
"asset_form"
>
<div
class=
"col-sm-1"
style=
"padding-left: 0"
>
<a
href=
"{% url 'assets:asset-add' %}"
class=
"btn btn-sm btn-primary "
>
添加资产
</a>
</div>
<div
class=
"col-sm-7"
style=
"padding-left: 0px"
>
<label>
<select
name=
"idc"
class=
"form-control m-b input-sm"
onchange=
"change_info()"
>
<option
value=
""
>
机房
</option>
{% for idc in idc_all %}
{% ifequal idc.name idc_name %}
<option
value=
"{{idc.name}}"
selected
>
{{ idc.name|slice:":20" }}
</option>
{% else %}
<option
value=
"{{idc.name}}"
>
{{ idc.name|slice:":20" }}
</option>
{% endifequal %}
{% endfor %}
</select>
</label>
<label>
<select
name=
"group"
class=
"form-control m-b input-sm"
onchange=
"change_info()"
>
<option
value=
""
>
主机组
</option>
{% for asset_group in asset_group_all %}
{% ifequal asset_group.name group_name %}
<option
value=
"{{ asset_group.name }}"
selected
>
{{ asset_group.name|slice:":20" }}
</option>
{% else %}
<option
value=
"{{ asset_group.name }}"
>
{{ asset_group.name|slice:":20" }}
</option>
{% endifequal %}
{% endfor %}
</select>
</label>
<label>
<select
name=
"asset_type"
class=
"form-control m-b input-sm"
onchange=
"change_info()"
>
<option
value=
""
>
资产类型
</option>
{# {% for type in asset_types %}#}
{# {% ifequal type.0|int2str asset_type %}#}
{#
<option
value=
"{{ type.0 }}"
selected
>
{{ type.1 }}
</option>
#}
{# {% else %}#}
{#
<option
value=
"{{ type.0 }}"
>
{{ type.1 }}
</option>
#}
{# {% endifequal %}#}
{# {% endfor %}#}
</select>
</label>
<label>
<select
name=
"status"
class=
"form-control m-b input-sm"
onchange=
"change_info()"
>
<option
value=
""
>
资产状态
</option>
{# {% for s in asset_status %}#}
{# {% ifequal s.0|int2str status %}#}
{#
<option
value=
"{{ s.0 }}"
selected
>
{{ s.1 }}
</option>
#}
{# {% else %}#}
{#
<option
value=
"{{ s.0 }}"
>
{{ s.1 }}
</option>
#}
{# {% endifequal %}#}
{# {% endfor %}#}
</select>
</label>
</div>
<div
class=
"col-sm-4"
style=
"padding-right: 0"
>
<div
class=
"input-group inline-group"
>
<input
type=
"text"
class=
"form-control m-b input-sm"
id=
"search_input"
name=
"keyword"
value=
"{{ keyword }}"
placeholder=
"Search"
>
<input
type=
"text"
style=
"display: none"
>
<div
class=
"input-group-btn"
>
<button
id=
'search_btn'
href=
"{% url 'assets:asset-list' %}?search=true"
type=
"button"
class=
"btn btn-sm btn-primary search-btn"
onclick=
"change_info()"
>
- 搜索 -
</button>
<button
type=
"button"
href=
"{% url 'assets:asset-list' %}?export=true"
name=
"export"
class=
"btn btn-sm btn-success search-btn-excel"
onclick=
"return false"
>
- 导出 -
</button>
</div>
</div>
</div>
<div
id=
"export"
></div>
<table
class=
"table table-striped table-bordered table-hover "
id=
"editable"
name=
"editable"
>
<thead>
<tr>
<th
class=
"text-center"
>
<input
id=
"checkall"
type=
"checkbox"
class=
"i-checks"
name=
"checkall"
value=
"checkall"
data-editable=
'false'
onclick=
"check_all('asset_form')"
>
</th>
<th
class=
"text-center"
>
主机名
</th>
<th
class=
"text-center"
name=
"ip"
>
IP地址
</th>
<th
class=
"text-center"
>
IDC
</th>
<th
class=
"text-center"
>
所属主机组
</th>
{#
<th
class=
"text-center"
>
配置信息
</th>
#}
<th
class=
"text-center"
>
操作系统
</th>
<th
class=
"text-center"
>
cpu核数
</th>
<th
class=
"text-center"
>
内存
</th>
<th
class=
"text-center"
>
硬盘
</th>
<th
class=
"text-center"
>
操作
</th>
</tr>
</thead>
<tbody>
{% for asset in assets %}
<tr
class=
"gradeX"
>
<td
class=
"text-center"
name=
"id"
value=
"{{ asset.id }}"
data-editable=
'false'
>
<input
name=
"id"
value=
"{{ asset.id }}"
type=
"checkbox"
class=
"i-checks"
>
</td>
<td
class=
"text-center hostname"
>
<a
href=
"{% url 'assets:asset-detail' %}?id={{ asset.id }}"
>
{{ asset.hostname|default_if_none:"" }}
</a></td>
<td
class=
"text-center"
>
{{ asset.ip|default_if_none:"" }}
</td>
<td
class=
"text-center"
>
{{ asset.idc.name|default_if_none:"" }}
</td>
{#
<td
class=
"text-center"
>
{{ asset.group.all|group_str2 }}
</td>
#}
{#
<td
class=
"text-center"
>
{{ asset.cpu }}|{{ asset.memory }}|{{ asset.disk }}
</td>
#}
<td
class=
"text-center"
>
{{ asset.system_type|default_if_none:"" }}{{ asset.system_version|default_if_none:"" }}
</td>
<td
class=
"text-center"
>
{{ asset.cpu|default_if_none:"" }}
</td>
<td
class=
"text-center"
>
{{ asset.memory|default_if_none:"" }}{% if asset.memory %}G{% endif %}
</td>
<td
class=
"text-center"
>
{{ asset.disk }}{% if asset.disk %}G{% endif %}
</td>
<td
class=
"text-center"
data-editable=
'false'
>
{#
<a
href=
"{% url 'asset_edit' %}?id={{ asset.id }}"
class=
"btn btn-xs btn-info"
>
编辑
</a>
#}
<a
value=
"{{ asset.id }}"
class=
"conn btn btn-xs btn-warning"
>
连接
</a>
{#
<a
value=
"{% url 'asset_del' %}?id={{ asset.id }}"
class=
"btn btn-xs btn-danger asset_del"
>
删除
</a>
#}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div
class=
"row"
>
<div
class=
"col-sm-6"
>
<input
type=
"button"
id=
"asset_del"
class=
"btn btn-danger btn-sm"
name=
"del_button"
value=
"删除"
/>
{#
<a
value=
"{% url 'asset_edit_batch' %}"
type=
"button"
class=
"btn btn-sm btn-warning iframe"
>
修改
</a>
#}
<input
type=
"button"
id=
"asset_update"
class=
"btn btn-info btn-sm"
name=
"update_button"
value=
"更新"
/>
{#
<input
type=
"button"
id=
"asset_update_all"
class=
"btn btn-primary btn-sm"
name=
"update_button"
value=
"更新全部"
/>
#}
<input
type=
"button"
id=
"exec_cmd"
class=
"btn btn-sm btn-primary"
name=
"exec_cmd"
value=
"执行命令"
/>
</div>
{# {% include 'paginator.html' %}#}
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block self_footer_js %}
<script>
$
(
document
).
ready
(
function
(){
$
(
'.asset_del'
).
click
(
function
(){
var
row
=
$
(
this
).
closest
(
'tr'
);
if
(
confirm
(
"确定删除?"
))
{
$
.
get
(
$
(
this
).
attr
(
'value'
),
{},
function
(
data
)
{
row
.
remove
()
}
)
}
});
$
(
'#exec_cmd'
).
click
(
function
(){
var
url
=
'{% url "role_get" %}'
;
var
new_url
=
'{% url "exec_cmd" %}?role='
;
var
check_array
=
[];
$
(
".gradeX input:checked"
).
closest
(
'tr'
).
find
(
'.hostname a'
).
each
(
function
()
{
check_array
.
push
(
$
(
this
).
text
())
});
check_assets
=
check_array
.
join
(
':'
);
$
.
ajax
({
type
:
'GET'
,
url
:
url
,
data
:
{},
success
:
function
(
data
){
var
dataArray
=
data
.
split
(
','
);
if
(
dataArray
.
length
==
1
&&
data
!=
'error'
){
var
title
=
'Jumpserver Exec Terminal'
;
layer
.
open
({
type
:
2
,
title
:
title
,
maxmin
:
true
,
shade
:
false
,
area
:
[
'725px'
,
'600px'
],
content
:
new_url
+
data
+
'&check_assets='
+
check_assets
});
//window.open(new_url + data, '', 'location=no, resizeable=no, height=410, width=625, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,status=no');
}
else
if
(
dataArray
.
length
==
'1'
&&
data
==
'error'
){
layer
.
alert
(
'没有授权系统用户'
)
}
else
{
aUrl
=
''
;
$
.
each
(
dataArray
,
function
(
index
,
value
){
aUrl
+=
'<a onclick="windowOpenExec(this); return false" class="btn btn-xs btn-primary newa" href='
+
new_url
+
value
+
'&check_assets='
+
check_assets
+
'>'
+
value
+
'</a> '
});
layer
.
alert
(
aUrl
,
{
skin
:
'layui-layer-molv'
,
title
:
'授权多个系统用户,请选择一个连接'
,
shade
:
false
,
closeBtn
:
0
})
}
}
});
return
false
});
$
(
'.conn'
).
click
(
function
(){
var
url
=
'{% url "role_get" %}?id='
+
$
(
this
).
attr
(
'value'
);
// 获取用户有权限的角色
var
href
=
$
(
this
).
attr
(
'href'
);
var
new_url
=
'{% url "terminal" %}?id='
+
$
(
this
).
attr
(
'value'
)
+
'&role='
;
// webterminal socket url
var
hostname
=
$
(
this
).
closest
(
'tr'
).
find
(
'.hostname a'
)[
0
].
innerHTML
;
$
.
ajax
({
type
:
'GET'
,
url
:
url
,
data
:
{},
success
:
function
(
data
){
var
dataArray
=
data
.
split
(
','
);
if
(
data
==
'error'
||
data
==
''
||
data
==
null
||
data
==
undefined
){
layer
.
alert
(
'没有授权系统用户'
)
}
else
if
(
dataArray
.
length
==
1
&&
data
!=
'error'
&&
navigator
.
platform
==
'Win32'
){
/*
var title = 'Jumpserver Web Terminal' + '<span class="text-info"> '+ hostname +'</span>';
layer.open({
type: 2,
title: title,
maxmin: true,
shade: false,
area: ['628px', '420px'],
content: new_url+data
});
window.open(new_url+data, '_blank', 'toolbar=yes, location=yes, scrollbars=yes, resizable=yes, copyhistory=yes, width=628, height=400')
*/
window
.
open
(
new_url
+
data
,
"_blank"
);
}
else
if
(
dataArray
.
length
==
1
&&
data
!=
'error'
){
/*layer.open({
type: 2,
title: title,
maxmin: true,
shade: false,
area: ['628px', '452px'],
content: new_url+data
});
*/
window
.
open
(
new_url
+
data
,
'_blank'
);
}
else
{
aUrl
=
''
;
$
.
each
(
dataArray
,
function
(
index
,
value
){
aUrl
+=
'<a onclick="windowOpen(this); return false" class="btn btn-xs btn-primary newa" href='
+
new_url
+
value
+
' value='
+
hostname
+
'>'
+
value
+
'</a> '
});
console
.
log
(
aUrl
);
layer
.
alert
(
aUrl
,
{
skin
:
'layui-layer-molv'
,
title
:
'授权多个系统用户,请选择一个连接'
,
shade
:
false
,
closeBtn
:
0
})
}
}
});
return
false
});
});
function
windowOpen
(
a
){
var
new_url
=
$
(
a
).
attr
(
'href'
);
var
hostname
=
$
(
a
).
attr
(
'value'
);
var
title
=
'Jumpserver Web Terminal - '
+
'<span class="text-info"> '
+
hostname
+
'</span>'
;
if
(
navigator
.
platform
==
'Win32'
){
/*
layer.open({
type: 2,
title: title,
maxmin: true,
area: ['628px', '420px'],
shade: false,
content: new_url
});
*/
window
.
open
(
new_url
,
'_blank'
)
}
else
{
/*
layer.open({
type: 2,
title: title,
maxmin: true,
area: ['628px', '452px'],
shade: false,
content: new_url
});
*/
window
.
open
(
new_url
,
'_blank'
);
}
return
false
}
function
windowOpenExec
(
a
){
var
new_url
=
$
(
a
).
attr
(
'href'
);
var
title
=
'Jumpserver Exec Terminal'
;
layer
.
open
({
type
:
2
,
title
:
title
,
maxmin
:
true
,
area
:
[
'725px'
,
'600px'
],
shade
:
false
,
content
:
new_url
});
return
false
}
$
(
".iframe"
).
on
(
'click'
,
function
(){
var
asset_id_all
=
getIDall
();
if
(
asset_id_all
==
''
){
alert
(
"请至少选择一行!"
);
return
false
;
}
var
url
=
$
(
this
).
attr
(
"value"
)
+
'?asset_id_all='
+
asset_id_all
;
parent
.
layer
.
open
({
type
:
2
,
title
:
'JumpServer - 批量修改主机'
,
maxmin
:
true
,
shift
:
'top'
,
border
:
[
2
,
0.3
,
'#1AB394'
],
shade
:
[
0.5
,
'#000000'
],
area
:
[
'800px'
,
'600px'
],
shadeClose
:
true
,
content
:
url
,
cancel
:
function
(){
location
.
replace
(
location
.
href
);
}
});
});
$
(
'.search-btn-excel'
).
unbind
(
'click'
).
bind
(
'click'
,
function
(){
var
url
=
$
(
this
).
attr
(
"href"
);
$
.
ajax
({
type
:
"GET"
,
url
:
url
,
data
:
$
(
"#asset_form"
).
serialize
(),
success
:
function
(
data
)
{
$
(
"#export"
).
html
(
data
);
}
});
});
$
(
'#asset_del'
).
click
(
function
()
{
var
asset_id_all
=
getIDall
();
if
(
asset_id_all
==
''
){
alert
(
"请至少选择一行!"
);
return
false
;
}
if
(
confirm
(
"确定删除?"
))
{
$
.
ajax
({
type
:
"post"
,
data
:
{
asset_id_all
:
asset_id_all
},
url
:
"{% url 'asset_del' %}?arg=batch"
,
success
:
function
()
{
parent
.
location
.
reload
();
}
});
}
});
$
(
'#asset_update'
).
click
(
function
()
{
var
asset_id_all
=
getIDall
();
if
(
asset_id_all
==
''
){
if
(
confirm
(
"更新全部资产信息?"
))
{
layer
.
msg
(
'玩命更新中...'
,
{
time
:
200000
});
$
.
ajax
({
type
:
"post"
,
url
:
"{% url 'asset_update_batch' %}?arg=all"
,
success
:
function
()
{
parent
.
location
.
reload
();
}
});
}
}
else
{
layer
.
msg
(
'玩命更新中...'
,
{
time
:
200000
});
$
.
ajax
({
type
:
"post"
,
data
:
{
asset_id_all
:
asset_id_all
},
url
:
"{% url 'asset_update_batch' %}"
,
success
:
function
()
{
parent
.
location
.
reload
();
}
});
}
});
{
#
$
(
'#asset_update_all'
).
click
(
function
()
{
#
}
{
#
layer
.
msg
(
'玩命更新中...'
,
{
time
:
200000
});
#
}
{
#
$
.
ajax
({
#
}
{
#
type
:
"post"
,
#
}
{
#
url
:
"/jasset/asset_update_batch/?arg=all"
,
#
}
{
#
success
:
function
()
{
#
}
{
#
parent
.
location
.
reload
();
#
}
{
#
}
#
}
{
#
});
#
}
{
#
});
#
}
function
change_info
(){
var
args
=
$
(
"#asset_form"
).
serialize
();
window
.
location
=
"{% url 'asset_list' %}?"
+
args
}
$
(
"#search_input"
).
keydown
(
function
(
e
){
if
(
e
.
keyCode
==
13
){
change_info
()
}
});
</script>
{% endblock %}
apps/assets/templates/assets/example.html
deleted
100644 → 0
View file @
e3223f74
apps/assets/urls.py
View file @
edd60cad
# coding:utf-8
from
django.conf.urls
import
url
from
.views
import
*
app_name
=
'assets'
urlpatterns
=
[
url
(
r'^add/$'
,
AssetAddView
.
as_view
(),
name
=
'asset-add'
),
url
(
r'^list/$'
,
AssetListView
.
as_view
(),
name
=
'asset-list'
),
url
(
r'^(?P<pk>[0-9]+)/delete/$'
,
AssetDeleteView
.
as_view
(),
name
=
'asset-list'
),
url
(
r'^(?P<pk>[0-9]+)/detail/$'
,
AssetDetailView
.
as_view
(),
name
=
'asset-detail'
),
]
apps/assets/views.py
View file @
edd60cad
from
django.shortcuts
import
render
from
django.views.generic
import
(
TemplateView
,
ListView
)
from
django.urls
import
reverse_lazy
from
django.views.generic.edit
import
(
CreateView
,
DeleteView
,
FormView
,
UpdateView
)
from
django.views.generic.detail
import
(
DetailView
)
from
.models
import
(
Asset
,
AssetGroup
,
IDC
,
AssetExtend
)
from
.forms
import
(
AssetForm
,
)
class
AssetAddView
(
CreateView
):
model
=
Asset
form_class
=
AssetForm
template_name
=
'assets/asset_add.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
class
AssetEdit
():
pass
class
AssetDeleteView
(
DeleteView
):
model
=
Asset
success_url
=
reverse_lazy
(
'assets:asset-list'
)
class
AssetListView
(
ListView
):
model
=
Asset
context_object_name
=
'assets'
template_name
=
'assets/asset_list.html'
class
AssetDetailView
(
DetailView
):
model
=
Asset
context_object_name
=
'asset'
template_name
=
'assets/asset_detail.html'
# Create your views here.
apps/jumpserver/urls.py
View file @
edd60cad
...
...
@@ -18,5 +18,6 @@ from django.conf.urls import url, include
urlpatterns
=
[
url
(
r'^users/'
,
include
(
'users.urls'
)),
url
(
r'^assets/'
,
include
(
'assets.urls'
)),
# url(r'^admin/', admin.site.urls),
]
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment