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
ce5950ca
Commit
ce5950ca
authored
Sep 19, 2016
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
Merge with asset
parents
65461a09
24e31a69
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
575 additions
and
167 deletions
+575
-167
forms.py
apps/assets/forms.py
+55
-10
models.py
apps/assets/models.py
+64
-32
admin_user_list.html
apps/assets/templates/assets/admin_user_list.html
+1
-1
asset_create.html
apps/assets/templates/assets/asset_create.html
+37
-97
asset_detail.html
apps/assets/templates/assets/asset_detail.html
+0
-0
asset_group_list.html
apps/assets/templates/assets/asset_group_list.html
+1
-1
asset_list.html
apps/assets/templates/assets/asset_list.html
+0
-0
asset_update.html
apps/assets/templates/assets/asset_update.html
+82
-0
idc_list.html
apps/assets/templates/assets/idc_list.html
+1
-1
system_user_list.html
apps/assets/templates/assets/system_user_list.html
+1
-1
views.py
apps/assets/views.py
+66
-22
utils.py
apps/common/utils.py
+7
-0
django.po
apps/locale/zh/LC_MESSAGES/django.po
+0
-0
asset_permission_list.html
apps/perms/templates/perms/asset_permission_list.html
+1
-1
inputTags.css
apps/static/css/plugins/inputTags.css
+214
-0
inputTags.jquery.min.js
apps/static/js/plugins/inputTags.jquery.min.js
+0
-0
_base_create_update.html
apps/templates/_base_create_update.html
+37
-0
_base_list.html
apps/templates/_base_list.html
+0
-0
user_create.html
apps/users/templates/users/user_create.html
+1
-0
user_group_list.html
apps/users/templates/users/user_group_list.html
+6
-0
user_list.html
apps/users/templates/users/user_list.html
+1
-1
No files found.
apps/assets/forms.py
View file @
ce5950ca
# coding:utf-8
from
django
import
forms
from
.models
import
IDC
,
Asset
,
AssetGroup
,
AdminUser
,
SystemUser
from
.models
import
IDC
,
Asset
,
AssetGroup
,
AdminUser
,
SystemUser
,
Tag
from
django.utils.translation
import
gettext_lazy
as
_
class
AssetForm
(
forms
.
ModelForm
):
# class AssetForm(forms.ModelForm):
# class Meta:
# model = Asset
#
# fields = [
# 'ip', 'other_ip', 'remote_card_ip', 'hostname', 'port', 'groups', 'username', 'password',
# 'idc', 'mac_address', 'brand', 'cpu', 'memory', 'disk', 'os', 'cabinet_no', 'cabinet_pos',
# 'number', 'status', 'type', 'env', 'sn', 'is_active', 'comment', 'admin_user', 'system_users'
# ]
#
# widgets = {
# 'groups': forms.SelectMultiple(attrs={'class': 'select2-groups', 'data-placeholder': _('Select asset groups')}),
# 'system_user': forms.SelectMultiple(attrs={'class': 'select2-system-user', 'data-placeholder': _('Select asset system user')}),
# 'admin_user': forms.SelectMultiple(attrs={'class': 'select2-admin-user', 'data-placeholder': _('Select asset admin user')}),
# }
#
class
AssetCreateForm
(
forms
.
ModelForm
):
tags
=
forms
.
CharField
(
label
=
_
(
'Tags'
),
widget
=
forms
.
TextInput
(
attrs
=
{
'id'
:
'tags'
}),
required
=
False
,
help_text
=
'Use `,` split'
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
instance
=
kwargs
.
get
(
'instance'
,
None
)
if
instance
:
initial
=
kwargs
.
get
(
'initial'
,
{})
tags
=
instance
.
tags
.
all
()
initial
[
'tags'
]
=
","
.
join
([
tag
.
value
for
tag
in
tags
])
print
(
kwargs
.
get
(
'initial'
))
super
(
AssetCreateForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
_save_m2m
(
self
):
tags
=
self
.
cleaned_data
[
'tags'
]
if
tags
:
value_list
=
tags
.
split
(
','
)
self
.
instance
.
tags
.
all
()
.
delete
()
Tag
.
objects
.
bulk_create
(
[
Tag
(
value
=
value
,
asset
=
self
.
instance
)
for
value
in
value_list
]
)
class
Meta
:
model
=
Asset
fields
=
[
"ip"
,
"other_ip"
,
"remote_card_ip"
,
"hostname"
,
"port"
,
"groups"
,
"username"
,
"password"
,
"idc"
,
"mac_address"
,
"brand"
,
"cpu"
,
"memory"
,
"disk"
,
"os"
,
"cabinet_no"
,
"cabinet_pos"
,
"number"
,
"status"
,
"type"
,
"env"
,
"sn"
,
"is_active"
,
"comment"
,
"admin_user"
,
"system_users"
'hostname'
,
'ip'
,
'port'
,
'type'
,
'comment'
,
'admin_user'
,
'system_users'
,
'idc'
,
'groups'
,
'other_ip'
,
'remote_card_ip'
,
'mac_address'
,
'brand'
,
'cpu'
,
'memory'
,
'disk'
,
'os'
,
'cabinet_no'
,
'cabinet_pos'
,
'number'
,
'status'
,
'env'
,
'sn'
,
]
widgets
=
{
'groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2-groups'
,
'data-placeholder'
:
_
(
'Select asset groups'
)}),
'system_users'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2-system-user'
,
'data-placeholder'
:
_
(
'Select asset system user'
)}),
# 'admin_user': forms.SelectMultiple(attrs={'class': 'select2-admin-user', 'data-placeholder': _('Select asset admin user')}),
'groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select asset groups'
)}),
'system_users'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select asset system users'
)}),
'admin_user'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select asset admin user'
)}),
}
help_texts
=
{
'hostname'
:
'* required'
,
'ip'
:
'* required'
,
}
...
...
@@ -32,7 +77,7 @@ class AssetGroupForm(forms.ModelForm):
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
if
kwargs
.
get
(
'instance'
):
if
kwargs
.
get
(
'instance'
,
None
):
initial
=
kwargs
.
get
(
'initial'
,
{})
initial
[
'assets'
]
=
kwargs
[
'instance'
]
.
assets
.
all
()
super
(
AssetGroupForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
...
apps/assets/models.py
View file @
ce5950ca
# coding:utf-8
from
__future__
import
unicode_literals
,
absolute_import
import
functools
from
django.db
import
models
import
logging
from
django.utils.translation
import
ugettext_lazy
as
_
...
...
@@ -26,6 +27,10 @@ class IDC(models.Model):
def
__unicode__
(
self
):
return
self
.
name
@classmethod
def
initial
(
cls
):
return
cls
.
objects
.
get_or_create
(
name
=
_
(
'Default'
),
created_by
=
_
(
'System'
),
comment
=
_
(
'Default IDC'
))[
0
]
class
Meta
:
db_table
=
'idc'
...
...
@@ -55,10 +60,10 @@ class IDC(models.Model):
class
AssetExtend
(
models
.
Model
):
key
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'KEY'
))
value
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'VALUE'
))
key
=
models
.
CharField
(
max_length
=
64
,
verbose_name
=
_
(
'KEY'
))
value
=
models
.
CharField
(
max_length
=
64
,
verbose_name
=
_
(
'VALUE'
))
created_by
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
verbose_name
=
_
(
"Created by"
))
date_created
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
date_created
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
def
__unicode__
(
self
):
...
...
@@ -83,6 +88,7 @@ class AssetExtend(models.Model):
class
Meta
:
db_table
=
'asset_extend'
unique_together
=
(
'key'
,
'value'
)
class
AdminUser
(
models
.
Model
):
...
...
@@ -249,7 +255,7 @@ class AssetGroup(models.Model):
@classmethod
def
initial
(
cls
):
asset_group
=
cls
(
name
=
_
(
'Default'
),
comm
o
nt
=
_
(
'Default asset group'
))
asset_group
=
cls
(
name
=
_
(
'Default'
),
comm
e
nt
=
_
(
'Default asset group'
))
asset_group
.
save
()
@classmethod
...
...
@@ -271,49 +277,68 @@ class AssetGroup(models.Model):
continue
def
get_default_extend
(
key
,
value
):
try
:
return
AssetExtend
.
objects
.
get_or_create
(
key
=
key
,
value
=
value
)[
0
]
except
:
return
None
def
get_default_idc
():
return
IDC
.
initial
()
class
Asset
(
models
.
Model
):
ip
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'IP'
))
ip
=
models
.
GenericIPAddressField
(
max_length
=
32
,
verbose_name
=
_
(
'IP'
))
other_ip
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Other IP'
))
remote_card_ip
=
models
.
CharField
(
max_length
=
16
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Remote card IP'
))
hostname
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Hostname'
))
port
=
models
.
IntegerField
(
default
=
22
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Port'
))
hostname
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Hostname'
))
port
=
models
.
IntegerField
(
default
=
22
,
verbose_name
=
_
(
'Port'
))
groups
=
models
.
ManyToManyField
(
AssetGroup
,
blank
=
True
,
related_name
=
'assets'
,
verbose_name
=
_
(
'Asset groups'
))
username
=
models
.
CharField
(
max_length
=
16
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Admin user'
))
password
=
models
.
CharField
(
max_length
=
256
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
"Admin password"
))
admin_user
=
models
.
ForeignKey
(
AdminUser
,
null
=
True
,
blank
=
True
,
related_name
=
'assets'
,
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
"Admin user"
))
system_users
=
models
.
ManyToManyField
(
SystemUser
,
blank
=
True
,
related_name
=
'assets'
,
verbose_name
=
_
(
"System User"
))
idc
=
models
.
ForeignKey
(
IDC
,
null
=
True
,
related_name
=
'assets'
,
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
'IDC'
))
idc
=
models
.
ForeignKey
(
IDC
,
null
=
True
,
related_name
=
'assets'
,
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
'IDC'
),)
# default=get_default_idc)
mac_address
=
models
.
CharField
(
max_length
=
20
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
"Mac address"
))
brand
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Brand'
))
cpu
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'CPU'
))
cpu
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'CPU'
))
memory
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Memory'
))
disk
=
models
.
CharField
(
max_length
=
1024
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Disk'
))
os
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'OS'
))
cabinet_no
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Cabinet number'
))
cabinet_pos
=
models
.
IntegerField
(
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Cabinet position'
))
number
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Asset number'
))
status
=
models
.
ForeignKey
(
AssetExtend
,
null
=
True
,
blank
=
True
,
related_name
=
"asset_status_extend"
,
verbose_name
=
_
(
'Asset status'
))
type
=
models
.
ForeignKey
(
AssetExtend
,
null
=
True
,
blank
=
True
,
related_name
=
"asset_type_extend"
,
verbose_name
=
_
(
'Asset type'
))
env
=
models
.
ForeignKey
(
AssetExtend
,
null
=
True
,
blank
=
True
,
related_name
=
"asset_env_extend"
,
verbose_name
=
_
(
'Asset environment'
))
status
=
models
.
ForeignKey
(
AssetExtend
,
null
=
True
,
blank
=
True
,
related_name
=
"status_asset"
,
verbose_name
=
_
(
'Asset status'
),)
# default=functools.partial(get_default_extend, 'status', 'In use'))
type
=
models
.
ForeignKey
(
AssetExtend
,
null
=
True
,
limit_choices_to
=
{
'key'
:
'type'
},
related_name
=
"type_asset"
,
verbose_name
=
_
(
'Asset type'
),)
# default=functools.partial(get_default_extend, 'type','Server'))
env
=
models
.
ForeignKey
(
AssetExtend
,
blank
=
True
,
null
=
True
,
limit_choices_to
=
{
'key'
:
'env'
},
related_name
=
"env_asset"
,
verbose_name
=
_
(
'Asset environment'
),)
# default=functools.partial(get_default_extend, 'env', 'Production'))
sn
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Serial number'
))
created_by
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Is active'
))
date_created
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Date added'
))
comment
=
models
.
Char
Field
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
comment
=
models
.
Text
Field
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
def
__unicode__
(
self
):
return
'
%(ip)
s:
%(port)
s'
%
{
'ip'
:
self
.
ip
,
'port'
:
self
.
port
}
def
initial
(
self
):
pass
def
is_valid
(
self
):
warning
=
''
if
not
self
.
is_active
:
warning
+=
' inactive'
else
:
return
True
,
''
return
False
,
warning
class
Meta
:
db_table
=
'asset'
index
_together
=
(
'ip'
,
'port'
)
unique
_together
=
(
'ip'
,
'port'
)
@classmethod
def
generate_fake
(
cls
,
count
=
100
):
...
...
@@ -323,8 +348,8 @@ class Asset(models.Model):
seed
()
for
i
in
range
(
count
):
asset
=
cls
(
ip
=
'
%
s.
%
s.
%
s.
%
s'
%
tuple
([
forgery_py
.
forgery
.
basic
.
text
(
length
=
3
,
digits
=
True
)
for
i
in
range
(
0
,
4
)]
),
asset
=
cls
(
ip
=
'
%
s.
%
s.
%
s.
%
s'
%
(
i
,
i
,
i
,
i
),
hostname
=
forgery_py
.
internet
.
user_name
(
True
),
admin_user
=
choice
(
AdminUser
.
objects
.
all
()),
idc
=
choice
(
IDC
.
objects
.
all
()),
port
=
22
,
...
...
@@ -339,21 +364,28 @@ class Asset(models.Model):
continue
class
Label
(
models
.
Model
):
key
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'KEY'
))
value
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'VALUE'
))
asset
=
models
.
ForeignKey
(
Asset
,
null
=
True
,
blank
=
True
,
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
'Asset'
))
created_by
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
verbose_name
=
_
(
"Created by"
))
date_created
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)
comment
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
class
Tag
(
models
.
Model
):
value
=
models
.
CharField
(
max_length
=
64
,
verbose_name
=
_
(
'VALUE'
))
asset
=
models
.
ForeignKey
(
Asset
,
related_name
=
'tags'
,
on_delete
=
models
.
CASCADE
,
verbose_name
=
_
(
'Asset'
))
def
__unicode__
(
self
):
return
self
.
key
return
self
.
value
class
Meta
:
db_table
=
'label'
db_table
=
'tag'
unique_together
=
(
'value'
,
'asset'
)
def
init_all_models
():
for
cls
in
(
AssetExtend
,
AssetGroup
):
cls
.
initial
()
def
generate_fake
():
for
cls
in
(
AssetGroup
,
IDC
,
AdminUser
,
SystemUser
,
Asset
):
cls
.
generate_fake
()
def
flush_all
():
for
cls
in
(
AssetGroup
,
AssetExtend
,
IDC
,
AdminUser
,
SystemUser
,
Asset
):
cls
.
objects
.
all
()
.
delete
()
apps/assets/templates/assets/admin_user_list.html
View file @
ce5950ca
{% extends '_
list_base
.html' %}
{% extends '_
base_list
.html' %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
...
...
apps/assets/templates/assets/asset_create.html
View file @
ce5950ca
{% extends '
bas
e.html' %}
{% extends '
_base_create_updat
e.html' %}
{% load static %}
{% load bootstrap %}
{% block custom_head_css_js %}
<link
href=
"{% static "
css
/
plugins
/
select2
/
select2
.
min
.
css
"
%}"
rel=
"stylesheet"
>
<script
src=
"{% static "
js
/
plugins
/
select2
/
select2
.
full
.
min
.
js
"
%}"
></script>
{% endblock %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
添加资产
</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=
"tab-content"
>
<form
id=
"assetForm"
method=
"post"
class=
"form-horizontal"
>
{% csrf_token %}
<h3
class=
"widget-head-color-box"
>
基本信息
</h3>
{{ form.hostname|bootstrap_horizontal }}
{{ form.ip|bootstrap_horizontal }}
{{ form.port|bootstrap_horizontal }}
{{ form.type|bootstrap_horizontal }}
{{ form.comment|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
关联资产用户
</h3>
<div
class=
"form-group"
>
<label
for=
"j_group"
class=
"col-sm-2 control-label"
>
管理用户
</label>
<div
class=
"col-sm-9"
>
<div
class=
"radio i-checks"
>
<label><input
type=
"radio"
checked=
"checked"
id=
"id_use_default_auth"
name=
"use_default_auth"
><span>
使用预定义管理用户
</span></label>
<label><input
type=
"radio"
id=
"id_use_default_auth"
name=
"use_default_auth"
><span>
自定义
</span></label>
</div>
</div>
</div>
{{ form.admin_user|bootstrap_horizontal }}
<p
class=
"col-sm-offset-2"
>
Tips: 管理用户是服务器存在的root或拥有sudo的用户,用来推送系统用户
</p>
<div
class=
"hr-line-dashed"
></div>
{{ form.system_users|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
所属
</h3>
{{ form.idc|bootstrap_horizontal }}
{{ form.groups|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
标签
</h3>
<div
class=
"form-group"
id=
"id_label"
>
<label
class=
"col-sm-2 control-label"
>
Label
</label>
<div
class=
"col-sm-4"
>
<input
type=
"text"
placeholder=
"Key"
name=
"key"
class=
"form-control"
>
</div>
<div
class=
"col-sm-5"
>
<input
type=
"text"
placeholder=
"Value"
name=
"value"
class=
"form-control"
>
</div>
</div>
<div
class=
"col-sm-offset-2"
>
<i
class=
"fa fa-plus-circle"
></i>
<span
class=
"nav-label"
>
添加
</span><span
class=
"fa arrow"
></span>
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<div
class=
"col-sm-4 col-sm-offset-5"
>
<button
class=
"btn btn-white"
type=
"reset"
>
重置
</button>
<button
class=
"btn btn-primary"
type=
"submit"
>
提交
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% load i18n %}
{% block form %}
<form
action=
""
method=
"post"
class=
"form-horizontal"
>
{% csrf_token %}
<h3>
{% trans 'Basic' %}
</h3>
{{ form.hostname|bootstrap_horizontal }}
{{ form.ip|bootstrap_horizontal }}
{{ form.port|bootstrap_horizontal }}
{{ form.type|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Group' %}
</h3>
{{ form.idc|bootstrap_horizontal }}
{{ form.groups|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Asset user' %}
</h3>
{{ form.admin_user|bootstrap_horizontal }}
{{ form.system_users|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
{{ form.tags|bootstrap_horizontal }}
{{ form.comment|bootstrap_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>
</div>
</form>
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
ready
(
function
()
{
$
(
'.select2-groups'
).
select2
();
$
(
'.select2-admin-user'
).
select2
();
$
(
'.select2-system-user'
).
select2
();
$
(
'.select2'
).
select2
();
$
(
'#tags'
).
inputTags
();
})
</script>
{% endblock %}
\ No newline at end of file
apps/assets/templates/assets/asset_detail.html
View file @
ce5950ca
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/asset_group_list.html
View file @
ce5950ca
{% extends '_
list_base
.html' %}
{% extends '_
base_list
.html' %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
...
...
apps/assets/templates/assets/asset_list.html
View file @
ce5950ca
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/asset_update.html
0 → 100644
View file @
ce5950ca
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap %}
{% load i18n %}
{% block custom_head_css_js_create %}
<link
href=
"{% static "
css
/
plugins
/
inputTags
.
css
"
%}"
rel=
"stylesheet"
>
<script
src=
"{% static "
js
/
plugins
/
inputTags
.
jquery
.
min
.
js
"
%}"
></script>
{% endblock %}
{% block form %}
<form
action=
""
method=
"post"
class=
"form-horizontal"
>
{% csrf_token %}
<h3>
{% trans 'Basic' %}
</h3>
{{ form.hostname|bootstrap_horizontal }}
{{ form.ip|bootstrap_horizontal }}
{{ form.port|bootstrap_horizontal }}
{{ form.type|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Group' %}
</h3>
{{ form.idc|bootstrap_horizontal }}
{{ form.groups|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Asset user' %}
</h3>
{{ form.admin_user|bootstrap_horizontal }}
{{ form.system_users|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Hardware' %}
</h3>
{{ form.sn|bootstrap_horizontal }}
{{ form.brand|bootstrap_horizontal }}
{{ form.cpu|bootstrap_horizontal }}
{{ form.memory|bootstrap_horizontal }}
{{ form.disk|bootstrap_horizontal }}
{{ form.mac_address|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Configuration' %}
</h3>
{{ form.number|bootstrap_horizontal }}
{{ form.other_ip|bootstrap_horizontal }}
{{ form.remote_card_ip|bootstrap_horizontal }}
{{ form.os|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Location' %}
</h3>
{{ form.cabinet_no|bootstrap_horizontal }}
{{ form.cabinet_pos|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
{{ form.status|bootstrap_horizontal }}
{{ form.env|bootstrap_horizontal }}
{{ form.tags|bootstrap_horizontal }}
{{ form.comment|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
<button
class=
"btn btn-white"
type=
"reset"
>
{% trans 'Reset' %}
</button>
<button
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
</div>
</div>
</form>
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
ready
(
function
()
{
$
(
'.select2'
).
select2
();
{
#
$
(
'#tags'
).
inputTags
({
#
}
{
#
tags
:
[{
%
for
tag
in
form
.
tags
.
value
%
}
{{
tag
|
safe
}},
{
%
endfor
%
}]
#
}
{
#
});
#
}
$
(
'#tags'
).
inputTags
(
);
})
</script>
{% endblock %}
\ No newline at end of file
apps/assets/templates/assets/idc_list.html
View file @
ce5950ca
{% extends '_
list_base
.html' %}
{% extends '_
base_list
.html' %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
...
...
apps/assets/templates/assets/system_user_list.html
View file @
ce5950ca
{% extends '_
list_base
.html' %}
{% extends '_
base_list
.html' %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
...
...
apps/assets/views.py
View file @
ce5950ca
...
...
@@ -10,45 +10,77 @@ from django.urls import reverse_lazy
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.views.generic.detail
import
DetailView
,
SingleObjectMixin
from
django.shortcuts
import
get_object_or_404
,
reverse
,
redirect
from
.models
import
Asset
,
AssetGroup
,
IDC
,
AssetExtend
,
AdminUser
,
SystemUser
,
Label
from
.forms
import
AssetForm
,
AssetGroupForm
,
IDCForm
,
AdminUserForm
,
SystemUserForm
from
common.utils
import
int_seq
from
.models
import
Asset
,
AssetGroup
,
IDC
,
AssetExtend
,
AdminUser
,
SystemUser
,
Tag
from
.forms
import
AssetCreateForm
,
AssetGroupForm
,
IDCForm
,
AdminUserForm
,
SystemUserForm
from
.hands
import
AdminUserRequiredMixin
class
AssetListView
(
AdminUserRequiredMixin
,
ListView
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
model
=
Asset
context_object_name
=
'asset_list'
template_name
=
'assets/asset_list.html'
def
get_queryset
(
self
):
queryset
=
super
(
AssetListView
,
self
)
.
get_queryset
()
queryset
=
sorted
(
queryset
,
key
=
self
.
sorted_by_valid_and_ip
)
return
queryset
@staticmethod
def
sorted_by_valid_and_ip
(
asset
):
ip_list
=
int_seq
(
asset
.
ip
.
split
(
'.'
))
ip_list
.
insert
(
0
,
asset
.
is_valid
()[
0
])
return
ip_list
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'Assets'
,
'action'
:
'Asset list'
,
}
kwargs
.
update
(
context
)
return
super
(
AssetListView
,
self
)
.
get_context_data
(
**
kwargs
)
class
AssetCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
Asset
form_class
=
AssetForm
form_class
=
Asset
Create
Form
template_name
=
'assets/asset_create.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
def
form_valid
(
self
,
form
):
asset
=
form
.
save
(
commit
=
False
)
key
=
self
.
request
.
POST
.
get
(
'key'
,
''
)
value
=
self
.
request
.
POST
.
get
(
'value'
,
''
)
asset
.
save
()
Label
.
objects
.
create
(
key
=
key
,
value
=
value
,
asset
=
asset
)
return
super
(
AssetCreateView
,
self
)
.
form_valid
(
form
)
def
form_invalid
(
self
,
form
):
print
(
form
.
errors
)
return
super
(
AssetCreateView
,
self
)
.
form_invalid
(
form
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
AssetCreateView
,
self
)
.
get_context_data
(
**
kwargs
)
context
.
update
({
'admin_users'
:
AdminUser
.
objects
.
all
()})
assert
isinstance
(
context
,
object
)
return
context
class
AssetUpdateView
(
UpdateView
):
pass
context
=
{
'app'
:
'Assets'
,
'action'
:
'Create asset'
,
}
kwargs
.
update
(
context
)
return
super
(
AssetCreateView
,
self
)
.
get_context_data
(
**
kwargs
)
class
Asset
DeleteView
(
Dele
teView
):
class
Asset
UpdateView
(
AdminUserRequiredMixin
,
Upda
teView
):
model
=
Asset
form_class
=
AssetCreateForm
template_name
=
'assets/asset_update.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'Assets'
,
'action'
:
'Update asset'
,
}
kwargs
.
update
(
context
)
return
super
(
AssetUpdateView
,
self
)
.
get_context_data
(
**
kwargs
)
class
Asset
ListView
(
List
View
):
class
Asset
DeleteView
(
Delete
View
):
model
=
Asset
context_object_name
=
'assets
'
template_name
=
'assets/asset_list.html'
template_name
=
'assets/delete_confirm.html
'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
class
AssetDetailView
(
DetailView
):
...
...
@@ -56,6 +88,18 @@ class AssetDetailView(DetailView):
context_object_name
=
'asset'
template_name
=
'assets/asset_detail.html'
def
get_context_data
(
self
,
**
kwargs
):
asset_groups
=
self
.
object
.
groups
.
all
()
context
=
{
'app'
:
'Assets'
,
'action'
:
'Asset detail'
,
'asset_groups_remain'
:
[
asset_group
for
asset_group
in
AssetGroup
.
objects
.
all
()
if
asset_group
not
in
asset_groups
],
'asset_groups'
:
asset_groups
,
}
kwargs
.
update
(
context
)
return
super
(
AssetDetailView
,
self
)
.
get_context_data
(
**
kwargs
)
class
AssetGroupCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
AssetGroup
...
...
apps/common/utils.py
View file @
ce5950ca
...
...
@@ -100,3 +100,10 @@ def search_object_attr(obj, value='', attr_list=None, ignore_case=False):
def
get_logger
(
name
=
None
):
return
logging
.
getLogger
(
'jumpserver.
%
s'
%
name
)
def
int_seq
(
seq
):
try
:
return
map
(
int
,
seq
)
except
ValueError
:
return
seq
apps/locale/zh/LC_MESSAGES/django.po
View file @
ce5950ca
This diff is collapsed.
Click to expand it.
apps/perms/templates/perms/asset_permission_list.html
View file @
ce5950ca
{% extends '_
list_base
.html' %}
{% extends '_
base_list
.html' %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
...
...
apps/static/css/plugins/inputTags.css
0 → 100644
View file @
ce5950ca
@import
url("https://fonts.useso.com/css?family=Open+Sans:300,400,600,700")
;
@import
url("https://fonts.useso.com/css?family=Roboto:400,300,500,700")
;
/** {*/
/*box-sizing: border-box;*/
/*}*/
/*.color {*/
/*color: #19BC9C !important;*/
/*}*/
/*html,*/
/*body {*/
/*width: 100%;*/
/*height: 100%;*/
/*margin: 0;*/
/*font-family: 'Ubuntu Condensed', sans-serif;*/
/*background-color: #fff;*/
/*}*/
/*h1 {*/
/*text-align: center;*/
/*margin-bottom: 32px;*/
/*}*/
div
.container
{
display
:
block
;
width
:
50%
;
margin
:
32px
auto
;
padding
:
16px
32px
;
background-color
:
#fff
;
box-shadow
:
2px
2px
8px
rgba
(
0
,
0
,
0
,
0.1
);
}
div
.inputTags-list
{
display
:
inline-block
;
width
:
100%
;
padding
:
6px
;
border
:
1px
solid
rgba
(
25
,
188
,
156
,
0.35
);
/*background-color: #f9f9f9;*/
box-shadow
:
1px
2px
2px
rgba
(
221
,
221
,
221
,
0.2
);
-webkit-border-radius
:
4px
;
-moz-border-radius
:
4px
;
border-radius
:
4px
;
-moz-background-clip
:
padding
;
-webkit-background-clip
:
padding-box
;
background-clip
:
padding-box
;
}
div
.inputTags-list
span
.inputTags-item
{
position
:
relative
;
display
:
inline-block
;
margin
:
2px
;
padding
:
3px
22px
4px
8px
;
background-color
:
#19BC9C
;
text-align
:
center
;
color
:
#fff
;
opacity
:
1
;
-webkit-border-radius
:
3px
;
-moz-border-radius
:
3px
;
border-radius
:
3px
;
-moz-background-clip
:
padding
;
-webkit-background-clip
:
padding-box
;
background-clip
:
padding-box
;
}
div
.inputTags-list
span
.inputTags-item.is-edit
{
display
:
none
;
}
div
.inputTags-list
span
.inputTags-item.is-hidden
{
display
:
none
!important
;
}
div
.inputTags-list
span
.inputTags-item.is-exists
{
background-color
:
rgba
(
231
,
76
,
60
,
0.7
);
}
div
.inputTags-list
span
.inputTags-item
span
.value
{
cursor
:
pointer
;
}
div
.inputTags-list
span
.inputTags-item
i
{
position
:
absolute
;
top
:
50%
;
right
:
6px
;
font-size
:
20px
;
cursor
:
pointer
;
z-index
:
10
;
font-weight
:
400
;
font-family
:
sans-serif
;
line-height
:
1
;
font-style
:
normal
;
-webkit-transition
:
color
0.2s
;
-khtml-transition
:
color
0.2s
;
-moz-transition
:
color
0.2s
;
-ms-transition
:
color
0.2s
;
-o-transition
:
color
0.2s
;
-webkit-transform
:
translateY
(
-50%
);
-khtml-transform
:
translateY
(
-50%
);
-moz-transform
:
translateY
(
-50%
);
-ms-transform
:
translateY
(
-50%
);
-o-transform
:
translateY
(
-50%
);
}
div
.inputTags-list
span
.inputTags-item
i
:hover
{
color
:
#e74c3c
;
}
div
.inputTags-list
input
.inputTags-field
{
border
:
none
;
margin-left
:
4px
;
background-color
:
transparent
;
}
div
.inputTags-list
input
.inputTags-field
:focus
,
div
.inputTags-list
input
.inputTags-field
:active
{
outline
:
none
;
}
div
.inputTags-list
input
.inputTags-field.is-edit
{
margin
:
0
2px
;
padding
:
4px
8px
3px
8px
;
border
:
1px
dashed
#c4c4c4
;
-webkit-border-radius
:
4px
;
-moz-border-radius
:
4px
;
border-radius
:
4px
;
-moz-background-clip
:
padding
;
-webkit-background-clip
:
padding-box
;
background-clip
:
padding-box
;
}
div
.inputTags-list
ul
.inputTags-autocomplete-list
{
position
:
absolute
;
max-height
:
192px
;
margin
:
0
;
padding
:
0
;
list-style-type
:
none
;
background-color
:
#fff
;
border
:
1px
solid
#ddd
;
overflow-y
:
auto
;
z-index
:
100
;
opacity
:
0
;
-webkit-border-radius
:
4px
;
-moz-border-radius
:
4px
;
border-radius
:
4px
;
-moz-background-clip
:
padding
;
-webkit-background-clip
:
padding-box
;
background-clip
:
padding-box
;
-webkit-transform
:
scaleY
(
0
);
-khtml-transform
:
scaleY
(
0
);
-moz-transform
:
scaleY
(
0
);
-ms-transform
:
scaleY
(
0
);
-o-transform
:
scaleY
(
0
);
-webkit-transform-origin
:
50%
0
;
-khtml-transform-origin
:
50%
0
;
-moz-transform-origin
:
50%
0
;
-ms-transform-origin
:
50%
0
;
-o-transform-origin
:
50%
0
;
-webkit-transition-duration
:
0.2s
;
-khtml-transition-duration
:
0.2s
;
-moz-transition-duration
:
0.2s
;
-ms-transition-duration
:
0.2s
;
-o-transition-duration
:
0.2s
;
}
div
.inputTags-list
ul
.inputTags-autocomplete-list.is-active
{
opacity
:
1
;
-webkit-transform
:
scaleY
(
1
);
-khtml-transform
:
scaleY
(
1
);
-moz-transform
:
scaleY
(
1
);
-ms-transform
:
scaleY
(
1
);
-o-transform
:
scaleY
(
1
);
}
div
.inputTags-list
ul
.inputTags-autocomplete-list
li
{
height
:
32px
;
line-height
:
32px
;
padding
:
0
16px
;
cursor
:
pointer
;
border-bottom
:
1px
solid
#ddd
;
-webkit-transition-duration
:
0.3s
;
-khtml-transition-duration
:
0.3s
;
-moz-transition-duration
:
0.3s
;
-ms-transition-duration
:
0.3s
;
-o-transition-duration
:
0.3s
;
-webkit-transition-duration
:
0.2s
;
-khtml-transition-duration
:
0.2s
;
-moz-transition-duration
:
0.2s
;
-ms-transition-duration
:
0.2s
;
-o-transition-duration
:
0.2s
;
}
div
.inputTags-list
ul
.inputTags-autocomplete-list
li
:last-child
{
border
:
none
;
}
div
.inputTags-list
ul
.inputTags-autocomplete-list
li
:hover
{
background-color
:
#19BC9C
;
color
:
#fff
;
}
div
.inputTags-list
ul
.inputTags-autocomplete-list
li
.is-disabled
{
cursor
:
default
;
background-color
:
#f7f7f7
;
color
:
initial
;
}
p
.inputTags-error
{
position
:
relative
;
margin
:
0
;
padding
:
0.5em
1em
;
color
:
#fff
;
background-color
:
rgba
(
231
,
76
,
60
,
0.7
);
cursor
:
pointer
;
-webkit-border-radius
:
4px
;
-moz-border-radius
:
4px
;
border-radius
:
4px
;
-moz-background-clip
:
padding
;
-webkit-background-clip
:
padding-box
;
background-clip
:
padding-box
;
}
p
.inputTags-error
:first-of-type
{
margin-top
:
8px
;
}
p
.inputTags-error
:after
{
position
:
absolute
;
content
:
"\000D7"
;
top
:
50%
;
right
:
0.5em
;
-webkit-transform
:
translateY
(
-50%
);
-khtml-transform
:
translateY
(
-50%
);
-moz-transform
:
translateY
(
-50%
);
-ms-transform
:
translateY
(
-50%
);
-o-transform
:
translateY
(
-50%
);
font-size
:
28px
;
}
apps/static/js/plugins/inputTags.jquery.min.js
0 → 100644
View file @
ce5950ca
This diff is collapsed.
Click to expand it.
apps/templates/_base_create_update.html
0 → 100644
View file @
ce5950ca
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap %}
{% 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>
{% block custom_head_css_js_create %} {% endblock %}
{% 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"
>
{% block form %} {% endblock %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
apps/templates/_
list_base
.html
→
apps/templates/_
base_list
.html
View file @
ce5950ca
File moved
apps/users/templates/users/user_create.html
View file @
ce5950ca
{% extends 'users/_user.html' %}
{% load i18n %}
{% load bootstrap %}
{% block user_template_title %}{% trans "Create user" %}{% endblock %}
{% block username %}
{{ form.username|bootstrap_horizontal }}
{% endblock %}
...
...
apps/users/templates/users/user_group_list.html
View file @
ce5950ca
<
<<<<<<
HEAD
{%
extends
'
_list_base
.
html
'
%}
{%
load
i18n
static
%}
{%
block
custom_head_css_js
%}
...
...
@@ -5,6 +6,11 @@
<script
src=
"{% static "
js
/
plugins
/
sweetalert
/
sweetalert
.
min
.
js
"
%}"
></script>
{% endblock %}
=======
{% extends '_base_list.html' %}
{% load i18n %}
{% load common_tags %}
>>>>>>> asset
{% block content_left_head %}
<a
href=
"{% url 'users:user-group-create' %}"
class=
"btn btn-sm btn-primary "
>
{% trans "Add User Group" %}
</a>
{% endblock %}
...
...
apps/users/templates/users/user_list.html
View file @
ce5950ca
{% extends '_
list_base
.html' %}
{% extends '_
base_list
.html' %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
...
...
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