自动化运维 Ansible 2.2.1 playbook api

最近把Ansible升级到2.2.1,感觉变化比较大,花些时间对playbook api 的调用做下总结

[b]重大更新:[/b]
[list]
[*]ansible.conf中添加了strategy:free属性, 配置该属性可以实现任务的异步执行,再也不用的等待所有机器执行完,才进入下个任务了。
[*]ansible api 和 ansible-playbook api 的调用方式
[/list]

[b]发现的问题:[/b]
[list]
[*]2.2.1 的执行速度比1.9略慢
[/list]

[b]Ansible Playbook api的调用[/b]

核心类
ansible.executor.task_queue_manager
[list]
[*]将各类参数放到"ansible.executor.task_queue_manager"类中
[*]将playbook 拆分成多个task 放入ansible.executor.task_queue_manager中
[/list]

直接上源码

class TaskQueueManager:

'''
This class handles the multiprocessing requirements of Ansible by
creating a pool of worker forks, a result handler fork, and a
manager object with shared datastructures/queues for coordinating
work between all processes.

The queue manager is responsible for loading the play strategy plugin,
which dispatches the Play's tasks to hosts.
'''

def __init__(self, inventory, variable_manager, loader, options, passwords, stdout_callback=None, run_additional_callbacks=True, run_tree=False):

self._inventory = inventory
self._variable_manager = variable_manager
self._loader = loader
self._options = options
self._stats = AggregateStats()
self.passwords = passwords
self._stdout_callback = stdout_callback
self._run_additional_callbacks = run_additional_callbacks
self._run_tree = run_tree

self._callbacks_loaded = False
self._callback_plugins = []
self._start_at_done = False

# make sure the module path (if specified) is parsed and
# added to the module_loader object

...



[b]参数:[/b]
[list]
[*]inventory --> 由ansible.inventory模块创建,用于导入inventory文件 (也可以直接使用实例)
[*]variable_manager --> 由ansible.vars模块创建,用于存储各类变量信息
[*]loader --> 由ansible.parsing.dataloader模块创建,用于数据解析
[*]options --> 存放各类配置信息的数据字典
[*]passwords --> 登录密码,可设置加密信息
[*]stdout_callback --> 回调函数(可以自定义返回结果)
[/list]


完整的例子:

class MyInventory(object):
"""
this is my ansible inventory object
"""

def __init__(self, loader, variable_manager, host_list, groupname='default_group'):
"""
:param loader:
:param variable_manager:
:param host_list: ex.:[{'hostname':'','ip':'','port':,'username':,'password':,'become_root_passwd':,'become':,}]
:param groupname:
"""

self.inventory = Inventory(loader, variable_manager, host_list=[])
# self.inventory.refresh_inventory()
self.set_inventory(host_list, groupname)

def get_inventory(self):
return self.inventory

def set_inventory(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")
hostip = host.get('ip', hostname)
hostport = host.get("port")
username = host.get("username")
password = host.get("password")
become_root_passwd = host.get("become_root_passwd")
become = host.get("become", True)

my_host = Host(name=hostname, port=hostport)
my_host.set_variable('ansible_host', hostip)
my_host.set_variable('ansible_port', hostport)
my_host.set_variable('ansible_user', username)
my_host.set_variable('ansible_ssh_pass', password)
my_host.set_variable('ansible_become', become)
my_host.set_variable('ansible_become_method', 'su')
my_host.set_variable('ansible_become_user', 'root')
my_host.set_variable('ansible_become_pass', become_root_passwd)

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)


class ResultsCallBack(CallbackBase):
def __init__(self, *args, **kwargs):
super(ResultsCallBack, self).__init__(*args, **kwargs)
self.host_ok = {}
self.host_unreachable = {}
self.host_failed = {}

def v2_runner_on_unreachable(self, result):
self.host_unreachable[result._host.get_name()] = result

def v2_runner_on_ok(self, result, *args, **kwargs):
self.host_ok[result._host.get_name()] = result

def v2_runner_on_failed(self, result, *args, **kwargs):
self.host_failed[result._host.get_name()] = result


class AnsiblePlaybookTask(object):
def __init__(self, host_list, **kwargs):
"""

:param host_list: [{'hostname':'','ip':'','port':,'username':,'password':,'become_root_passwd':,'become':,}]
"""
Options = namedtuple('Options',
['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check',
'listtags', 'listtasks', 'listhosts', 'syntax', 'stdout_callback'])
# initialize needed objects
self.loader = DataLoader()
self.variable_manager = VariableManager()
self.resultCallBack = ResultsCallBack()
self.options = Options(
listtags=None,
listtasks=None,
listhosts=None,
syntax=None,
connection='smart',
module_path=None,
forks=100 if not kwargs else kwargs.get('forks', 100),
become=True, become_method=None,
stdout_callback=self.resultCallBack,
become_user=None, check=False)
myInventory = MyInventory(self.loader, self.variable_manager, host_list)
self.inventory = myInventory.get_inventory()

def run_yaml(self, yml_path, extra_vars):
self.variable_manager.extra_vars = extra_vars
playbook = Playbook.load(yml_path, variable_manager=self.variable_manager, loader=self.loader)
p = playbook.get_plays()[0]
tqm = None
try:
tqm = TaskQueueManager(
inventory=self.inventory,
variable_manager=self.variable_manager,
loader=self.loader,
options=self.options,
passwords=None,
stdout_callback=self.options.stdout_callback,
)
result = tqm.run(playbook.get_plays()[0])
finally:
if tqm is not None:
tqm.cleanup()
return result

def get_result(self):
self.results_raw = {'ok': {}, 'failed': {}, 'unreachable': {}}
for host, result in self.resultCallBack.host_ok.items():
self.results_raw['ok'][host] = result._result

for host, result in self.resultCallBack.host_failed.items():
self.results_raw['failed'][host] = result._result

for host, result in self.resultCallBack.host_unreachable.items():
self.results_raw['unreachable'][host] = result._result

return self.results_raw


调用:

playbook = AnsiblePlaybookTask( [dict(hostname='XXX', ip='XXX', port=XXX, username="XXX",
password='XXX', become_root_passwd='XXX', become=XXX,
platform='XXX') ])
playbook.run_yaml(yml_path='XXX', extra_vars={})

playbook.get_result()



优化点:
[list]
[*]可以在MyInventory中设置每个Host的自身属性,并在yml里调用
[*]自定义callback,将结果按需要输出
[/list]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值