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
5a3c11f6
Commit
5a3c11f6
authored
Nov 22, 2015
by
wangyong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
asset update batch and crontab
parent
b8cb6f42
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
126 additions
and
571 deletions
+126
-571
ansible_api.py
jasset/ansible_api.py
+0
-459
asset_api.py
jasset/asset_api.py
+63
-0
models.py
jasset/models.py
+1
-1
urls.py
jasset/urls.py
+1
-0
views.py
jasset/views.py
+24
-52
settings.py
jumpserver/settings.py
+5
-0
asset_detail.html
templates/jasset/asset_detail.html
+6
-0
asset_edit.html
templates/jasset/asset_edit.html
+6
-0
asset_edit_batch.html
templates/jasset/asset_edit_batch.html
+0
-27
asset_list.html
templates/jasset/asset_list.html
+20
-32
No files found.
jasset/ansible_api.py
deleted
100644 → 0
View file @
b8cb6f42
# -*- 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 @
5a3c11f6
...
@@ -4,6 +4,8 @@ import xlsxwriter
...
@@ -4,6 +4,8 @@ import xlsxwriter
from
django.db.models
import
AutoField
from
django.db.models
import
AutoField
from
jumpserver.api
import
*
from
jumpserver.api
import
*
from
jasset.models
import
ASSET_STATUS
,
ASSET_TYPE
,
ASSET_ENV
,
IDC
,
AssetRecord
from
jasset.models
import
ASSET_STATUS
,
ASSET_TYPE
,
ASSET_ENV
,
IDC
,
AssetRecord
from
jperm.ansible_api
import
MyRunner
from
jperm.perm_api
import
gen_resource
def
group_add_asset
(
group
,
asset_id
=
None
,
asset_ip
=
None
):
def
group_add_asset
(
group
,
asset_id
=
None
,
asset_ip
=
None
):
...
@@ -406,3 +408,64 @@ def excel_to_db(excel_file):
...
@@ -406,3 +408,64 @@ def excel_to_db(excel_file):
asset
.
group
=
group_instance
asset
.
group
=
group_instance
asset
.
save
()
asset
.
save
()
return
True
return
True
def
get_ansible_asset_info
(
asset_ip
,
setup_info
):
disk_all
=
setup_info
.
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"
)
all_ip
=
setup_info
.
get
(
"ansible_all_ipv4_addresses"
)
other_ip_list
=
all_ip
.
remove
(
asset_ip
)
if
asset_ip
in
all_ip
else
[]
other_ip
=
','
.
join
(
other_ip_list
)
if
other_ip_list
else
''
# hostname = setup_info.get("ansible_hostname")
# ip = setup_info.get("ansible_default_ipv4").get("address")
mac
=
setup_info
.
get
(
"ansible_default_ipv4"
)
.
get
(
"macaddress"
)
brand
=
setup_info
.
get
(
"ansible_product_name"
)
cpu_type
=
setup_info
.
get
(
"ansible_processor"
)[
1
]
cpu_cores
=
setup_info
.
get
(
"ansible_processor_count"
)
cpu
=
cpu_type
+
' * '
+
unicode
(
cpu_cores
)
memory
=
setup_info
.
get
(
"ansible_memtotal_mb"
)
disk
=
disk_need
system_type
=
setup_info
.
get
(
"ansible_distribution"
)
system_version
=
setup_info
.
get
(
"ansible_distribution_version"
)
# asset_type = setup_info.get("ansible_system")
sn
=
setup_info
.
get
(
"ansible_product_serial"
)
asset_info
=
[
other_ip
,
mac
,
cpu
,
memory
,
disk
,
sn
,
system_type
,
system_version
,
brand
]
return
asset_info
def
asset_ansible_update
(
obj_list
,
name
=
''
):
resource
=
gen_resource
(
obj_list
)
ansible_instance
=
MyRunner
(
resource
)
ansible_asset_info
=
ansible_instance
.
run
(
module_name
=
'setup'
,
pattern
=
'*'
)
for
asset
in
obj_list
:
try
:
setup_info
=
ansible_asset_info
[
'contacted'
][
asset
.
hostname
][
'ansible_facts'
]
except
KeyError
:
continue
else
:
asset_info
=
get_ansible_asset_info
(
asset
.
ip
,
setup_info
)
other_ip
,
mac
,
cpu
,
memory
,
disk
,
sn
,
system_type
,
system_version
,
brand
=
asset_info
asset_dic
=
{
"other_ip"
:
other_ip
,
"mac"
:
mac
,
"cpu"
:
cpu
,
"memory"
:
memory
,
"disk"
:
disk
,
"sn"
:
sn
,
"system_type"
:
system_type
,
"system_version"
:
system_version
,
"brand"
:
brand
}
ansible_record
(
asset
,
asset_dic
,
name
)
def
asset_ansible_update_all
():
name
=
u'定时更新'
asset_all
=
Asset
.
objects
.
all
()
asset_ansible_update
(
asset_all
,
name
)
jasset/models.py
View file @
5a3c11f6
...
@@ -73,7 +73,7 @@ class Asset(models.Model):
...
@@ -73,7 +73,7 @@ class Asset(models.Model):
memory
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'内存'
)
memory
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'内存'
)
disk
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'硬盘'
)
disk
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'硬盘'
)
system_type
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"系统类型"
)
system_type
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"系统类型"
)
system_version
=
models
.
CharField
(
max_length
=
8
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"版本号"
)
system_version
=
models
.
CharField
(
max_length
=
8
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"
系统
版本号"
)
cabinet
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'机柜号'
)
cabinet
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'机柜号'
)
position
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
u'机器位置'
)
position
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
u'机器位置'
)
number
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'资产编号'
)
number
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'资产编号'
)
...
...
jasset/urls.py
View file @
5a3c11f6
...
@@ -11,6 +11,7 @@ urlpatterns = patterns('',
...
@@ -11,6 +11,7 @@ urlpatterns = patterns('',
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'^asset_update/$'
,
asset_update
),
url
(
r'^asset_update_batch/$'
,
asset_update_batch
),
# url(r'^search/$', host_search),
# url(r'^search/$', host_search),
# 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
),
...
...
jasset/views.py
View file @
5a3c11f6
...
@@ -6,7 +6,8 @@ from jumpserver.api import *
...
@@ -6,7 +6,8 @@ from jumpserver.api import *
from
jumpserver.models
import
Setting
from
jumpserver.models
import
Setting
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
from
jperm.ansible_api
import
Tasks
,
MyRunner
from
jperm.perm_api
import
gen_resource
@require_role
(
'admin'
)
@require_role
(
'admin'
)
...
@@ -197,7 +198,7 @@ def asset_edit(request):
...
@@ -197,7 +198,7 @@ def asset_edit(request):
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'
,
''
)
username
=
request
.
session
.
get
(
'username'
,
'admin'
)
username
=
request
.
user
.
username
asset
=
get_object
(
Asset
,
id
=
asset_id
)
asset
=
get_object
(
Asset
,
id
=
asset_id
)
if
asset
:
if
asset
:
password_old
=
asset
.
password
password_old
=
asset
.
password
...
@@ -311,7 +312,7 @@ def asset_list(request):
...
@@ -311,7 +312,7 @@ def asset_list(request):
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
asset_edit_batch
(
request
):
def
asset_edit_batch
(
request
):
af
=
AssetForm
()
af
=
AssetForm
()
name
=
request
.
session
.
get
(
'username'
,
'admin'
)
name
=
request
.
user
.
username
asset_group_all
=
AssetGroup
.
objects
.
all
()
asset_group_all
=
AssetGroup
.
objects
.
all
()
if
request
.
method
==
'POST'
:
if
request
.
method
==
'POST'
:
...
@@ -409,55 +410,30 @@ def asset_update(request):
...
@@ -409,55 +410,30 @@ def asset_update(request):
"""
"""
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
asset
=
get_object
(
Asset
,
id
=
asset_id
)
asset
=
get_object
(
Asset
,
id
=
asset_id
)
name
=
request
.
session
.
get
(
'username'
,
'admin'
)
name
=
request
.
user
.
username
if
not
asset
:
if
not
asset
:
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
if
asset
.
use_default_auth
:
default
=
Setting
.
objects
.
all
()
if
default
:
default
=
default
[
0
]
username
=
default
.
default_user
password
=
CRYPTOR
.
decrypt
(
default
.
default_password
)
port
=
default
.
default_port
else
:
return
HttpResponse
(
u'没有设置默认用户名和密码!'
)
else
:
else
:
username
=
asset
.
username
asset_ansible_update
(
asset_list
,
name
)
password
=
CRYPTOR
.
decrypt
(
asset
.
password
)
port
=
asset
.
port
resource
=
[{
"hostname"
:
asset
.
ip
,
"port"
:
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'
)
all_ip
=
asset_info
.
get
(
'other_ip'
)
other_ip_list
=
all_ip
.
remove
(
asset
.
ip
)
if
asset
.
ip
in
all_ip
else
[]
other_ip
=
','
.
join
(
other_ip_list
)
if
other_ip_list
else
''
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
)
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
@require_role
(
'admin'
)
def
asset_update_batch
(
request
):
if
request
.
method
==
'POST'
:
asset_list
=
[]
name
=
unicode
(
request
.
user
.
username
)
+
' - '
+
u'自动更新'
asset_id_all
=
unicode
(
request
.
POST
.
get
(
'asset_id_all'
,
''
))
asset_id_all
=
asset_id_all
.
split
(
','
)
for
asset_id
in
asset_id_all
:
asset
=
get_object
(
Asset
,
id
=
asset_id
)
if
asset
:
asset_list
.
append
(
asset
)
asset_ansible_update
(
asset_list
,
name
)
return
HttpResponse
(
u'批量更新成功!'
)
return
HttpResponse
(
u'批量更新成功!'
)
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
idc_add
(
request
):
def
idc_add
(
request
):
"""
"""
...
@@ -478,9 +454,7 @@ def idc_add(request):
...
@@ -478,9 +454,7 @@ def idc_add(request):
return
HttpResponseRedirect
(
"/jasset/idc_list/"
)
return
HttpResponseRedirect
(
"/jasset/idc_list/"
)
else
:
else
:
idc_form
=
IdcForm
()
idc_form
=
IdcForm
()
return
render_to_response
(
'jasset/idc_add.html'
,
return
my_render
(
'jasset/idc_add.html'
,
locals
(),
request
)
locals
(),
context_instance
=
RequestContext
(
request
))
@require_role
(
'admin'
)
@require_role
(
'admin'
)
...
@@ -496,9 +470,7 @@ def idc_list(request):
...
@@ -496,9 +470,7 @@ def idc_list(request):
else
:
else
:
posts
=
IDC
.
objects
.
exclude
(
name
=
'ALL'
)
.
order_by
(
'id'
)
posts
=
IDC
.
objects
.
exclude
(
name
=
'ALL'
)
.
order_by
(
'id'
)
contact_list
,
p
,
contacts
,
page_range
,
current_page
,
show_first
,
show_end
=
pages
(
posts
,
request
)
contact_list
,
p
,
contacts
,
page_range
,
current_page
,
show_first
,
show_end
=
pages
(
posts
,
request
)
return
render_to_response
(
'jasset/idc_list.html'
,
return
my_render
(
'jasset/idc_list.html'
,
locals
(),
request
)
locals
(),
context_instance
=
RequestContext
(
request
))
@require_role
(
'admin'
)
@require_role
(
'admin'
)
...
...
jumpserver/settings.py
View file @
5a3c11f6
...
@@ -66,6 +66,7 @@ INSTALLED_APPS = (
...
@@ -66,6 +66,7 @@ INSTALLED_APPS = (
'django.contrib.messages'
,
'django.contrib.messages'
,
'django.contrib.staticfiles'
,
'django.contrib.staticfiles'
,
'django.contrib.humanize'
,
'django.contrib.humanize'
,
'django_crontab'
,
'bootstrapform'
,
'bootstrapform'
,
'jumpserver'
,
'jumpserver'
,
'juser'
,
'juser'
,
...
@@ -149,3 +150,7 @@ USE_TZ = False
...
@@ -149,3 +150,7 @@ USE_TZ = False
STATIC_URL
=
'/static/'
STATIC_URL
=
'/static/'
BOOTSTRAP_COLUMN_COUNT
=
10
BOOTSTRAP_COLUMN_COUNT
=
10
CRONJOBS
=
[
(
'0 1 * * *'
,
'jasset.asset_api.asset_ansible_update_all'
)
]
templates/jasset/asset_detail.html
View file @
5a3c11f6
...
@@ -11,9 +11,15 @@
...
@@ -11,9 +11,15 @@
<div
class=
"ibox-title"
>
<div
class=
"ibox-title"
>
<span
class=
"text text-primary"
><b>
{{ asset.ip }}
</b></span>
<span
class=
"text text-primary"
><b>
{{ asset.ip }}
</b></span>
<div
class=
"ibox-tools"
>
<div
class=
"ibox-tools"
>
<a
class=
""
href=
"/jasset/asset_update/?id={{ asset.id }}"
>
<i
class=
"fa fa-refresh"
></i>
</a>
<a
class=
"collapse-link"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
<i
class=
"fa fa-chevron-up"
></i>
</a>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
<ul
class=
"dropdown-menu dropdown-user"
>
</ul>
</ul>
<a
class=
"close-link"
>
<a
class=
"close-link"
>
...
...
templates/jasset/asset_edit.html
View file @
5a3c11f6
...
@@ -96,6 +96,12 @@
...
@@ -96,6 +96,12 @@
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
{{ af.memory|bootstrap_horizontal }}
{{ af.memory|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
{{ af.system_type|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
{{ af.system_version|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
{{ af.disk|bootstrap_horizontal }}
{{ af.disk|bootstrap_horizontal }}
...
...
templates/jasset/asset_edit_batch.html
View file @
5a3c11f6
...
@@ -54,29 +54,17 @@
...
@@ -54,29 +54,17 @@
<div
class=
"col-sm-2"
>
<div
class=
"col-sm-2"
>
<div
class=
"radio i-checks"
>
<div
class=
"radio i-checks"
>
<label>
<label>
<
<<<<<<
HEAD
<
input
type=
"radio"
checked=
""
value=
"no_action"
id=
"no"
name=
"use_default_auth"
class=
"auth"
><span>
不修改
</span>
=======
<input
type=
"radio"
checked=
""
value=
""
id=
"no"
name=
"use_default_auth"
class=
"auth"
><span>
不修改
</span>
<input
type=
"radio"
checked=
""
value=
""
id=
"no"
name=
"use_default_auth"
class=
"auth"
><span>
不修改
</span>
>>>>>>> cmdb
</label>
</label>
</div>
</div>
<div
class=
"radio i-checks"
>
<div
class=
"radio i-checks"
>
<label>
<label>
<
<<<<<<
HEAD
<
input
type=
"radio"
id=
"default"
name=
"use_default_auth"
class=
"auth"
><span>
使用默认
</span>
=======
<input
type=
"radio"
id=
"default"
name=
"use_default_auth"
class=
"auth"
value=
"default"
><span>
使用默认
</span>
<input
type=
"radio"
id=
"default"
name=
"use_default_auth"
class=
"auth"
value=
"default"
><span>
使用默认
</span>
>>>>>>> cmdb
</label>
</label>
</div>
</div>
<div
class=
"radio i-checks"
>
<div
class=
"radio i-checks"
>
<label>
<label>
<
<<<<<<
HEAD
<
input
type=
"radio"
id=
"pass"
name=
"use_default_auth"
class=
"auth"
><span>
用户名密码
</span>
=======
<input
type=
"radio"
id=
"pass"
name=
"use_default_auth"
class=
"auth"
value=
"user_passwd"
><span>
用户名密码
</span>
<input
type=
"radio"
id=
"pass"
name=
"use_default_auth"
class=
"auth"
value=
"user_passwd"
><span>
用户名密码
</span>
>>>>>>> cmdb
</label>
</label>
</div>
</div>
</div>
</div>
...
@@ -138,21 +126,6 @@
...
@@ -138,21 +126,6 @@
</div>
</div>
<script>
<script>
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
<<<<<<<
HEAD
$
(
'#host_edit'
).
click
(
function
()
{
var
args
=
{};
var
match
=
null
;
var
uuid
=
decodeURIComponent
(
location
.
search
.
substring
(
1
));
var
reg
=
/
(?:([^
&
]
+
)
=
([^
&
]
+
))
/g
;
while
((
match
=
reg
.
exec
(
uuid
))
!==
null
){
args
[
match
[
1
]]
=
match
[
2
];
}
var
ids
=
args
[
'uuid'
];
$
(
'#uuid'
).
val
(
ids
)
});
=======
>>>>>>>
cmdb
$
(
'.auth'
).
click
(
function
(){
$
(
'.auth'
).
click
(
function
(){
if
(
$
(
this
).
attr
(
'id'
)
==
'pass'
){
if
(
$
(
this
).
attr
(
'id'
)
==
'pass'
){
$
(
'#admin_account'
).
css
(
'display'
,
'block'
)
$
(
'#admin_account'
).
css
(
'display'
,
'block'
)
...
...
templates/jasset/asset_list.html
View file @
5a3c11f6
...
@@ -130,7 +130,6 @@
...
@@ -130,7 +130,6 @@
<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>
...
@@ -142,7 +141,7 @@
...
@@ -142,7 +141,7 @@
<div
class=
"col-sm-6"
>
<div
class=
"col-sm-6"
>
<input
type=
"button"
id=
"asset_del"
class=
"btn btn-danger btn-sm"
name=
"del_button"
value=
"删除"
/>
<input
type=
"button"
id=
"asset_del"
class=
"btn btn-danger btn-sm"
name=
"del_button"
value=
"删除"
/>
<a
value=
"/jasset/asset_edit_batch/"
type=
"button"
class=
"btn btn-sm btn-warning iframe"
>
修改
</a>
<a
value=
"/jasset/asset_edit_batch/"
type=
"button"
class=
"btn btn-sm btn-warning iframe"
>
修改
</a>
<
a
value=
"/jasset/asset_update_batch/"
type=
"button"
class=
"btn btn-sm btn-info"
>
更新
</a
>
<
input
type=
"button"
id=
"asset_update"
class=
"btn btn-info btn-sm"
name=
"update_button"
value=
"更新"
/
>
</div>
</div>
{% include 'paginator.html' %}
{% include 'paginator.html' %}
</div>
</div>
...
@@ -156,23 +155,10 @@
...
@@ -156,23 +155,10 @@
{% block self_footer_js %}
{% block self_footer_js %}
<script>
<script>
$
(
'table td'
).
on
(
'change'
,
function
(
env
,
id
){
var
url
=
"/jasset/show_all_ajax/?env="
+
env
+
"&id="
+
id
;
console
.
log
(
url
);
$
.
ajax
({
type
:
"GET"
,
url
:
url
,
// data: $("#search_form").serialize(),
success
:
function
(
data
)
{
$
(
"#j_dept_"
+
id
).
html
(
data
);
}
});
});
$
(
document
).
ready
(
function
(){
$
(
document
).
ready
(
function
(){
$
(
'.asset_del'
).
click
(
function
(){
$
(
'.asset_del'
).
click
(
function
(){
var
row
=
$
(
this
).
closest
(
'tr'
);
var
row
=
$
(
this
).
closest
(
'tr'
);
if
(
confirm
(
"确定删除"
))
{
if
(
confirm
(
"确定删除
?
"
))
{
$
.
get
(
$
.
get
(
$
(
this
).
attr
(
'value'
),
$
(
this
).
attr
(
'value'
),
{},
{},
...
@@ -222,12 +208,11 @@
...
@@ -222,12 +208,11 @@
$
(
'#asset_del'
).
click
(
function
()
{
$
(
'#asset_del'
).
click
(
function
()
{
var
asset_id_all
=
getIDall
();
var
asset_id_all
=
getIDall
();
console
.
log
(
asset_id_all
);
if
(
asset_id_all
==
''
){
if
(
asset_id_all
==
''
){
alert
(
"请至少选择一行!"
);
alert
(
"请至少选择一行!"
);
return
false
;
return
false
;
}
}
if
(
confirm
(
"确定删除"
))
{
if
(
confirm
(
"确定删除
?
"
))
{
$
.
ajax
({
$
.
ajax
({
type
:
"post"
,
type
:
"post"
,
data
:
{
asset_id_all
:
asset_id_all
},
data
:
{
asset_id_all
:
asset_id_all
},
...
@@ -239,6 +224,23 @@
...
@@ -239,6 +224,23 @@
}
}
});
});
$
(
'#asset_update'
).
click
(
function
()
{
var
asset_id_all
=
getIDall
();
if
(
asset_id_all
==
''
){
alert
(
"请至少选择一行!"
);
return
false
;
}
layer
.
msg
(
'玩命更新中...'
,
{
time
:
200000
});
$
.
ajax
({
type
:
"post"
,
data
:
{
asset_id_all
:
asset_id_all
},
url
:
"/jasset/asset_update_batch/"
,
success
:
function
()
{
parent
.
location
.
reload
();
}
});
});
function
change_info
(){
function
change_info
(){
var
args
=
$
(
"#asset_form"
).
serialize
();
var
args
=
$
(
"#asset_form"
).
serialize
();
...
@@ -250,19 +252,6 @@
...
@@ -250,19 +252,6 @@
change_info
()
change_info
()
}
}
});
});
function
show_all
(
env
,
id
)
{
var
url
=
"/jasset/show_all_ajax/?env="
+
env
+
"&id="
+
id
;
console
.
log
(
url
);
$
.
ajax
({
type
:
"GET"
,
url
:
url
,
success
:
function
(
data
)
{
$
(
"#j_group_"
+
id
).
html
(
data
);
}
});
}
</script>
</script>
{% endblock %}
{% endblock %}
\ No newline at end of file
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