品茶:代码是基于咱们的服务树结构进行构建,若是须要本身构建相应服务树则能够根据group host inventory进行自行构建。咱们中带有中文,因此命令行模式须要2.0才能够调中文,1.9须要改代码。直接调模块不受影响。
json
ansible2.0更贴近于ansible cli的经常使用命令执行方式,不一样于上一版本只能发送单个命令或playbook;而更推荐用户在调用ansibleAPI的时候,将playbook的每一个task拆分出来,获取每一个task的结果。可以跟灵活处理在执行批量做业过程当中的各类反馈。ssh
将执行操做的队列模型,包含各种环境参数设置,归结到“ansible.executor.task_queue_manager”类中
将执行过程当中的各个task的设置,或者说playbook中的编排内容,归结到“ansible.playbook.play”中ide
from collections import namedtuple #有命元组 from ansible.parsing.dataloader import DataLoader #数据解析 from ansible.vars import VariableManager # 变量管旦 from ansible.inventory import Inventory # 主机配置信息 from ansible.playbook.play import Play # 剧本 from ansible.executor.task_queue_manager import TaskQueueManager # 任务消息队列 from ansible.plugins.callback import CallbackBase #回调
# #coding:utf8 import json import sys from ansible.runner import Runner from ansible.inventory.group import Group from ansible.inventory.host import Host from ansible.inventory import Inventory from ansible import playbook from ansible import callbacks from ansible import utils from cmdb import groups class CmdbInventory(object): ''' Get ansible.inventory for cmdb parse tree ''' def __init__(self): self.cmdbs = groups() self.inventory = self.init_inventory() def init_inventory(self, inventory=Inventory(host_list=[])): ''' :param inventory: default param, init cmdb Tree info. :return: ansible.inventory type ''' for name in self.cmdbs: if name == "_meta": # 主机变量,暂不处理 pass g = Group(name=name) # 设置组环境变量 if self.cmdbs[name].get("vars", None): vars = self.cmdbs[name]["vars"] for k,v in vars.iteritems(): g.set_variable(k, v) # 添加主机进主机组 if self.cmdbs[name].get("hosts", None): hosts = self.cmdbs[name]["hosts"] for host in hosts: h = Host(name=host) g.add_host(h) inventory.add_group(g) # 处理子组 for name in self.cmdbs: if self.cmdbs[name].get("children", None): children = self.cmdbs[name]["children"] for child in children: g = inventory.get_group(name) child = inventory.get_group(child) g.add_child_group(child) # 处理主机的环境变量 hostvars = self.cmdbs.get("_meta",{}).get("hostvars", {}) if hostvars: for host in hostvars: inve_host = inventory.get_host(host) for k, v in hostvars[host].iteritems(): inve_host.set_variable(k, v) return inventory class Ansible(object): def __init__(self, transport="paramiko", module_name="ping", module_args="", pattern="", remote_user="", remote_pass="", play_book=False, yml_path=""): ''' Run a ansible task :param transport: paramiko, ssh, smart :param module_name: ansible module name :param module_args: ansible module args :param pattern: ansible pattern :param remote_user: transport user :param remote_pass: transport password :return: ansible task result ''' if not remote_user or not remote_pass: raise ValueError("Ansible class need params remote_user, remote_pass") if play_book: if not yml_path: raise ValueError("playbook need params yml_path") else: if not module_name or not pattern: raise ValueError("Ad-hoc need params module_name, pattern") if transport not in ("paramiko", "ssh", "smart"): raise ValueError("params transport not in paramiko, ssh, smart.") self.transport = transport self.module_name = module_name self.module_args = module_args self.pattern = pattern.decode("utf-8") # 这是由于中文问题 self.remote_user = remote_user self.remote_pass = remote_pass self.play_book = play_book self.yml_path = yml_path # A 经过解析方式(这是一种单独的方式) # ci = CmdbInventory() # inventory = ci.inventory # B 经过脚本方式(这是一种全量的方式,可经过修改文件名) self.inventory = Inventory(host_list="cmdb.py") def task(self): '''Ansible Ad-Hoc''' try: runner = Runner( transport=self.transport, module_name=self.module_name, module_args=self.module_args, pattern=self.pattern, forks=10, inventory=self.inventory, remote_user=self.remote_user, remote_pass=self.remote_pass ) result = runner.run() return True, result except Exception as e: return False, str(e) def playbook(self): stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats=stats, verbose=utils.VERBOSITY) # B 经过脚本方式(这是一种全量的方式,可经过修改文件名) inventory = Inventory(host_list="cmdb.py") pb = playbook.PlayBook( inventory=self.inventory, playbook=self.yml_path, stats=stats, callbacks=playbook_cb, runner_callbacks=runner_cb, check=True, transport=self.transport, remote_user=self.remote_user, remote_pass=self.remote_pass ) result = pb.run() return True, result if __name__ == "__main__": ansible = Ansible(remote_user="", remote_pass="", play_book=True, yml_path="playbooks/ping.yml") # result = ansible.task() result = ansible.playbook() print json.dumps(result, indent=4)