日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

【Ansible】的python api

發布時間:2025/4/5 python 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Ansible】的python api 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【Ansible API】

  Ansible本身就是由python寫成,所有其對python形式的API的支持應該不錯。

  其API分不同的版本,這個版本也就是ansible本身的版本,可以通過ansible --version命令查看或者在python中import ansible然后查看anisble.__version__。

  在2.0的版本以前,ansible的API十分簡單。通過大概十幾行代碼就可以模擬通過ad-hoc的方式運行annsible命令的。

  但是在2.0及以后的版本,難度突然陡增,與此同時更多的更加底層的東西被開放給一般開發,雖然復雜了,但是也更加靈活了。

  對于一些簡單的需求,可能我們還是喜歡老版API,因此這里有個網上別人封裝好的2.0版本API簡化文件,通過這里的代碼我們可以依然簡單地運行ansible的ad-hoc。同時,它的源碼支持修改,從而達到更個性化的改造。

  *** 需要注意,下面這個代碼只在2.0開頭的幾個版本中適用。至少到2.4.0之后,API又有了一些改動,下面的代碼運行會出錯。我懶得再研究2.4了,就干脆pip install ansible==2.0來配合這個庫

  ansible_api.py:

# -*- coding:utf-8 -*-import os import sys from collections import namedtuple from ansible.parsing.dataloader import DataLoader from ansible.vars import VariableManager from ansible.inventory import Inventory from ansible.inventory.group import Group from ansible.inventory.host import Host from ansible.playbook.play import Play from ansible.executor.task_queue_manager import TaskQueueManager from ansible.executor.playbook_executor import PlaybookExecutor from ansible.plugins.callback import CallbackBaseclass ResultsCollector(CallbackBase):def __init__(self, *args, **kwargs):super(ResultsCollector, 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()] = resultdef v2_runner_on_ok(self, result, *args, **kwargs):self.host_ok[result._host.get_name()] = resultdef v2_runner_on_failed(self, result, *args, **kwargs):self.host_failed[result._host.get_name()] = resultclass MyInventory(Inventory):""" this is my ansible inventory object. """def __init__(self, resource, loader, variable_manager):""" resource的數據格式是一個列表字典,比如 { "group1": { "hosts": [{"hostname": "10.0.0.0", "port": "22", "username": "test", "password": "pass"}, ...], "vars": {"var1": value1, "var2": value2, ...} } } 如果你只傳入1個列表,這默認該列表內的所有主機屬于my_group組,比如 [{"hostname": "10.0.0.0", "port": "22", "username": "test", "password": "pass"}, ...] """self.resource = resourceself.inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=[])self.gen_inventory()def my_add_group(self, hosts, groupname, groupvars=None):""" add hosts to a group """my_group = Group(name=groupname)# if group variables exists, add them to groupif groupvars:for key, value in groupvars.iteritems():my_group.set_variable(key, value)# add hosts to groupfor host in hosts:# set connection variableshostname = 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)# set other variablesfor key, value in host.iteritems():if key not in ["hostname", "port", "username", "password"]:my_host.set_variable(key, value)# add to group my_group.add_host(my_host)self.inventory.add_group(my_group)def gen_inventory(self):""" add hosts to inventory. """if isinstance(self.resource, list):self.my_add_group(self.resource, 'default_group')elif isinstance(self.resource, dict):for groupname, hosts_and_vars in self.resource.iteritems():self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))class AnsibleAPI(object):""" This is a General object for parallel execute modules. """def __init__(self, resource, *args, **kwargs):self.resource = resourceself.inventory = Noneself.variable_manager = Noneself.loader = Noneself.options = Noneself.passwords = Noneself.callback = Noneself.__initializeData()self.results_raw = {}def __initializeData(self):""" 初始化ansible """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'])# initialize needed objectsself.variable_manager = VariableManager()self.loader = DataLoader()self.options = Options(connection='smart', module_path='/usr/share/ansible', 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).inventoryself.variable_manager.set_inventory(self.inventory)def run(self, host_list, module_name, module_args):""" run module from andible ad-hoc. module_name: ansible module_name module_args: ansible module args """# create play with tasksplay_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)# actually run ittqm = Noneself.callback = ResultsCollector()try:tqm = TaskQueueManager(inventory=self.inventory,variable_manager=self.variable_manager,loader=self.loader,options=self.options,passwords=self.passwords,)tqm._stdout_callback = self.callbacktqm.run(play)finally:if tqm is not None:tqm.cleanup()def run_playbook(self, host_list, role_name, role_uuid, temp_param):""" run ansible palybook """try:self.callback = ResultsCollector()filenames = ['' + '/handlers/ansible/v1_0/sudoers.yml'] # playbook的路徑template_file = '' # 模板文件的路徑if not os.path.exists(template_file):sys.exit()extra_vars = {} # 額外的參數 sudoers.yml以及模板中的參數,它對應ansible-playbook test.yml --extra-vars "host='aa' name='cc' "host_list_str = ','.join([item for item in host_list])extra_vars['host_list'] = host_list_strextra_vars['username'] = role_nameextra_vars['template_dir'] = template_fileextra_vars['command_list'] = temp_param.get('cmdList')extra_vars['role_uuid'] = 'role-%s' % role_uuidself.variable_manager.extra_vars = extra_vars# actually run itexecutor = PlaybookExecutor(playbooks=filenames, inventory=self.inventory, variable_manager=self.variable_manager,loader=self.loader,options=self.options, passwords=self.passwords,)executor._tqm._stdout_callback = self.callbackexecutor.run()except Exception as e:print "error:",e.messagedef get_result(self):self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}for host, result in self.callback.host_ok.items():self.results_raw['success'][host] = result._resultfor host, result in self.callback.host_failed.items():self.results_raw['failed'][host] = result._result.get('msg') or result._resultfor host, result in self.callback.host_unreachable.items():self.results_raw['unreachable'][host] = result._result['msg']return self.results_raw

?

  簡單的用法是這樣的:

# -*- coding:utf-8 -*-from ansible_api import AnsibleAPIresource = [{'hostname':'localtest','ip','192.168.178.59','username':'root','password':'xxx'},{'hostname':'localtest2','ip':'192.168.178.141','username':'root','password':'yyy'} #有個小坑,hostname中不能有空格,否則這個host會被ansible無視 ]api = AnsibleAPI(resource)# 開始模擬以ad-hoc方式運行ansible命令 api.run(['localtest','localtest2'], # 指出本次運行涉及的主機,在resource中定義'command', # 本次運行使用的模塊'hostname' # 模塊的參數 )# 獲取結果,是一個字典格式,如果是print可以用json模塊美化一下 import json print json.dumps(api.get_result(),indent=4)

?

  從邏輯上看,首先我們聲明了一個resource,在這是一個list結構,其中包含了各個被操作主機的信息。hostname,ip,username,password這些是作為ansible連接所用的最基本的幾個參數,此外port也可指定。resource被api類加載,這個過程其實就是生成了一個動態的inventory。從源碼中的90多行可以看出,當傳入一個list時api默認將其中所有host信息都放入一個default_group的inventory組,當傳入一個dict就默認這個dict的各個鍵值對分別是組名和組中host信息。

  run方法是真正的執行方法,其參數從前往后三個分別是host_list, module, module_args。command的話args比較簡單。像類似于copy這類模塊的參數可以這么寫:

  api.run(['test'],'copy','src="/tmp/testfille" dest="/tmp/newfile"')

  而file就可以這樣:

  api.run(['test'],'path="/tmp/test.py" mode=0755 owner="tmpuser"')

  通過這兩個例子基本就可以看清楚如何向run方法傳遞ansible模塊的參數了。

  api在執行run方法之后并不會主動輸出結果,需要我們手動地get_result()。result在空的情況下是這樣一個結構:

{"success": {},"failed": {},"unreachable":{} }

?

  不難看出,從主機層面上,主機們被分成了執行成功,執行失敗,和連接不到三類,分別給出結果。

  下面給出一個返回結果的示例

{"failed": {"node-one": {"cmd": ["cat", "/tmp/test"], "end": "2018-05-08 16:27:29.327685", "_ansible_no_log": false, "stdout": "", "changed": true, "failed": true, "delta": "0:00:00.003369", "stderr": "cat: /tmp/test: \u6ca1\u6709\u90a3\u4e2a\u6587\u4ef6\u6216\u76ee\u5f55", "rc": 1, "invocation": {"module_name": "command", "module_args": {"creates": null, "executable": null, "chdir": null, "_raw_params": "cat /tmp/test", "removes": null, "warn": true, "_uses_shell": false}}, "stdout_lines": [], "start": "2018-05-08 16:27:29.324316", "warnings": []}}, "success": {"localtest": {"cmd": ["cat", "/tmp/test"], "end": "2018-05-08 16:27:30.692616", "_ansible_no_log": false, "stdout": "", "changed": true, "start": "2018-05-08 16:27:30.689329", "delta": "0:00:00.003287", "stderr": "", "rc": 0, "invocation": {"module_name": "command", "module_args": {"creates": null, "executable": null, "chdir": null, "_raw_params": "cat /tmp/test", "removes": null, "warn": true, "_uses_shell": false}}, "stdout_lines": [], "warnings": []}}, "unreachable": {"node-two": "ERROR! SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue"} } View Code

?

  localtest執行成功,返回中有changed,delta,start/end,stdout等可能要在后續處理中用到的各種數據

  node-one執行失敗,所以可以讀取stderr中的內容。由于返回是中文,在這里以unicode的形式展現

  node-two無法連接,只給出了簡單的無法連接的提示信息

?

  基本使用就說到這里吧。下面我要使用了,過程中可能會要回過頭來改源碼。

總結

以上是生活随笔為你收集整理的【Ansible】的python api的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 任我爽在线 | 免费看黄色三级三级 | 欧美精品videos | 亚洲精品久久久久久国产精华液 | 麻豆成人精品国产免费 | 精品人人妻人人澡人人爽牛牛 | 日韩免费电影一区 | 男男做性免费视频网 | 国产微拍一区 | 成人女同av免费观看 | 男女视频在线观看免费 | 美日韩一区二区三区 | 9191在线视频 | www国产91 | 成人激情五月天 | 欧美日韩在线第一页 | 99中文字幕 | 99久久婷婷国产综合精品青牛牛 | 自拍偷拍视频网站 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 中日韩精品在线 | 欧美日韩加勒比 | 亚洲av成人精品毛片 | 国产中文欧美日韩在线 | 日本免费不卡视频 | 国产乱码一区二区三区播放 | 成人免费视频国产免费 | 久久高清国产 | 波多野结衣高清视频 | 在线观看三区 | 国产精品一区二区6 | 影音先锋制服丝袜 | 激情国产一区 | 三级黄色网络 | 欧美性色a | 人妻熟人中文字幕一区二区 | 欧美wwwxxxx| 日韩三级在线播放 | 美国免费高清电影在线观看 | 少妇精品无码一区二区三区 | 美女黄页网站 | 亚洲av首页在线 | 国产伦精品一区二区三区视频女 | 影音先锋中文字幕一区二区 | 日在线视频 | 成人美女免费网站视频 | 国产精品成人国产乱一区 | 国外成人性视频免费 | 国产丰满农村老妇女乱 | 884aa四虎影成人精品一区 | 国产视频综合 | 欧美日韩国产一级片 | 麻豆激情视频 | 日本黄图 | 国产午夜电影在线观看 | 亚洲视频播放 | 免费网站黄色 | 无码精品一区二区三区AV | 99久久成人| 久久久久性色av无码一区二区 | 黄色高清免费 | 成人理论影院 | 欧美久草视频 | 亚洲第二页| 日本三级免费 | 日韩区在线观看 | 性欧美18 | 欧美第二区| 午夜精品久久久久久久久久蜜桃 | 久久成人a| 日韩激情小视频 | 亚洲精品乱码久久久久久国产主播 | av天天干 | 日韩精品播放 | 91黄视频在线观看 | 青青色在线观看 | 成年人在线播放视频 | 国产在线观看免费 | 永久免费国产 | 天天色天天操天天射 | 色婷婷婷| 韩国精品av | 午夜黄色剧场 | 欧美国产不卡 | 波多野一区二区三区 | 亚洲成人网在线播放 | 中文字幕久热 | 日本人三级 | 99精品久久99久久久久 | 日本亚洲一区二区三区 | 青青草国产在线 | 五月天开心网 | 日本精品中文字幕 | 亚洲综合五月天 | 亚洲一二三不卡 | 动漫av在线免费观看 | 久久久久人妻一区精品色 | 久久久国产精品久久久 | 日本激情在线 |