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
13f34a8b
Commit
13f34a8b
authored
Oct 25, 2016
by
Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ops: [future]完成ansible2.0 API 的基本封装.
parent
73f5891f
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
144 additions
and
86 deletions
+144
-86
ansible_api.py
apps/ops/ansible_api.py
+144
-86
No files found.
apps/ops/ansible_api.py
View file @
13f34a8b
...
@@ -80,56 +80,34 @@ class Config(object):
...
@@ -80,56 +80,34 @@ class Config(object):
default_config
.
HOST_KEY_CHECKING
=
False
default_config
.
HOST_KEY_CHECKING
=
False
class
MyInventory
(
object
):
class
InventoryMixin
(
object
):
"""Ansible Inventory对象的封装, Inventory是Ansbile中的核心概念(资产清单),
"""提供生成Ansible inventory对象的方法
这个概念和CMDB很像,都是对资产的抽象. 为了简化Inventory的使用, 通过传入资产列表即可初始化Inventory.
"""
"""
def
__init__
(
self
,
*
assets
,
**
group
):
def
gen_inventory
(
self
):
"""初始化Inventory对象, args为一个资产列表, kwargs是资产组变量列表, 比如
"""用于生成动态构建Ansible Inventory.
args:
[{
"name": "asset_name",
"ip": "asset_ip",
"port": "asset_port",
"username": "asset_user",
"password": "asset_pass",
"key": "asset_private_key",
"group": "asset_group_name",
...
}]
kwargs:
"groupName1": {"group_variable1": "value1",...}
"groupName2": {"group_variable1": "value1",...}
"""
self
.
assets
=
assets
self
.
assets_group
=
group
self
.
loader
=
DataLoader
()
self
.
variable_manager
=
VariableManager
()
self
.
groups
=
[]
self
.
inventory
=
self
.
gen_inventory
()
def
__gen_group
(
self
):
:return: 返回一个Ansible的inventory对象
"""初始化Ansible Group, 将资产添加到Inventory里面
:return: None
"""
"""
# TODO: 验证输入
# 创建Ansible Group.
# 创建Ansible Group.
for
asset
in
self
.
asse
ts
:
for
asset
in
self
.
hos
ts
:
g_name
=
asset
.
get
(
'group'
,
'default'
)
g_name
=
asset
.
get
(
'group'
,
'default'
)
if
g_name
not
in
[
g
.
name
for
g
in
self
.
groups
]:
if
g_name
not
in
[
g
.
name
for
g
in
self
.
groups
]:
group
=
Group
(
name
=
asset
.
get
(
'group'
,
'default'
))
group
=
Group
(
name
=
asset
.
get
(
'group'
,
'default'
))
self
.
groups
.
append
(
group
)
self
.
groups
.
append
(
group
)
# 初始化组变量
# 初始化组变量
for
group_name
,
variables
in
self
.
assets_group
.
iteritems
():
for
group_name
,
variables
in
self
.
group_vars
.
iteritems
():
for
g
in
self
.
groups
:
for
g
in
self
.
groups
:
if
g
.
name
==
group_name
:
if
g
.
name
==
group_name
:
for
v_name
,
v_value
in
variables
:
for
v_name
,
v_value
in
variables
:
g
.
set_variable
(
v_name
,
v_value
)
g
.
set_variable
(
v_name
,
v_value
)
# 往组里面添加Host
# 往组里面添加Host
for
asset
in
self
.
asse
ts
:
for
asset
in
self
.
hos
ts
:
host
=
Host
(
name
=
asset
[
'name'
],
port
=
asset
[
'port'
])
host
=
Host
(
name
=
asset
[
'name'
],
port
=
asset
[
'port'
])
host
.
set_variable
(
'ansible_ssh_host'
,
asset
[
'ip'
])
host
.
set_variable
(
'ansible_ssh_host'
,
asset
[
'ip'
])
host
.
set_variable
(
'ansible_ssh_port'
,
asset
[
'port'
])
host
.
set_variable
(
'ansible_ssh_port'
,
asset
[
'port'
])
...
@@ -147,36 +125,103 @@ class MyInventory(object):
...
@@ -147,36 +125,103 @@ class MyInventory(object):
if
g
.
name
==
asset
.
get
(
'group'
,
'default'
):
if
g
.
name
==
asset
.
get
(
'group'
,
'default'
):
g
.
add_host
(
host
)
g
.
add_host
(
host
)
def
validate
(
self
):
# 生成Ansible inventory对象
pass
inventory
=
Inventory
(
loader
=
self
.
loader
,
variable_manager
=
self
.
variable_manager
,
host_list
=
[])
def
gen_inventory
(
self
):
self
.
validate
()
i
=
Inventory
(
loader
=
self
.
loader
,
variable_manager
=
self
.
variable_manager
,
host_list
=
[])
self
.
__gen_group
()
for
g
in
self
.
groups
:
for
g
in
self
.
groups
:
i
.
add_group
(
g
)
i
nventory
.
add_group
(
g
)
self
.
variable_manager
.
set_inventory
(
i
)
self
.
variable_manager
.
set_inventory
(
i
nventory
)
return
i
return
i
nventory
class
PlayBookRunner
(
object
):
class
CallbackModule
(
CallbackBase
):
"""
用于执行AnsiblePlaybook的接口.简化Playbook对象的使用
"""
处理和分析Ansible运行结果,并保存数据.
"""
"""
CALLBACK_VERSION
=
2.0
CALLBACK_TYPE
=
'stdout'
CALLBACK_NAME
=
'json'
def
__init__
(
self
,
display
=
None
):
super
(
CallbackModule
,
self
)
.
__init__
(
display
)
self
.
results
=
[]
def
_new_play
(
self
,
play
):
return
{
'play'
:
{
'name'
:
play
.
name
,
'id'
:
str
(
play
.
_uuid
)
},
'tasks'
:
[]
}
def
_new_task
(
self
,
task
):
return
{
'task'
:
{
'name'
:
task
.
name
,
'id'
:
str
(
task
.
_uuid
)
},
'hosts'
:
{}
}
def
v2_playbook_on_play_start
(
self
,
play
):
self
.
results
.
append
(
self
.
_new_play
(
play
))
def
v2_playbook_on_task_start
(
self
,
task
,
is_conditional
):
self
.
results
[
-
1
][
'tasks'
]
.
append
(
self
.
_new_task
(
task
))
def
v2_runner_on_ok
(
self
,
result
,
**
kwargs
):
host
=
result
.
_host
self
.
results
[
-
1
][
'tasks'
][
-
1
][
'hosts'
][
host
.
name
]
=
result
.
_result
def
v2_playbook_on_stats
(
self
,
stats
):
"""Display info about playbook statistics"""
hosts
=
sorted
(
stats
.
processed
.
keys
())
def
__init__
(
self
,
inventory
,
config
,
palybook_path
,
playbook_var
,
become_pass
,
verbosity
=
0
):
summary
=
{}
for
h
in
hosts
:
s
=
stats
.
summarize
(
h
)
summary
[
h
]
=
s
output
=
{
'plays'
:
self
.
results
,
'stats'
:
summary
}
print
(
json
.
dumps
(
output
,
indent
=
4
,
sort_keys
=
True
))
v2_runner_on_failed
=
v2_runner_on_ok
v2_runner_on_unreachable
=
v2_runner_on_ok
v2_runner_on_skipped
=
v2_runner_on_ok
class
PlayBookRunner
(
InventoryMixin
):
"""用于执行AnsiblePlaybook的接口.简化Playbook对象的使用.
"""
"""
:param inventory: myinventory实例
def
__init__
(
self
,
config
,
palybook_path
,
playbook_var
,
become_pass
,
*
hosts
,
**
group_vars
):
"""
:param config: Config实例
:param config: Config实例
:param palybook_path: playbook的路径
:param palybook_path: playbook的路径
:param playbook_var: 执行Playbook时的变量
:param playbook_var: 执行Playbook时的变量
:param become_pass: sudo passsword
:param become_pass: sudo passsword
:param verbosity: --verbosity
:param hosts: 可变位置参数, 为一个资产列表, 每一个资产用dict表示, 以下是这个dict必须包含的key
[{
"name": "asset_name",
"ip": "asset_ip",
"port": "asset_port",
"username": "asset_user",
"password": "asset_pass",
"key": "asset_private_key",
"group": "asset_group_name",
...
}]
:param group_vars: 可变关键字参数, 是资产组变量, 记录对应的资产组变量
"groupName1": {"group_variable1": "value1",...}
"groupName2": {"group_variable1": "value1",...}
"""
"""
self
.
options
=
config
self
.
options
=
config
self
.
options
.
verbosity
=
verbosity
self
.
options
.
connection
=
'smart'
# 设置verbosity级别, 及命令行的--verbose选项
# 设置verbosity级别, 及命令行的--verbose选项
self
.
display
=
Display
()
self
.
display
=
Display
()
...
@@ -190,16 +235,24 @@ class PlayBookRunner(object):
...
@@ -190,16 +235,24 @@ class PlayBookRunner(object):
passwords
=
{
'become_pass'
:
become_pass
}
passwords
=
{
'become_pass'
:
become_pass
}
# 传入playbook的路径,以及执行需要的变量
# 传入playbook的路径,以及执行需要的变量
inventory
.
variable_manager
.
extra_vars
=
playbook_var
pb_dir
=
os
.
path
.
dirname
(
__file__
)
pb_dir
=
os
.
path
.
dirname
(
__file__
)
playbook
=
"
%
s/
%
s"
%
(
pb_dir
,
palybook_path
)
playbook
=
"
%
s/
%
s"
%
(
pb_dir
,
palybook_path
)
# 生成Ansible inventory, 这些变量Mixin都会用到
self
.
hosts
=
hosts
self
.
group_vars
=
group_vars
self
.
loader
=
DataLoader
()
self
.
variable_manager
=
VariableManager
()
self
.
groups
=
[]
self
.
variable_manager
.
extra_vars
=
playbook_var
self
.
inventory
=
self
.
gen_inventory
()
# 初始化playbook的executor
# 初始化playbook的executor
self
.
pbex
=
playbook_executor
.
PlaybookExecutor
(
self
.
pbex
=
playbook_executor
.
PlaybookExecutor
(
playbooks
=
[
playbook
],
playbooks
=
[
playbook
],
inventory
=
inventory
,
inventory
=
self
.
inventory
,
variable_manager
=
inventory
.
variable_manager
,
variable_manager
=
self
.
variable_manager
,
loader
=
inventory
.
loader
,
loader
=
self
.
loader
,
options
=
self
.
options
,
options
=
self
.
options
,
passwords
=
passwords
)
passwords
=
passwords
)
...
@@ -223,13 +276,15 @@ class PlayBookRunner(object):
...
@@ -223,13 +276,15 @@ class PlayBookRunner(object):
return
stats
return
stats
class
ADHocRunner
(
object
):
class
ADHocRunner
(
InventoryMixin
):
"""ADHoc接口
"""ADHoc接口
"""
"""
def
__init__
(
self
,
inventory
,
config
,
become_pass
=
None
,
verbosity
=
0
):
def
__init__
(
self
,
config
,
play_data
,
become_pass
=
None
,
*
hosts
,
**
group_vars
):
"""
"""
:param inventory: myinventory实例
:param hosts: 见PlaybookRunner参数
:param group_vars: 见PlaybookRunner参数
:param config: Config实例
:param config: Config实例
:param play_data:
:param play_data:
play_data = dict(
play_data = dict(
name="Ansible Ad-Hoc",
name="Ansible Ad-Hoc",
...
@@ -240,8 +295,6 @@ class ADHocRunner(object):
...
@@ -240,8 +295,6 @@ class ADHocRunner(object):
"""
"""
self
.
options
=
config
self
.
options
=
config
self
.
options
.
verbosity
=
verbosity
self
.
options
.
connection
=
'smart'
# 设置verbosity级别, 及命令行的--verbose选项
# 设置verbosity级别, 及命令行的--verbose选项
self
.
display
=
Display
()
self
.
display
=
Display
()
...
@@ -254,22 +307,18 @@ class ADHocRunner(object):
...
@@ -254,22 +307,18 @@ class ADHocRunner(object):
self
.
options
.
become_user
=
'root'
self
.
options
.
become_user
=
'root'
self
.
passwords
=
{
'become_pass'
:
become_pass
}
self
.
passwords
=
{
'become_pass'
:
become_pass
}
# 初始化callback插件
# 生成Ansible inventory, 这些变量Mixin都会用到
# self.results_callback = ResultCallback()
self
.
hosts
=
hosts
self
.
group_vars
=
group_vars
self
.
loader
=
DataLoader
()
self
.
variable_manager
=
VariableManager
()
self
.
groups
=
[]
self
.
inventory
=
self
.
gen_inventory
()
# 初始化Play
# 初始化callback插件
play_source
=
{
self
.
results_callback
=
CallbackModule
()
"name"
:
"Ansible Play"
,
"hosts"
:
"*"
,
"gather_facts"
:
"no"
,
"tasks"
:
[
dict
(
action
=
dict
(
module
=
'shell'
,
args
=
'id'
),
register
=
'shell_out'
),
dict
(
action
=
dict
(
module
=
'debug'
,
args
=
dict
(
msg
=
'{{shell_out.stdout}}'
)))
]
}
self
.
play
=
Play
()
.
load
(
play_source
,
variable_manager
=
inventory
.
variable_manager
,
loader
=
inventory
.
loader
)
self
.
play
=
Play
()
.
load
(
play_data
,
variable_manager
=
self
.
variable_manager
,
loader
=
self
.
loader
)
self
.
inventory
=
inventory
def
run
(
self
):
def
run
(
self
):
"""执行ADHoc 记录日志, 处理结果
"""执行ADHoc 记录日志, 处理结果
...
@@ -278,16 +327,16 @@ class ADHocRunner(object):
...
@@ -278,16 +327,16 @@ class ADHocRunner(object):
# TODO:日志和结果分析
# TODO:日志和结果分析
try
:
try
:
tqm
=
TaskQueueManager
(
tqm
=
TaskQueueManager
(
inventory
=
self
.
inventory
.
inventory
,
inventory
=
self
.
inventory
,
variable_manager
=
self
.
inventory
.
variable_manager
,
variable_manager
=
self
.
variable_manager
,
loader
=
self
.
inventory
.
loader
,
loader
=
self
.
loader
,
stdout_callback
=
default_config
.
DEFAULT_STDOUT_CALLBACK
,
stdout_callback
=
self
.
results_callback
,
options
=
self
.
options
,
options
=
self
.
options
,
passwords
=
self
.
passwords
passwords
=
self
.
passwords
)
)
ext_code
=
tqm
.
run
(
self
.
play
)
result
=
tqm
.
run
(
self
.
play
)
result
=
json
.
dumps
(
self
.
results_callback
.
results
)
return
result
return
ext_code
,
result
finally
:
finally
:
if
tqm
:
if
tqm
:
tqm
.
cleanup
()
tqm
.
cleanup
()
...
@@ -300,11 +349,19 @@ if __name__ == "__main__":
...
@@ -300,11 +349,19 @@ if __name__ == "__main__":
"ip"
:
"localhost"
,
"ip"
:
"localhost"
,
"port"
:
"22"
,
"port"
:
"22"
,
"username"
:
"yumaojun"
,
"username"
:
"yumaojun"
,
"password"
:
"
xxx
"
,
"password"
:
"
yusky0902
"
,
"key"
:
"asset_private_key"
,
"key"
:
"asset_private_key"
,
}]
}]
inv
=
MyInventory
(
*
assets
)
# 初始化Play
print
inv
.
inventory
.
get_group
(
'default'
)
.
get_hosts
()
play_source
=
{
hoc
=
ADHocRunner
(
inv
,
conf
,
'xxx'
)
"name"
:
"Ansible Play"
,
hoc
.
run
()
"hosts"
:
"*"
,
"gather_facts"
:
"no"
,
"tasks"
:
[
dict
(
action
=
dict
(
module
=
'setup'
)),
]
}
hoc
=
ADHocRunner
(
conf
,
play_source
,
'yusky0902'
,
*
assets
)
ext_code
,
result
=
hoc
.
run
()
print
ext_code
print
result
\ 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