本文共 6100 字,大约阅读时间需要 20 分钟。
品茶:代码是基于我们的服务树结构进行构建,如果需要自己构建相应服务树则可以根据group host inventory进行自行构建。我们中带有中文,所以命令行模式需要2.0才可以调中文,1.9需要改代码。直接调模块不受影响。
ansible2.0更贴近于ansible cli的常用命令执行方式,不同于上一版本只能发送单个命令或playbook;而更推荐用户在调用ansibleAPI的时候,将playbook的每个task拆分出来,获取每个task的结果。能够跟灵活处理在执行批量作业过程中的各种反馈。
将执行操作的队列模型,包含各类环境参数设置,归结到“ansible.executor.task_queue_manager”类中
将执行过程中的各个task的设置,或者说playbook中的编排内容,归结到“ansible.playbook.play”中
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:utf8import jsonimport sysfrom ansible.runner import Runnerfrom ansible.inventory.group import Groupfrom ansible.inventory.host import Hostfrom ansible.inventory import Inventoryfrom ansible import playbookfrom ansible import callbacksfrom ansible import utilsfrom cmdb import groupsclass 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 inventoryclass 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, resultif __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)
转载于:https://blog.51cto.com/cwtea/2054174