Ansible API 2.0 研究

本文详细介绍了 Ansible 2.0 版本 API 的使用方法,包括 inventory 和 playbook 的获取方式及执行流程。通过示例代码展示了如何简单执行 Ansible 任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编者:Matlon    
      Ansible 作为新出现的运维工具,是基于Python开发的,糅合了众多老牌运维工具的优点,实现了批量操作系统配置、批量程序的部署、批量运行命令等功能。在几个月前发布了2.0版本,变化比较大,大部分被重写,所以许多地方需要重新研究。

      如下,我们先看一下之前API的部分代码:

  1. import ansible.runner
  2. runner = ansible.runner.Runner(
  3.     module_name='ping',
  4.     module_args='',
  5.     pattern='web*',
  6.     forks=10)datastructure = runner.run()

使用runner 模块就可以调用ansible,执行一系列任务,但在2.0,这就变得比较困难了,首先看如下2.0的API的目录结构:

0?wx_fmt=png

在2.0中,仍然使用和之前相同的run()方法,但其不在runner模块中了,而在executor模块,它的基本类名是PlaybookExecutor,部分代码如下:

点击(此处)折叠或打开

  1. def __init__(self, playbooks, inventory, variable_manager, loader, options, passwords):

  2.         self._playbooks = playbooks #获取playbook的地址

  3.         self._inventory = inventory #获取主机列表

  4.         self._variable_manager = variable_manager #获取额外的变量

  5.         self._loader = loader

  6.         self._options = options

  7.         self.passwords = passwords

  8.         self._unreachable_hosts = dict()

  9.         if options.listhosts or options.listtasks or options.listtags or options.syntax

  10.            self._tqm = None

  11.         else:

  12.            self._tqm = TaskQueueManager(inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=self.passwords #通过调用任务管理器来执行playbook

所有的调度逻辑由run()来实现,playbook中的task由TaskQueueManager与taskExecutor来管理执行,暂时不需要理解,我们现在只需要去了解inventory和playbook如何获取,就可以简单执行,进到inventory目录,找到它的主要模块,

点击(此处)折叠或打开

  1. def __init__(self, loader,variable_manager,host_list=C.DEFAULT_HOST_LIST):

inventory 可以传参,参数的格式和类型需要考虑,解析如下:

#如果是str,根据逗号来区分并且去除空格,放到list里面

  1. if isinstance(host_list, string_types):
  2.             if "," in host_list:
  3.                 host_list = host_list.split(",")
  4.                 host_list = [ h for h in host_list if h and h.strip() ]

#host_list没有传入参数时,默认是去找/etc/ansible/hosts文件的

  1. if host_list is None:
  2.             pass

#如果是list类型,直接解析

  1. elif isinstance(host_list, list):
  2.             for h in host_list:
  3.                 (host, port) = parse_address(h, allow_ranges=False)
  4.                 all.add_host(Host(host, port))

#如果你指定host位置,它会从你的指定文件读入的,如果是hosts脚本,需返回一个json格式的对象。

  1. elif self._loader.path_exists(host_list):
  2.             if self.is_directory(host_list):
  3.                 # Ensure basedir is inside the directory
  4.                 host_list = os.path.join(self.host_list, "")
  5.                 self.parser = InventoryDirectory(loader=self._loader, groups=self.groups, filename=host_list) #group一般设为all、ungrouped
  6.             else:
  7.                 self.parser = get_file_parser(host_list, self.groups, self._loader)
  8.                 vars_loader.add_directory(self.basedir(), with_subdir=True)

综上:我们只要给inventory传入特定格式的参数,就可以处理host_list

之后,再看playbook如何传入,进入playbook 目录,找到playbook的初始化模块,有一个load()函数,就是获取playbook的文件路径,来加载playbook,如下:

  1. def load(file_name, variable_manager=None, loader=None):
  2.         pb = Playbook(loader=loader)
  3.         pb._load_playbook_data(file_name=file_name, variable_manager=variable_manager)
  4.         return pb

当然,也可以运行单个play,在playbook目录可以看到有一个play的模块,同样是load方法,只不过它获取的是一个dict类型对象,如下:

  1. play_data = dict(
  2.         name = "Ansible play",
  3.         hosts = "localhost",
  4.         tasks = [
  5.                   dict(action=dict(module='shell',args='ls'),register='shell_out')
  6.                   ]
  7.       )

  8. play = Play.load(play_data,variable_manager=variable_manager,loader=loader)

最终,可以得到如下API脚本:

点击(此处)折叠或打开

  1. #!/bin/env python
  2. import os
  3. import sys
  4. import json
  5. from collections import namedtuple
  6. from ansible.parsing.dataloader import DataLoader
  7. from ansible.vars import VariableManager
  8. from ansible.inventory import Inventory
  9. from ansible.executor.playbook_executor import PlaybookExecutor
  10. def install(request):
  11.         if 'ip' in request.GET:
  12.                 ip = request.GET['ip']
  13.                 host = []
  14.                 host.append(ip) #传入一个host列表
  15.                 variable_manager = VariableManager()
  16.                 loader = DataLoader()
  17.                 inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=host)
  18.                 playbook_path = '/etc/ansible/main.yml #传入一个playbook路径
  19.                 Options = namedtuple('Options', ['listtags', 'listtasks', 'listhosts', 'syntax', 'connection','module_path', 'forks', 'remote_user', 'private_key_file','ssh_common_args','ssh_extra_args','sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check'])
  20.                 options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, forks=100, remote_user='root, private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=True, become_method=None, become_user='root', verbosity=None, check=False)
                    passwords = {}
                    pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords)
                    results =  pbex.run()  #返回的结果是数字,不同的结果对应不同的数字  
                    return 1          
            else:
                    return  0


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30109892/viewspace-2063898/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/30109892/viewspace-2063898/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值