2.x的ansible api和1.x的api差别是很大的在1.x中import ansible.runnerimport jsonrunner = ansible.runner.Runner( module_name='ping', # 模块名 module_args='', # 模块参数 pattern='all', # 目标机器的pattern forks=10 )datastructure = runner.run()data = json.dumps(datastructure,indent=4)from ansible import callbacksfrom ansible import utilsfrom ansible.playbook import PlayBookstats = callbacks.AggregateStats()callback = callbacks.PlaybookCallbacks()runner_callbacks = callbacks.PlaybookRunnerCallbacks(stats)pb = ansible.playbook.PlayBook( playbook="tasks.yml", stats=stats, callbacks=playbook_cb, runner_callbacks=runner_cb, check=True)pb.run()以上是1.x的ad_hoc和playbook的api调用比较简单直接但是2.x的api相当于自己编写runner方法下面就是ansible2.0的ad_hoc和playbook,并且重写了返回结果和Inventory,ansible结果返回Json对象#!/usr/local/python27/bin/python#encoding:utf8import json,sys,osfrom collections import namedtuplefrom ansible.parsing.dataloader import DataLoaderfrom ansible.vars import VariableManagerfrom ansible.inventory import Inventory,Host,Groupfrom ansible.playbook.play import Playfrom ansible.executor.task_queue_manager import TaskQueueManagerfrom ansible.plugins.callback import CallbackBasefrom ansible.executor.playbook_executor import PlaybookExecutorclass MyInventory(Inventory): def __init__(self, resource, loader, variable_manager): self.resource = resource self.inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=[]) self.dynamic_inventory() def add_dynamic_group(self, hosts, groupname, groupvars=None): my_group = Group(name=groupname) if groupvars: for key, value in groupvars.iteritems(): my_group.set_variable(key, value) 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") ssh_key = host.get("ssh_key") my_host = Host(name=hostname, port=hostport) my_host.set_variable('ansible_ssh_host', hostip) my_host.set_variable('ansible_ssh_port', hostport) my_host.set_variable('ansible_ssh_user', username) my_host.set_variable('ansible_ssh_pass', password) my_host.set_variable('ansible_ssh_private_key_file', ssh_key) for key, value in host.iteritems(): if key not in ["hostname", "port", "username", "password"]: my_host.set_variable(key, value) my_group.add_host(my_host) self.inventory.add_group(my_group) def dynamic_inventory(self): if isinstance(self.resource, list): self.add_dynamic_group(self.resource, 'default_group') elif isinstance(self.resource, dict): for groupname, hosts_and_vars in self.resource.iteritems(): self.add_dynamic_group(hosts_and_vars.get("hosts"), groupname,hosts_and_vars.get("vars")) class ModelResultsCollector(CallbackBase): def __init__(self, *args, **kwargs): super(ModelResultsCollector, 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 PlayBookResultsCollector(CallbackBase): CALLBACK_VERSION = 2.0 def __init__(self,taskList, *args, **kwargs): super(PlayBookResultsCollector, self).__init__(*args, **kwargs) self.task_ok = {} self.task_skipped = {} self.task_failed = {} self.task_status = {} self.task_unreachable = {} def v2_runner_on_ok(self, result, *args, **kwargs): if taskList.has_key(result._host.get_name()): data = {} data['task'] = str(result._task).replace("TASK: ","") taskList[result._host.get_name()].get('ok').append(data) self.task_ok[result._host.get_name()] = taskList[result._host.get_name()]['ok'] def v2_runner_on_failed(self, result, *args, **kwargs): if taskList.has_key(result._host.get_name()): data = {} data['task'] = str(result._task).replace("TASK: ","") msg = result._result.get('stderr') if msg is None: results = result._result.get('results') if result: task_item = {} for rs in results: msg = rs.get('msg') if msg: task_item[rs.get('item')] = msg data['msg'] = task_item taskList[result._host.get_name()]['failed'].append(data) else: msg = result._result.get('msg') data['msg'] = msg taskList[result._host.get_name()].get('failed').append(data) else: data['msg'] = msg taskList[result._host.get_name()].get('failed').append(data) self.task_failed[result._host.get_name()] = taskList[result._host.get_name()]['failed'] def v2_runner_on_unreachable(self, result): self.task_unreachable[result._host.get_name()] = result def v2_runner_on_skipped(self, result): if taskList.has_key(result._host.get_name()): data = {} data['task'] = str(result._task).replace("TASK: ","") taskList[result._host.get_name()].get('skipped').append(data) self.task_ok[result._host.get_name()] = taskList[result._host.get_name()]['skipped'] def v2_playbook_on_stats(self, stats): hosts = sorted(stats.processed.keys()) for h in hosts: t = stats.summarize(h) self.task_status[h] = { "ok":t['ok'], "changed" : t['changed'], "unreachable":t['unreachable'], "skipped":t['skipped'], "failed":t['failures'] }class MyRunner(object): def __init__(self,resource,*args, **kwargs): self.resource = resource self.inventory = None self.variable_manager = None self.loader = None self.options = None self.passwords = None self.callback = None self.__initializeData() self.results_raw = {} def __initializeData(self): Options = namedtuple('Options', ['connection','module_path', 'forks', 'timeout', 'remote_user', 'ask_pass', 'private_key_file', 'ssh_common_args', 'ssh_extra_args','sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'ask_value_pass', 'verbosity', check', 'listhosts', 'listtasks', 'listtags', 'syntax']) self.variable_manager = VariableManager() self.loader = DataLoader() self.options = Options(connection='smart', module_path=None, forks=100, timeout=10, remote_user='root', ask_pass=False, private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=None, become_method=None, become_user='root', ask_value_pass=False, verbosity=None, check=False, listhosts=False, listtasks=False, listtags=False, syntax=False) self.passwords = dict(sshpass=None, becomepass=None) self.inventory = MyInventory(self.resource, self.loader, self.variable_manager).inventory self.variable_manager.set_inventory(self.inventory) def run_model(self, host_list, module_name, module_args): """ run module from andible ad-hoc. module_name: ansible module_name module_args: ansible module args """ play_source = dict( name="Ansible Play", hosts=host_list, gather_facts='no', tasks=[dict(action=dict(module=module_name, args=module_args))] ) play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader) tqm = None self.callback = ModelResultsCollector() try: tqm = TaskQueueManager( inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords, ) tqm._stdout_callback = self.callback result = tqm.run(play) finally: if tqm is not None: tqm.cleanup() def run_playbook(self, host_list, playbook_path, ): """ run ansible palybook """ global taskList taskList = {} for host in host_list: taskList[host] = {} taskList[host]['ok'] = [] taskList[host]['failed'] = [] taskList[host]['skppied'] = [] try: self.callback = PlayBookResultsCollector(taskList) executor = PlaybookExecutor( playbooks=[playbook_path], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords, ) executor._tqm._stdout_callback = self.callback executor.run() except Exception as e: print e return False def get_model_result(self): self.results_raw = {'success':{}, 'failed':{}, 'unreachable':{}} for host, result in self.callback.host_ok.items(): self.results_raw['success'][host] = result._result for host, result in self.callback.host_failed.items(): self.results_raw['failed'][host] = result._result for host, result in self.callback.host_unreachable.items(): self.results_raw['unreachable'][host]= result._result return json.dumps(self.results_raw) def get_playbook_result(self): self.results_raw = {'skipped':{}, 'failed':{}, 'ok':{},"status":{},'unreachable':{}} for host, result in self.callback.task_ok.items(): self.results_raw['ok'][host] = result for host, result in self.callback.task_failed.items(): self.results_raw['failed'][host] = result for host, result in self.callback.task_status.items(): self.results_raw['status'][host] = result for host, result in self.callback.task_skipped.items(): self.results_raw['skipped'][host] = result for host, result in self.callback.task_unreachable.items(): self.results_raw['unreachable'][host] = result._result return json.dumps(self.results_raw) if __name__ == '__main__': module_resource = [ {"hostname": "192.168.222.139", "port": "22", "username": "root", "password": "123456"}, {"hostname": "192.168.222.140", "port": "22", "username": "root", "password": "123456"}, {"hostname": "192.168.222.141", "port": "22", "username": "root", "password": "123456"}, {"hostname": "192.168.222.142", "port": "22", "username": "root", "password": "123456"} ] playbook_resource = { "cluster": { #定义的动态主机名,需要跟playbook里面的hosts对应 "hosts": [ {"hostname": "192.168.222.139", "port": "22"}, {"hostname": "192.168.222.142", "port": "22"} ], } } result = MyRunner(module_resource) #resource可以是列表或者字典形式,如果做了ssh-key认证,就不会通过账户密码方式认证 result.run_model(host_list=["192.168.222.139","192.168.222.140","192.168.222.142"],module_name='ping',module_args="") data = result.get_model_result() print data print '============================================================================' result1 = MyRunner(playbook_resource) #resource可以是列表或者字典形式,如果做了ssh-key认证,就不会通过账户密码方式认证 result1.run_playbook(["192.168.222.139","192.168.222.142"],playbook_path='apiplaybook.yml') data1 = result1.get_playbook_result() print data1执行结果[root@web2 version2]# ./all.py {"failed": {}, "success": {"192.168.222.140": {"invocation": {"module_args": {"data": null}}, "_ansible_parsed": true, "changed": false, "ping": "pong", "_ansible_no_log": false}, "192.168.222.142": {"invocation": {"module_args": {"data": null}}, "_ansible_parsed": true, "changed": false, "ping": "pong", "_ansible_no_log": false}, "192.168.222.139": {"invocation": {"module_args": {"data": null}}, "_ansible_parsed": true, "changed": false, "ping": "pong", "_ansible_no_log": false}}, "unreachable": {}}======================================================================================================{"status": {"192.168.222.139": {"unreachable": 0, "skipped": 0, "changed": 1, "ok": 2, "failed": 0}, "192.168.222.142": {"unreachable": 0, "skipped": 0, "changed": 1, "ok": 2, "failed": 0}}, "failed": {}, "skipped": {}, "ok": {"192.168.222.139": [{"task": "Gathering Facts"}, {"task": "command"}], "192.168.222.142": [{"task": "Gathering Facts"}, {"task": "command"}]}, "unreachable": {}}对于用惯了1.x的api同学需要适应一下2.x的api