自动化运维 Ansible 2.2.1 playbook api
程序员文章站
2022-03-10 15:16:08
...
最近把Ansible升级到2.2.1,感觉变化比较大,花些时间对playbook api 的调用做下总结
重大更新:
发现的问题:
Ansible Playbook api的调用
核心类
ansible.executor.task_queue_manager
直接上源码
参数:
完整的例子:
调用:
优化点:
重大更新:
- ansible.conf中添加了strategy:free属性, 配置该属性可以实现任务的异步执行,再也不用的等待所有机器执行完,才进入下个任务了。
- ansible api 和 ansible-playbook api 的调用方式
发现的问题:
- 2.2.1 的执行速度比1.9略慢
Ansible Playbook api的调用
核心类
ansible.executor.task_queue_manager
- 将各类参数放到"ansible.executor.task_queue_manager"类中
- 将playbook 拆分成多个task 放入ansible.executor.task_queue_manager中
直接上源码
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 ...
参数:
- inventory --> 由ansible.inventory模块创建,用于导入inventory文件 (也可以直接使用实例)
- variable_manager --> 由ansible.vars模块创建,用于存储各类变量信息
- loader --> 由ansible.parsing.dataloader模块创建,用于数据解析
- options --> 存放各类配置信息的数据字典
- passwords --> 登录密码,可设置加密信息
- stdout_callback --> 回调函数(可以自定义返回结果)
完整的例子:
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()
优化点:
- 可以在MyInventory中设置每个Host的自身属性,并在yml里调用
- 自定义callback,将结果按需要输出
上一篇: Spring Boot 负载均衡之外置session状态保存
下一篇: 年味食物有哪些