品茶:代碼是基於咱們的服務樹結構進行構建,若是須要本身構建相應服務樹則能夠根據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)