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
0f29745b
Commit
0f29745b
authored
Nov 14, 2015
by
wangyong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
asset add batch
parent
ec7b543b
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
730 additions
and
172 deletions
+730
-172
ansible_api.py
jasset/ansible_api.py
+459
-0
asset_api.py
jasset/asset_api.py
+62
-4
models.py
jasset/models.py
+1
-1
models_bak.py
jasset/models_bak.py
+0
-151
urls.py
jasset/urls.py
+4
-3
views.py
jasset/views.py
+85
-8
mytags.py
jumpserver/templatetags/mytags.py
+17
-0
asset_add.html
templates/jasset/asset_add.html
+1
-1
asset_add_batch.html
templates/jasset/asset_add_batch.html
+66
-0
asset_detail.html
templates/jasset/asset_detail.html
+30
-2
asset_list.html
templates/jasset/asset_list.html
+5
-2
No files found.
jasset/ansible_api.py
0 → 100644
View file @
0f29745b
# -*- coding: utf-8 -*-
from
ansible.inventory.group
import
Group
from
ansible.inventory.host
import
Host
from
ansible.inventory
import
Inventory
from
ansible.runner
import
Runner
from
ansible.playbook
import
PlayBook
from
ansible
import
callbacks
from
ansible
import
utils
from
passlib.hash
import
sha512_crypt
# from utils import get_rand_pass
import
random
import
os.path
API_DIR
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
ANSIBLE_DIR
=
os
.
path
.
join
(
API_DIR
,
'playbooks'
)
def
get_rand_pass
():
"""
get a reandom password.
"""
lower
=
[
chr
(
i
)
for
i
in
range
(
97
,
123
)]
upper
=
[
chr
(
i
)
.
upper
()
for
i
in
range
(
97
,
123
)]
digit
=
[
str
(
i
)
for
i
in
range
(
10
)]
password_pool
=
[]
password_pool
.
extend
(
lower
)
password_pool
.
extend
(
upper
)
password_pool
.
extend
(
digit
)
pass_list
=
[
random
.
choice
(
password_pool
)
for
i
in
range
(
1
,
14
)]
pass_list
.
insert
(
random
.
choice
(
range
(
1
,
14
)),
'@'
)
pass_list
.
insert
(
random
.
choice
(
range
(
1
,
14
)),
random
.
choice
(
digit
))
password
=
''
.
join
(
pass_list
)
return
password
class
AnsibleError
(
StandardError
):
"""
the base AnsibleError which contains error(required),
data(optional) and message(optional).
存储所有Ansible 异常对象
"""
def
__init__
(
self
,
error
,
data
=
''
,
message
=
''
):
super
(
AnsibleError
,
self
)
.
__init__
(
message
)
self
.
error
=
error
self
.
data
=
data
self
.
message
=
message
class
CommandValueError
(
AnsibleError
):
"""
indicate the input value has error or invalid.
the data specifies the error field of input form.
输入不合法 异常对象
"""
def
__init__
(
self
,
field
,
message
=
''
):
super
(
CommandValueError
,
self
)
.
__init__
(
'value:invalid'
,
field
,
message
)
class
MyInventory
(
object
):
"""
this is my ansible inventory object.
"""
def
__init__
(
self
,
resource
):
"""
resource的数据格式是一个列表字典,比如
{
"group1": {
"hosts": [{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...],
"vars": {"var1": value1, "var2": value2, ...}
}
}
如果你只传入1个列表,这默认该列表内的所有主机属于my_group组,比如
[{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...]
"""
self
.
resource
=
resource
self
.
inventory
=
Inventory
()
self
.
gen_inventory
()
def
add_group
(
self
,
hosts
,
groupname
,
groupvars
=
None
):
"""
add hosts to a group
"""
my_group
=
Group
(
name
=
groupname
)
# if group variables exists, add them to group
if
groupvars
:
for
key
,
value
in
groupvars
.
iteritems
():
my_group
.
set_variable
(
key
,
value
)
# add hosts to group
for
host
in
hosts
:
# set connection variables
hostname
=
host
.
get
(
"hostname"
)
hostport
=
host
.
get
(
"port"
)
username
=
host
.
get
(
"username"
)
password
=
host
.
get
(
"password"
)
my_host
=
Host
(
name
=
hostname
,
port
=
hostport
)
my_host
.
set_variable
(
'ansible_ssh_host'
,
hostname
)
my_host
.
set_variable
(
'ansible_ssh_port'
,
hostport
)
my_host
.
set_variable
(
'ansible_ssh_user'
,
username
)
my_host
.
set_variable
(
'ansible_ssh_pass'
,
password
)
# set other variables
for
key
,
value
in
host
.
iteritems
():
if
key
not
in
[
"hostname"
,
"port"
,
"username"
,
"password"
]:
my_host
.
set_variable
(
key
,
value
)
# add to group
my_group
.
add_host
(
my_host
)
self
.
inventory
.
add_group
(
my_group
)
def
gen_inventory
(
self
):
"""
add hosts to inventory.
"""
if
isinstance
(
self
.
resource
,
list
):
self
.
add_group
(
self
.
resource
,
'my_group'
)
elif
isinstance
(
self
.
resource
,
dict
):
for
groupname
,
hosts_and_vars
in
self
.
resource
.
iteritems
():
self
.
add_group
(
hosts_and_vars
.
get
(
"hosts"
),
groupname
,
hosts_and_vars
.
get
(
"vars"
))
class
Command
(
MyInventory
):
"""
this is a command object for parallel execute command.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Command
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
results
=
''
def
run
(
self
,
command
,
module_name
=
"command"
,
timeout
=
5
,
forks
=
10
,
group
=
'my_group'
):
"""
run command from andible ad-hoc.
command : 必须是一个需要执行的命令字符串, 比如
'uname -a'
"""
if
module_name
not
in
[
"raw"
,
"command"
,
"shell"
]:
raise
CommandValueError
(
"module_name"
,
"module_name must be of the 'raw, command, shell'"
)
hoc
=
Runner
(
module_name
=
module_name
,
module_args
=
command
,
timeout
=
timeout
,
inventory
=
self
.
inventory
,
subset
=
group
,
forks
=
forks
)
self
.
results
=
hoc
.
run
()
if
self
.
stdout
:
return
{
"ok"
:
self
.
stdout
}
else
:
msg
=
[]
if
self
.
stderr
:
msg
.
append
(
self
.
stderr
)
if
self
.
dark
:
msg
.
append
(
self
.
dark
)
return
{
"failed"
:
msg
}
@property
def
raw_results
(
self
):
"""
get the ansible raw results.
"""
return
self
.
results
@property
def
exec_time
(
self
):
"""
get the command execute time.
"""
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
{
"start"
:
value
.
get
(
"start"
),
"end"
:
value
.
get
(
"end"
),
"delta"
:
value
.
get
(
"delta"
),}
return
result
@property
def
stdout
(
self
):
"""
get the comamnd standard output.
"""
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
value
.
get
(
"stdout"
)
return
result
@property
def
stderr
(
self
):
"""
get the command standard error.
"""
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
{
"stderr"
:
value
.
get
(
"stderr"
),
"warnings"
:
value
.
get
(
"warnings"
),}
return
result
@property
def
dark
(
self
):
"""
get the dark results.
"""
return
self
.
results
.
get
(
"dark"
)
class
Tasks
(
Command
):
"""
this is a tasks object for include the common command.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Tasks
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
__run
(
self
,
module_args
,
module_name
=
"command"
,
timeout
=
5
,
forks
=
10
,
group
=
'my_group'
):
"""
run command from andible ad-hoc.
command : 必须是一个需要执行的命令字符串, 比如
'uname -a'
"""
hoc
=
Runner
(
module_name
=
module_name
,
module_args
=
module_args
,
timeout
=
timeout
,
inventory
=
self
.
inventory
,
subset
=
group
,
forks
=
forks
)
self
.
results
=
hoc
.
run
()
@property
def
msg
(
self
):
"""
get the contacted and dark msg
"""
msg
=
{}
for
result
in
[
"contacted"
,
"dark"
]:
all
=
self
.
results
.
get
(
result
)
for
key
,
value
in
all
.
iteritems
():
if
value
.
get
(
"msg"
):
msg
[
key
]
=
value
.
get
(
"msg"
)
return
msg
def
push_key
(
self
,
user
,
key_path
):
"""
push the ssh authorized key to target.
"""
module_args
=
'user="
%
s" key="{{ lookup("file", "
%
s") }}"'
%
(
user
,
key_path
)
self
.
__run
(
module_args
,
"authorized_key"
)
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
}
def
del_key
(
self
,
user
,
key_path
):
"""
push the ssh authorized key to target.
"""
module_args
=
'user="
%
s" key="{{ lookup("file", "
%
s") }}" state="absent"'
%
(
user
,
key_path
)
self
.
__run
(
module_args
,
"authorized_key"
)
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
}
def
add_user
(
self
,
username
,
password
):
"""
add a host user.
"""
encrypt_pass
=
sha512_crypt
.
encrypt
(
password
)
module_args
=
'name=
%
s shell=/bin/bash password=
%
s'
%
(
username
,
encrypt_pass
)
self
.
__run
(
module_args
,
"user"
)
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
}
def
add_multi_user
(
self
,
*
args
):
"""
add multi user
:param args:
user
:return:
"""
results
=
{}
users
=
{}
action
=
results
[
"action_info"
]
=
{}
for
user
in
args
:
users
[
user
]
=
get_rand_pass
()
for
user
,
password
in
users
.
iteritems
():
ret
=
self
.
add_user
(
user
,
password
)
action
[
user
]
=
ret
results
[
"user_info"
]
=
users
return
results
def
del_user
(
self
,
username
):
"""
delete a host user.
"""
module_args
=
'name=
%
s state=absent remove=yes move_home=yes force=yes'
%
(
username
)
self
.
__run
(
module_args
,
"user"
)
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
}
def
add_init_users
(
self
):
"""
add initail users: SA, DBA, DEV
"""
results
=
{}
action
=
results
[
"action_info"
]
=
{}
users
=
{
"SA"
:
get_rand_pass
(),
"DBA"
:
get_rand_pass
(),
"DEV"
:
get_rand_pass
()}
for
user
,
password
in
users
.
iteritems
():
ret
=
self
.
add_user
(
user
,
password
)
action
[
user
]
=
ret
results
[
"user_info"
]
=
users
return
results
def
del_init_users
(
self
):
"""
delete initail users: SA, DBA, DEV
"""
results
=
{}
action
=
results
[
"action_info"
]
=
{}
for
user
in
[
"SA"
,
"DBA"
,
"DEV"
]:
ret
=
self
.
del_user
(
user
)
action
[
user
]
=
ret
return
results
def
get_host_info
(
self
):
"""
use the setup module get host informations
:return:
all_ip is list
processor_count is int
system_dist_version is string
system_type is string
disk is dict (device_name: device_size}
system_dist is string
processor_type is string
default_ip is string
hostname is string
product_sn is string
memory_total is int (MB)
default_mac is string
product_name is string
"""
self
.
__run
(
''
,
'setup'
)
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
setup
=
value
.
get
(
"ansible_facts"
)
# get disk informations
disk_all
=
setup
.
get
(
"ansible_devices"
)
disk_need
=
{}
for
disk_name
,
disk_info
in
disk_all
.
iteritems
():
if
disk_name
.
startswith
(
'sd'
)
or
disk_name
.
startswith
(
'hd'
)
or
disk_name
.
startswith
(
'vd'
):
disk_need
[
disk_name
]
=
disk_info
.
get
(
"size"
)
result
[
key
]
=
{
"other_ip"
:
setup
.
get
(
"ansible_all_ipv4_addresses"
),
"hostname"
:
setup
.
get
(
"ansible_hostname"
),
"ip"
:
setup
.
get
(
"ansible_default_ipv4"
)
.
get
(
"address"
),
"mac"
:
setup
.
get
(
"ansible_default_ipv4"
)
.
get
(
"macaddress"
),
"brand"
:
setup
.
get
(
"ansible_product_name"
),
"cpu_type"
:
setup
.
get
(
"ansible_processor"
),
"cpu_cores"
:
setup
.
get
(
"ansible_processor_count"
),
"memory"
:
setup
.
get
(
"ansible_memtotal_mb"
),
"disk"
:
disk_need
,
"system_type"
:
setup
.
get
(
"ansible_distribution"
),
"system_version"
:
setup
.
get
(
"ansible_distribution_version"
),
"asset_type"
:
setup
.
get
(
"ansible_system"
),
"sn"
:
setup
.
get
(
"ansible_product_serial"
)
}
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
,
"result"
:
result
}
class
CustomAggregateStats
(
callbacks
.
AggregateStats
):
"""
Holds stats about per-host activity during playbook runs.
"""
def
__init__
(
self
):
super
(
CustomAggregateStats
,
self
)
.
__init__
()
self
.
results
=
[]
def
compute
(
self
,
runner_results
,
setup
=
False
,
poll
=
False
,
ignore_errors
=
False
):
"""
Walk through all results and increment stats.
"""
super
(
CustomAggregateStats
,
self
)
.
compute
(
runner_results
,
setup
,
poll
,
ignore_errors
)
self
.
results
.
append
(
runner_results
)
def
summarize
(
self
,
host
):
"""
Return information about a particular host
"""
summarized_info
=
super
(
CustomAggregateStats
,
self
)
.
summarize
(
host
)
# Adding the info I need
summarized_info
[
'result'
]
=
self
.
results
return
summarized_info
class
MyPlaybook
(
MyInventory
):
"""
this is my playbook object for execute playbook.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
MyPlaybook
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
run
(
self
,
playbook_relational_path
,
extra_vars
=
None
):
"""
run ansible playbook,
only surport relational path.
"""
stats
=
callbacks
.
AggregateStats
()
playbook_cb
=
callbacks
.
PlaybookCallbacks
(
verbose
=
utils
.
VERBOSITY
)
runner_cb
=
callbacks
.
PlaybookRunnerCallbacks
(
stats
,
verbose
=
utils
.
VERBOSITY
)
playbook_path
=
os
.
path
.
join
(
ANSIBLE_DIR
,
playbook_relational_path
)
pb
=
PlayBook
(
playbook
=
playbook_path
,
stats
=
stats
,
callbacks
=
playbook_cb
,
runner_callbacks
=
runner_cb
,
inventory
=
self
.
inventory
,
extra_vars
=
extra_vars
,
check
=
False
)
self
.
results
=
pb
.
run
()
@property
def
raw_results
(
self
):
"""
get the raw results after playbook run.
"""
return
self
.
results
class
App
(
MyPlaybook
):
"""
this is a app object for inclue the common playbook.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
App
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
if
__name__
==
"__main__"
:
pass
jasset/asset_api.py
View file @
0f29745b
# coding: utf-8
# coding: utf-8
import
ast
import
xlrd
import
xlsxwriter
import
xlsxwriter
from
django.db.models
import
AutoField
from
django.db.models
import
AutoField
from
jumpserver.api
import
*
from
jumpserver.api
import
*
...
@@ -310,8 +310,10 @@ def write_excel(asset_all):
...
@@ -310,8 +310,10 @@ def write_excel(asset_all):
group_all
=
'/'
.
join
(
group_list
)
group_all
=
'/'
.
join
(
group_list
)
status
=
asset
.
get_status_display
()
status
=
asset
.
get_status_display
()
alter_dic
=
[
asset
.
hostname
,
asset
.
ip
,
asset
.
idc
.
name
,
asset
.
mac
,
asset
.
remote_ip
,
asset
.
cpu
,
asset
.
memory
,
idc_name
=
asset
.
idc
.
name
if
asset
.
idc
else
u''
asset
.
disk
,
asset
.
system_type
,
asset
.
cabinet
,
group_all
,
status
,
asset
.
comment
]
alter_dic
=
[
asset
.
hostname
,
asset
.
ip
,
idc_name
,
asset
.
mac
,
asset
.
remote_ip
,
asset
.
cpu
,
asset
.
memory
,
asset
.
disk
,
(
asset
.
system_type
+
asset
.
system_version
),
asset
.
cabinet
,
group_all
,
status
,
asset
.
comment
]
data
.
append
(
alter_dic
)
data
.
append
(
alter_dic
)
format
=
workbook
.
add_format
()
format
=
workbook
.
add_format
()
format
.
set_border
(
1
)
format
.
set_border
(
1
)
...
@@ -342,6 +344,62 @@ def write_excel(asset_all):
...
@@ -342,6 +344,62 @@ def write_excel(asset_all):
def
copy_model_instance
(
obj
):
def
copy_model_instance
(
obj
):
initial
=
dict
([(
f
.
name
,
getattr
(
obj
,
f
.
name
))
initial
=
dict
([(
f
.
name
,
getattr
(
obj
,
f
.
name
))
for
f
in
obj
.
_meta
.
fields
for
f
in
obj
.
_meta
.
fields
if
not
isinstance
(
f
,
AutoField
)
and
\
if
not
isinstance
(
f
,
AutoField
)
and
\
not
f
in
obj
.
_meta
.
parents
.
values
()])
not
f
in
obj
.
_meta
.
parents
.
values
()])
return
obj
.
__class__
(
**
initial
)
return
obj
.
__class__
(
**
initial
)
def
ansible_record
(
asset
,
ansible_dic
,
username
):
alert_dic
=
{}
asset_dic
=
asset
.
__dict__
for
field
,
value
in
ansible_dic
.
items
():
old
=
asset_dic
.
get
(
field
)
new
=
ansible_dic
.
get
(
field
)
if
unicode
(
old
)
!=
unicode
(
new
):
print
old
,
new
,
type
(
old
),
type
(
new
)
setattr
(
asset
,
field
,
value
)
asset
.
save
()
alert_dic
[
field
]
=
[
old
,
new
]
db_asset_alert
(
asset
,
username
,
alert_dic
)
def
excel_to_db
(
excel_file
):
"""
Asset add batch function
"""
try
:
data
=
xlrd
.
open_workbook
(
filename
=
None
,
file_contents
=
excel_file
.
read
())
except
Exception
,
e
:
return
False
else
:
table
=
data
.
sheets
()[
0
]
rows
=
table
.
nrows
group_instance
=
[]
for
row_num
in
range
(
1
,
rows
):
row
=
table
.
row_values
(
row_num
)
if
row
:
ip
,
port
,
hostname
,
use_default_auth
,
username
,
password
,
group
=
row
print
ip
use_default_auth
=
1
if
use_default_auth
==
u'默认'
else
0
if
get_object
(
Asset
,
ip
=
ip
):
continue
if
ip
and
port
:
asset
=
Asset
(
ip
=
ip
,
port
=
port
,
use_default_auth
=
use_default_auth
,
username
=
username
,
password
=
password
)
asset
.
save
()
group_list
=
group
.
split
(
'/'
)
for
group_name
in
group_list
:
group
=
get_object
(
AssetGroup
,
name
=
group_name
)
if
group
:
group_instance
.
append
(
group
)
if
group_instance
:
print
group_instance
asset
.
group
=
group_instance
asset
.
save
()
return
True
jasset/models.py
View file @
0f29745b
...
@@ -80,7 +80,7 @@ class Asset(models.Model):
...
@@ -80,7 +80,7 @@ class Asset(models.Model):
status
=
models
.
IntegerField
(
max_length
=
2
,
choices
=
ASSET_STATUS
,
blank
=
True
,
null
=
True
,
default
=
1
,
verbose_name
=
u"机器状态"
)
status
=
models
.
IntegerField
(
max_length
=
2
,
choices
=
ASSET_STATUS
,
blank
=
True
,
null
=
True
,
default
=
1
,
verbose_name
=
u"机器状态"
)
asset_type
=
models
.
IntegerField
(
max_length
=
2
,
choices
=
ASSET_TYPE
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"主机类型"
)
asset_type
=
models
.
IntegerField
(
max_length
=
2
,
choices
=
ASSET_TYPE
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"主机类型"
)
env
=
models
.
IntegerField
(
max_length
=
2
,
choices
=
ASSET_ENV
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"运行环境"
)
env
=
models
.
IntegerField
(
max_length
=
2
,
choices
=
ASSET_ENV
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"运行环境"
)
sn
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"SN编号"
)
sn
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"SN编号"
)
date_added
=
models
.
DateTimeField
(
auto_now
=
True
,
default
=
datetime
.
datetime
.
now
(),
null
=
True
)
date_added
=
models
.
DateTimeField
(
auto_now
=
True
,
default
=
datetime
.
datetime
.
now
(),
null
=
True
)
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
u"是否激活"
)
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
u"是否激活"
)
comment
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"备注"
)
comment
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"备注"
)
...
...
jasset/models_bak.py
deleted
100644 → 0
View file @
ec7b543b
# coding: utf-8
import
datetime
from
django.db
import
models
from
juser.models
import
User
,
UserGroup
class
AssetGroup
(
models
.
Model
):
GROUP_TYPE
=
(
(
'P'
,
'PRIVATE'
),
(
'A'
,
'ASSET'
),
)
name
=
models
.
CharField
(
max_length
=
80
,
unique
=
True
)
comment
=
models
.
CharField
(
max_length
=
160
,
blank
=
True
,
null
=
True
)
def
__unicode__
(
self
):
return
self
.
name
def
get_asset
(
self
):
return
self
.
asset_set
.
all
()
def
get_asset_info
(
self
,
printable
=
False
):
assets
=
self
.
get_asset
()
ip_comment
=
{}
for
asset
in
assets
:
ip_comment
[
asset
.
ip
]
=
asset
.
comment
for
ip
in
sorted
(
ip_comment
):
if
ip_comment
[
ip
]:
print
'
%-15
s --
%
s'
%
(
ip
,
ip_comment
[
ip
])
else
:
print
'
%-15
s'
%
ip
print
''
def
get_asset_num
(
self
):
return
len
(
self
.
get_asset
())
def
get_user_group
(
self
):
perm_list
=
self
.
perm_set
.
all
()
user_group_list
=
[]
for
perm
in
perm_list
:
user_group_list
.
append
(
perm
.
user_group
)
return
user_group_list
def
get_user
(
self
):
user_list
=
[]
user_group_list
=
self
.
get_user_group
()
for
user_group
in
user_group_list
:
user_list
.
extend
(
user_group
.
user_set
.
all
())
return
user_list
def
is_permed
(
self
,
user
=
None
,
user_group
=
None
):
if
user
:
if
user
in
self
.
get_user
():
return
True
if
user_group
:
if
user_group
in
self
.
get_user_group
():
return
True
return
False
class
IDC
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
32
,
unique
=
True
)
bandwidth
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
)
linkman
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
,
null
=
True
)
phone
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
)
address
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
)
network
=
models
.
TextField
(
blank
=
True
,
null
=
True
)
date_added
=
models
.
DateField
(
auto_now
=
True
,
default
=
datetime
.
datetime
.
now
())
operator
=
models
.
IntegerField
(
max_length
=
32
,
blank
=
True
,
null
=
True
)
comment
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
)
def
__unicode__
(
self
):
return
self
.
name
class
Asset
(
models
.
Model
):
"""
asset modle
"""
ENVIRONMENT
=
(
(
0
,
U'生产环境'
),
(
1
,
U'测试环境'
)
)
SERVER_STATUS
=
(
(
0
,
u"已使用"
),
(
1
,
u"未使用"
),
(
2
,
u"报废"
)
)
ASSET_TYPE
=
(
(
0
,
u"服务器"
),
(
2
,
u"网络设备"
),
(
3
,
u"其他"
)
)
ip
=
models
.
IPAddressField
(
unique
=
True
)
second_ip
=
models
.
CharField
(
max_length
=
255
,
blank
=
True
,
null
=
True
)
hostname
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
null
=
True
)
port
=
models
.
IntegerField
(
max_length
=
6
)
group
=
models
.
ManyToManyField
(
AssetGroup
,
blank
=
True
,
null
=
True
)
username
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
,
null
=
True
)
password
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
null
=
True
)
use_default_auth
=
models
.
BooleanField
(
default
=
True
)
idc
=
models
.
ForeignKey
(
IDC
,
blank
=
True
,
null
=
True
,
on_delete
=
models
.
SET_NULL
)
mac
=
models
.
CharField
(
max_length
=
20
,
blank
=
True
,
null
=
True
)
remote_ip
=
models
.
IPAddressField
(
unique
=
True
,
blank
=
True
,
null
=
True
)
brand
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
null
=
True
)
cpu
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
null
=
True
)
memory
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
)
disk
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
)
system_type
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
)
system_version
=
models
.
CharField
(
max_length
=
8
,
blank
=
True
,
null
=
True
)
cabinet
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
)
position
=
models
.
IntegerField
(
max_length
=
2
,
blank
=
True
,
null
=
True
)
number
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
)
status
=
models
.
IntegerField
(
max_length
=
2
,
choices
=
SERVER_STATUS
,
default
=
1
)
asset_type
=
models
.
IntegerField
(
max_length
=
2
,
choices
=
ASSET_TYPE
,
blank
=
True
,
null
=
True
)
env
=
models
.
CharField
(
max_length
=
32
,
choices
=
ENVIRONMENT
,
blank
=
True
,
null
=
True
)
sn
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
)
date_added
=
models
.
DateTimeField
(
auto_now
=
True
,
default
=
datetime
.
datetime
.
now
())
is_active
=
models
.
BooleanField
(
default
=
True
)
comment
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
)
def
__unicode__
(
self
):
return
self
.
ip
def
get_user
(
self
):
perm_list
=
[]
asset_group_all
=
self
.
bis_group
.
all
()
for
asset_group
in
asset_group_all
:
perm_list
.
extend
(
asset_group
.
perm_set
.
all
())
user_group_list
=
[]
for
perm
in
perm_list
:
user_group_list
.
append
(
perm
.
user_group
)
user_permed_list
=
[]
for
user_group
in
user_group_list
:
user_permed_list
.
extend
(
user_group
.
user_set
.
all
())
user_permed_list
=
list
(
set
(
user_permed_list
))
return
user_permed_list
class
AssetAlias
(
models
.
Model
):
user
=
models
.
ForeignKey
(
User
)
asset
=
models
.
ForeignKey
(
Asset
)
alias
=
models
.
CharField
(
max_length
=
100
,
null
=
True
)
def
__unicode__
(
self
):
return
self
.
alias
jasset/urls.py
View file @
0f29745b
...
@@ -4,15 +4,14 @@ from jasset.views import *
...
@@ -4,15 +4,14 @@ from jasset.views import *
urlpatterns
=
patterns
(
''
,
urlpatterns
=
patterns
(
''
,
url
(
r'^asset_add/$'
,
asset_add
),
url
(
r'^asset_add/$'
,
asset_add
),
# url(r"^host_add_multi/$", hos
t_add_batch),
url
(
r"^asset_add_batch/$"
,
asse
t_add_batch
),
url
(
r'^group_del/$'
,
group_del
),
url
(
r'^group_del/$'
,
group_del
),
url
(
r'^asset_list/$'
,
asset_list
),
url
(
r'^asset_list/$'
,
asset_list
),
url
(
r'^asset_del/$'
,
asset_del
),
url
(
r'^asset_del/$'
,
asset_del
),
url
(
r"^asset_detail/$"
,
asset_detail
),
url
(
r"^asset_detail/$"
,
asset_detail
),
url
(
r'^asset_edit/$'
,
asset_edit
),
url
(
r'^asset_edit/$'
,
asset_edit
),
url
(
r'^asset_update/$'
,
asset_update
),
# url(r'^search/$', host_search),
# url(r'^search/$', host_search),
# url(r"^host_detail/$", host_detail),
# url(r"^dept_host_ajax/$", dept_host_ajax),
# url(r"^show_all_ajax/$", show_all_ajax),
# url(r"^show_all_ajax/$", show_all_ajax),
url
(
r'^group_add/$'
,
group_add
),
url
(
r'^group_add/$'
,
group_add
),
url
(
r'^group_list/$'
,
group_list
),
url
(
r'^group_list/$'
,
group_list
),
...
@@ -27,4 +26,5 @@ urlpatterns = patterns('',
...
@@ -27,4 +26,5 @@ urlpatterns = patterns('',
url
(
r'^idc_detail/$'
,
idc_detail
),
url
(
r'^idc_detail/$'
,
idc_detail
),
url
(
r'^idc_edit/$'
,
idc_edit
),
url
(
r'^idc_edit/$'
,
idc_edit
),
url
(
r'^idc_del/$'
,
idc_del
),
url
(
r'^idc_del/$'
,
idc_del
),
url
(
r'^upload/$'
,
asset_upload
),
)
)
\ No newline at end of file
jasset/views.py
View file @
0f29745b
# coding:utf-8
# coding:utf-8
import
ast
import
ast
from
django.db.models
import
Q
from
django.db.models
import
Q
from
django.shortcuts
import
get_object_or_404
from
django.shortcuts
import
get_object_or_404
from
jasset.asset_api
import
*
from
jasset.asset_api
import
*
from
jumpserver.api
import
*
from
jumpserver.api
import
*
from
jasset.forms
import
AssetForm
,
IdcForm
from
jasset.forms
import
AssetForm
,
IdcForm
from
jasset.models
import
Asset
,
IDC
,
AssetGroup
,
ASSET_TYPE
,
ASSET_STATUS
from
jasset.models
import
Asset
,
IDC
,
AssetGroup
,
ASSET_TYPE
,
ASSET_STATUS
from
ansible_api
import
Tasks
@require_role
(
'admin'
)
@require_role
(
'admin'
)
...
@@ -175,6 +174,12 @@ def asset_add(request):
...
@@ -175,6 +174,12 @@ def asset_add(request):
return
my_render
(
'jasset/asset_add.html'
,
locals
(),
request
)
return
my_render
(
'jasset/asset_add.html'
,
locals
(),
request
)
@require_role
(
'admin'
)
def
asset_add_batch
(
request
):
header_title
,
path1
,
path2
=
u'添加资产'
,
u'资产管理'
,
u'批量添加'
return
my_render
(
'jasset/asset_add_batch.html'
,
locals
(),
request
)
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
asset_del
(
request
):
def
asset_del
(
request
):
"""
"""
...
@@ -207,8 +212,6 @@ def asset_edit(request):
...
@@ -207,8 +212,6 @@ def asset_edit(request):
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
username
=
request
.
session
.
get
(
'username'
,
'admin'
)
username
=
request
.
session
.
get
(
'username'
,
'admin'
)
# if not asset_id:
# return HttpResponse('没有该主机')
asset
=
get_object
(
Asset
,
id
=
asset_id
)
asset
=
get_object
(
Asset
,
id
=
asset_id
)
asset_old
=
copy_model_instance
(
asset
)
asset_old
=
copy_model_instance
(
asset
)
af
=
AssetForm
(
instance
=
asset
)
af
=
AssetForm
(
instance
=
asset
)
...
@@ -231,8 +234,8 @@ def asset_edit(request):
...
@@ -231,8 +234,8 @@ def asset_edit(request):
af_save
.
password
=
''
af_save
.
password
=
''
af_save
.
save
()
af_save
.
save
()
af_post
.
save_m2m
()
af_post
.
save_m2m
()
asset_new
=
get_object
(
Asset
,
id
=
asset_id
)
#
asset_new = get_object(Asset, id=asset_id)
asset_diff_one
(
asset_old
,
asset_new
)
#
asset_diff_one(asset_old, asset_new)
info
=
asset_diff
(
af_post
.
__dict__
.
get
(
'initial'
),
request
.
POST
)
info
=
asset_diff
(
af_post
.
__dict__
.
get
(
'initial'
),
request
.
POST
)
db_asset_alert
(
asset
,
username
,
info
)
db_asset_alert
(
asset
,
username
,
info
)
...
@@ -306,7 +309,7 @@ def asset_edit_batch(request):
...
@@ -306,7 +309,7 @@ def asset_edit_batch(request):
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
asset_detail
(
request
):
def
asset_detail
(
request
):
"""
"""
主机详情
Asset detail view
"""
"""
header_title
,
path1
,
path2
=
u'主机详细信息'
,
u'资产管理'
,
u'主机详情'
header_title
,
path1
,
path2
=
u'主机详细信息'
,
u'资产管理'
,
u'主机详情'
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
...
@@ -316,6 +319,53 @@ def asset_detail(request):
...
@@ -316,6 +319,53 @@ def asset_detail(request):
return
my_render
(
'jasset/asset_detail.html'
,
locals
(),
request
)
return
my_render
(
'jasset/asset_detail.html'
,
locals
(),
request
)
@require_role
(
'admin'
)
def
asset_update
(
request
):
"""
Asset update host info via ansible view
"""
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
asset
=
get_object
(
Asset
,
id
=
asset_id
)
if
not
asset
:
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
name
=
request
.
session
.
get
(
'username'
,
'admin'
)
if
asset
.
use_default_auth
:
username
=
'root'
password
=
'123456'
else
:
username
=
asset
.
username
password
=
asset
.
password
resource
=
[{
"hostname"
:
asset
.
ip
,
"port"
:
asset
.
port
,
"username"
:
username
,
"password"
:
password
}]
ansible_instance
=
Tasks
(
resource
)
ansible_asset_info
=
ansible_instance
.
get_host_info
()
if
ansible_asset_info
[
'status'
]
==
'ok'
:
asset_info
=
ansible_asset_info
[
'result'
][
asset
.
ip
]
if
asset_info
:
hostname
=
asset_info
.
get
(
'hostname'
)
other_ip
=
','
.
join
(
asset_info
.
get
(
'other_ip'
))
cpu_type
=
asset_info
.
get
(
'cpu_type'
)[
1
]
cpu_cores
=
asset_info
.
get
(
'cpu_cores'
)
cpu
=
cpu_type
+
' * '
+
unicode
(
cpu_cores
)
memory
=
asset_info
.
get
(
'memory'
)
disk
=
asset_info
.
get
(
'disk'
)
sn
=
asset_info
.
get
(
'sn'
)
brand
=
asset_info
.
get
(
'brand'
)
system_type
=
asset_info
.
get
(
'system_type'
)
system_version
=
asset_info
.
get
(
'system_version'
)
asset_dic
=
{
"hostname"
:
hostname
,
"other_ip"
:
other_ip
,
"cpu"
:
cpu
,
"memory"
:
memory
,
"disk"
:
disk
,
"system_type"
:
system_type
,
"system_version"
:
system_version
,
"brand"
:
brand
,
"sn"
:
sn
}
ansible_record
(
asset
,
asset_dic
,
name
)
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
idc_add
(
request
):
def
idc_add
(
request
):
"""
"""
...
@@ -343,6 +393,9 @@ def idc_add(request):
...
@@ -343,6 +393,9 @@ def idc_add(request):
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
idc_list
(
request
):
def
idc_list
(
request
):
"""
IDC list view
"""
header_title
,
path1
,
path2
=
u'查看IDC'
,
u'资产管理'
,
u'查看IDC'
header_title
,
path1
,
path2
=
u'查看IDC'
,
u'资产管理'
,
u'查看IDC'
posts
=
IDC
.
objects
.
all
()
posts
=
IDC
.
objects
.
all
()
keyword
=
request
.
GET
.
get
(
'keyword'
,
''
)
keyword
=
request
.
GET
.
get
(
'keyword'
,
''
)
...
@@ -358,6 +411,10 @@ def idc_list(request):
...
@@ -358,6 +411,10 @@ def idc_list(request):
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
idc_edit
(
request
):
def
idc_edit
(
request
):
"""
IDC edit view
"""
header_title
,
path1
,
path2
=
u'编辑IDC'
,
u'资产管理'
,
u'编辑IDC'
idc_id
=
request
.
GET
.
get
(
'id'
,
''
)
idc_id
=
request
.
GET
.
get
(
'id'
,
''
)
idc
=
get_object
(
IDC
,
id
=
idc_id
)
idc
=
get_object
(
IDC
,
id
=
idc_id
)
if
request
.
method
==
'POST'
:
if
request
.
method
==
'POST'
:
...
@@ -372,7 +429,9 @@ def idc_edit(request):
...
@@ -372,7 +429,9 @@ def idc_edit(request):
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
idc_detail
(
request
):
def
idc_detail
(
request
):
""" IDC详情 """
"""
IDC detail view
"""
header_title
,
path1
,
path2
=
u'IDC详情'
,
u'资产管理'
,
u'IDC详情'
header_title
,
path1
,
path2
=
u'IDC详情'
,
u'资产管理'
,
u'IDC详情'
idc_id
=
request
.
GET
.
get
(
'id'
,
''
)
idc_id
=
request
.
GET
.
get
(
'id'
,
''
)
idc
=
get_object
(
IDC
,
id
=
idc_id
)
idc
=
get_object
(
IDC
,
id
=
idc_id
)
...
@@ -384,7 +443,25 @@ def idc_detail(request):
...
@@ -384,7 +443,25 @@ def idc_detail(request):
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
idc_del
(
request
):
def
idc_del
(
request
):
"""
IDC delete view
"""
uuid
=
request
.
GET
.
get
(
'uuid'
,
''
)
uuid
=
request
.
GET
.
get
(
'uuid'
,
''
)
idc
=
get_object_or_404
(
IDC
,
uuid
=
uuid
)
idc
=
get_object_or_404
(
IDC
,
uuid
=
uuid
)
idc
.
delete
()
idc
.
delete
()
return
HttpResponseRedirect
(
'/jasset/idc_list/'
)
return
HttpResponseRedirect
(
'/jasset/idc_list/'
)
@require_role
(
'admin'
)
def
asset_upload
(
request
):
"""
Upload file view
"""
if
request
.
method
==
'POST'
:
excel_file
=
request
.
FILES
.
get
(
'file_name'
,
''
)
ret
=
excel_to_db
(
excel_file
)
if
ret
:
smg
=
u'批量添加成功'
else
:
emg
=
u'批量添加失败,请检查格式.'
return
my_render
(
'jasset/asset_add_batch.html'
,
locals
(),
request
)
jumpserver/templatetags/mytags.py
View file @
0f29745b
...
@@ -415,12 +415,29 @@ def str_to_list(info):
...
@@ -415,12 +415,29 @@ def str_to_list(info):
"""
"""
str to list
str to list
"""
"""
print
ast
.
literal_eval
(
info
),
type
(
ast
.
literal_eval
(
info
))
return
ast
.
literal_eval
(
info
)
return
ast
.
literal_eval
(
info
)
@register.filter
(
name
=
'str_to_dic'
)
def
str_to_dic
(
info
):
"""
str to list
"""
return
ast
.
literal_eval
(
info
)
.
iteritems
()
@register.filter
(
name
=
'str_to_code'
)
@register.filter
(
name
=
'str_to_code'
)
def
str_to_code
(
char_str
):
def
str_to_code
(
char_str
):
if
char_str
:
if
char_str
:
return
char_str
return
char_str
else
:
else
:
return
u'空'
return
u'空'
@register.filter
(
name
=
'ip_str_to_list'
)
def
ip_str_to_list
(
ip_str
):
"""
ip str to list
"""
return
ip_str
.
split
(
','
)
templates/jasset/asset_add.html
View file @
0f29745b
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
<div
class=
"panel-options"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<ul
class=
"nav nav-tabs"
>
<li
class=
"active"
><a
href=
"/jasset/asset_add/"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
单台添加
</a></li>
<li
class=
"active"
><a
href=
"/jasset/asset_add/"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
单台添加
</a></li>
<li><a
href=
"/jasset/
host_add_multi
"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
批量添加
</a></li>
<li><a
href=
"/jasset/
asset_add_batch
"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
批量添加
</a></li>
</ul>
</ul>
</div>
</div>
<div
class=
"panel-body"
>
<div
class=
"panel-body"
>
...
...
templates/jasset/asset_add_batch.html
0 → 100644
View file @
0f29745b
{% extends 'base.html' %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<style>
.file-box
{
position
:
relative
;
width
:
340px
}
.txt
{
height
:
22px
;
border
:
1px
solid
#cdcdcd
;
width
:
180px
;}
.file
{
position
:
absolute
;
top
:
0
;
right
:
80px
;
height
:
24px
;
filter
:
alpha
(
opacity
:
0
);
opacity
:
0
;
width
:
260px
}
</style>
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-lg-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>
<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=
"panel blank-panel"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li><a
href=
"/jasset/asset_add/"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
单台添加
</a></li>
<li
class=
"active"
><a
href=
"/jasset/asset_add_batch/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
批量添加
</a></li>
</ul>
</div>
<div
class=
"panel-body"
>
<div
id=
"tab-2"
class=
"ibox float-e-margins tab-pane active"
>
{% if emg %}
<div
class=
"alert alert-warning text-center"
>
{{ emg }}
</div>
{% endif %}
{% if smg %}
<div
class=
"alert alert-success text-center"
>
{{ smg }}
</div>
{% endif %}
<p>
请下载Excel文件, 按照格式填写主机信息, 上传导入.
<a
href=
"/static/files/excels/asset.xlsx"
>
点击下载模板
</a></p>
<form
action=
"/jasset/upload/"
method=
"POST"
enctype=
"multipart/form-data"
>
<div
class=
"file-box"
>
<input
id=
'textfield'
/>
<input
type=
"button"
class=
"btn btn-info btn-sm"
name=
"file_name"
value=
"点击选择文件"
>
<input
type=
"file"
name=
"file_name"
class=
"file"
id=
"fileField"
size=
"28"
onchange=
"document.getElementById('textfield').value=this.value"
/>
<button
class=
"btn btn-primary btn-sm"
type=
"submit"
>
上传文件
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
\ No newline at end of file
templates/jasset/asset_detail.html
View file @
0f29745b
...
@@ -37,6 +37,20 @@
...
@@ -37,6 +37,20 @@
<td
class=
"text-navy"
>
主机名
</td>
<td
class=
"text-navy"
>
主机名
</td>
<td>
{{ asset.hostname }}
</td>
<td>
{{ asset.hostname }}
</td>
</tr>
</tr>
<tr>
<td
class=
"text-navy"
>
其他IP
</td>
<td>
<table
class=
"table"
>
{% if asset.other_ip %}
{% for ip in asset.other_ip|ip_str_to_list %}
<tr>
<td>
{{ ip }}
</td>
</tr>
{% endfor %}
{% endif %}
</table>
</td>
</tr>
<tr>
<tr>
<td
class=
"text-navy"
>
远控IP
</td>
<td
class=
"text-navy"
>
远控IP
</td>
<td>
{{ asset.remote_ip }}
</td>
<td>
{{ asset.remote_ip }}
</td>
...
@@ -77,11 +91,21 @@
...
@@ -77,11 +91,21 @@
</tr>
</tr>
<tr>
<tr>
<td
class=
"text-navy"
>
内存
</td>
<td
class=
"text-navy"
>
内存
</td>
<td>
{{ asset.memory }}
</td>
<td>
{{ asset.memory }}
M
</td>
</tr>
</tr>
<tr>
<tr>
<td
class=
"text-navy"
>
硬盘
</td>
<td
class=
"text-navy"
>
硬盘
</td>
<td>
{{ asset.disk }}
</td>
<td>
<table
class=
"table"
>
{% if asset.disk %}
{% for disk, value in asset.disk|str_to_dic %}
<tr>
<td><span
class=
"text-navy"
>
{{ disk }}
</span>
&
nbsp
&
nbsp
&
nbsp {{ value }}
</td>
</tr>
{% endfor %}
{% endif %}
</table>
</td>
</tr>
</tr>
<tr>
<tr>
<td
class=
"text-navy"
>
资产编号
</td>
<td
class=
"text-navy"
>
资产编号
</td>
...
@@ -95,6 +119,10 @@
...
@@ -95,6 +119,10 @@
<td
class=
"text-navy"
>
主机类型
</td>
<td
class=
"text-navy"
>
主机类型
</td>
<td>
{{ asset.get_asset_type_display }}
</td>
<td>
{{ asset.get_asset_type_display }}
</td>
</tr>
</tr>
<tr>
<td
class=
"text-navy"
>
系统版本
</td>
<td>
{{ asset.system_type }} {{ asset.system_version }}
</td>
</tr>
<tr>
<tr>
<td
class=
"text-navy"
>
运行环境
</td>
<td
class=
"text-navy"
>
运行环境
</td>
<td>
{{ asset.get_env_display }}
</td>
<td>
{{ asset.get_env_display }}
</td>
...
...
templates/jasset/asset_list.html
View file @
0f29745b
...
@@ -107,7 +107,8 @@
...
@@ -107,7 +107,8 @@
<th
class=
"text-center"
>
主机名
</th>
<th
class=
"text-center"
>
主机名
</th>
<th
class=
"text-center"
>
IDC
</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"
>
配置信息
</th>
#}
<th
class=
"text-center"
>
操作系统
</th>
<th
class=
"text-center"
>
使用默认管理
</th>
<th
class=
"text-center"
>
使用默认管理
</th>
<th
class=
"text-center"
>
操作
</th>
<th
class=
"text-center"
>
操作
</th>
</tr>
</tr>
...
@@ -122,12 +123,14 @@
...
@@ -122,12 +123,14 @@
<td
class=
"text-center"
>
{{ asset.hostname }}
</td>
<td
class=
"text-center"
>
{{ asset.hostname }}
</td>
<td
class=
"text-center"
>
{{ asset.idc.name }}
</td>
<td
class=
"text-center"
>
{{ asset.idc.name }}
</td>
<td
class=
"text-center"
>
{{ asset.group.all|group_str2 }}
</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.cpu }}|{{ asset.memory }}|{{ asset.disk }}
</td>
#}
<td
class=
"text-center"
>
{{ asset.system_type }}{{ asset.system_version }}
</td>
<td
class=
"text-center"
>
{{ asset.use_default_auth|bool2str }}
</td>
<td
class=
"text-center"
>
{{ asset.use_default_auth|bool2str }}
</td>
<td
class=
"text-center"
data-editable=
'false'
>
<td
class=
"text-center"
data-editable=
'false'
>
<a
href=
"/jasset/asset_detail/?id={{ asset.id }}"
class=
"btn btn-xs btn-primary"
>
详情
</a>
<a
href=
"/jasset/asset_detail/?id={{ asset.id }}"
class=
"btn btn-xs btn-primary"
>
详情
</a>
{% ifnotequal session_role_id 0 %}
{% ifnotequal session_role_id 0 %}
<a
href=
"/jasset/asset_edit/?id={{ asset.id }}"
class=
"btn btn-xs btn-info"
>
编辑
</a>
<a
href=
"/jasset/asset_edit/?id={{ asset.id }}"
class=
"btn btn-xs btn-info"
>
编辑
</a>
<a
href=
"/jasset/asset_update/?id={{ asset.id }}"
class=
"btn btn-xs btn-info"
>
更新
</a>
<a
value=
"/jasset/asset_del/?id={{ asset.id }}"
class=
"btn btn-xs btn-danger asset_del"
>
删除
</a>
<a
value=
"/jasset/asset_del/?id={{ asset.id }}"
class=
"btn btn-xs btn-danger asset_del"
>
删除
</a>
{% endifnotequal %}
{% endifnotequal %}
</td>
</td>
...
...
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