日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

ansible调用callbacks插件实现结果nosql输出回调

發(fā)布時(shí)間:2025/3/21 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ansible调用callbacks插件实现结果nosql输出回调 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言:

????ansible的結(jié)果默認(rèn)是輸出到cli終端和日志里面的,用慣了saltsatck的returners數(shù)據(jù)回調(diào)后,也很是喜歡ansible也有,一開始不知道有這個(gè)功能,自己也簡(jiǎn)單實(shí)現(xiàn)了這樣的功能。


我的實(shí)現(xiàn)方式是,在模塊里面做一些輸出的邏輯。當(dāng)使用ansible runner api的時(shí)候,是在后面runner代碼,最后加了一段往redis輸出的邏輯。 這里實(shí)現(xiàn)數(shù)據(jù)的輸出有些獨(dú)特,但是只能是在模塊和 api方面搞 。 如果是用playbook的話,按照我以前的思路的話,再繼續(xù)改ansbile的源碼。 ?這兩天聽沈燦說(shuō),ansible有個(gè)callback_plugins的功能,可以對(duì)于執(zhí)行的狀態(tài)做一些判斷,比如,執(zhí)行成功,執(zhí)行失敗,異步執(zhí)行,異步執(zhí)行失敗,playbook開始,結(jié)束等等。?

沈燦這貨先寫了關(guān)于ansible callbacks的文章,我看到了后,才知道有而一個(gè)東西。大家可以看看 。

http://www.shencan.net/index.php/2014/07/17/ansible-%E6%8F%92%E4%BB%B6%E4%B9%8Bcallback_plugins-%EF%BC%88%E5%AE%9E%E6%88%98%EF%BC%89/?



我也不說(shuō)復(fù)雜了,就簡(jiǎn)單說(shuō)一個(gè)例子,把執(zhí)行的結(jié)果,都推到redis里面,也可以暫存到sqlite數(shù)據(jù)庫(kù)里面,只是這段代碼我給屏蔽了,有興趣的朋友再搞搞。對(duì)于redis里面的數(shù)據(jù)可以寫一個(gè)頁(yè)面展現(xiàn)下,專門記錄錯(cuò)誤的問(wèn)題,成功的就pass掉。


原文:http://rfyiamcool.blog.51cto.com/1030776/1440624?


#xiaorui.ccimport?os import?time import?sqlite3 import?redis import?jsondbname?=?'/tmp/setup.db' TIME_FORMAT='%Y-%m-%d?%H:%M:%S'try:con?=?sqlite3.connect(dbname)cur?=?con.cursor() except:passdef?log(host,?data):#????if?type(data)?==?dict: #????????invocation?=?data.pop('invocation',?None) #????????if?invocation.get('module_name',?None)?!=?'setup': #????????????return # #????facts?=?data.get('ansible_facts',?None) # #????now?=?time.strftime(TIME_FORMAT,?time.localtime()) # #????try: #????????#?`host`?is?a?unique?index #????????cur.execute("REPLACE?INTO?inventory?(now,?host,?arch,?dist,?distvers,?sys,kernel)?VALUES(?,?,?,?,?,?,?);", #????????( #????????????now, #????????????facts.get('ansible_hostname',?None), #????????????facts.get('ansible_architecture',?None), #????????????facts.get('ansible_distribution',?None), #????????????facts.get('ansible_distribution_version',?None), #????????????facts.get('ansible_system',?None), #????????????facts.get('ansible_kernel',?None) #????????)) #????????con.commit() #????except: #????????pass # class?CallbackModule(object):def?runner_on_ok(self,?host,?res):r?=?redis.Redis(host='127.0.0.1',?port=6379,?db=0)?r.set(host,str(res))f?=?open('/tmp/11','a')f.write(str(host))f.write(str(res))f.close()log(host,?res)def?runner_on_failed(self,?host,?res,?ignore_errors=False):f?=?open('/tmp/11','a')f.write('\nbad\n')f.close()log(host,?res)



還是可以接收所有的facts數(shù)據(jù)的。

原文:http://rfyiamcool.blog.51cto.com/1030776/1440624?


原文:http://rfyiamcool.blog.51cto.com/1030776/1440624?


雖然我上面的例子用了redis,sqlite數(shù)據(jù)庫(kù),其實(shí)我個(gè)人推薦用mongodb這樣的文檔數(shù)據(jù)庫(kù)的。因?yàn)閍nsible主runner函數(shù),給callbacks傳遞了一個(gè)叫res的變量,他本身就是一個(gè)dict對(duì)象,如果放到redis的hash,sqlite的各種字段,夠你煩的了,如果直接mongo,那就簡(jiǎn)單了,直接insert ! 歐了



這里在show一個(gè)郵件的callbacks代碼,場(chǎng)景是,非常消耗時(shí)間的任務(wù),當(dāng)執(zhí)行完成后,查看結(jié)果咋辦?  但是你也可以在終端繼續(xù)看,既然咱們講了callbacks_plugins,就可以把結(jié)果push到你的郵箱里面,當(dāng)然只給你發(fā)錯(cuò)誤的,有問(wèn)題的。 下面的callback代碼需要自己替換成自己用的郵箱、密碼、smtp服務(wù)器。


#xiaorui.cc 原文:http://rfyiamcool.blog.51cto.com/1030776/1440624?import?smtplibdef?mail(subject='Ansible?error?mail',?sender='<root>',?to='root',?cc=None,?bcc=None,?body=None):if?not?body:body?=?subjectsmtp?=?smtplib.SMTP('localhost')content?=?'From:?%s\n'?%?sendercontent?+=?'To:?%s\n'?%?toif?cc:content?+=?'Cc:?%s\n'?%?cccontent?+=?'Subject:?%s\n\n'?%?subjectcontent?+=?bodyaddresses?=?to.split(',')if?cc:addresses?+=?cc.split(',')if?bcc:addresses?+=?bcc.split(',')for?address?in?addresses:smtp.sendmail(sender,?address,?content)smtp.quit()class?CallbackModule(object):"""This?Ansible?callback?plugin?mails?errors?to?interested?parties."""def?runner_on_failed(self,?host,?res,?ignore_errors=False):if?ignore_errors:returnsender?=?'"Ansible:?%s"?<root>'?%?hostsubject?=?'Failed:?%(module_name)s?%(module_args)s'?%?res['invocation']body?=?'The?following?task?failed?for?host?'?+?host?+?':\n\n%(module_name)s?%(module_args)s\n\n'?%?res['invocation']if?'stdout'?in?res.keys()?and?res['stdout']:subject?=?res['stdout'].strip('\r\n').split('\n')[-1]body?+=?'with?the?following?output?in?standard?output:\n\n'?+?res['stdout']?+?'\n\n'if?'stderr'?in?res.keys()?and?res['stderr']:subject?=?res['stderr'].strip('\r\n').split('\n')[-1]body?+=?'with?the?following?output?in?standard?error:\n\n'?+?res['stderr']?+?'\n\n'if?'msg'?in?res.keys()?and?res['msg']:subject?=?res['msg'].strip('\r\n').split('\n')[0]body?+=?'with?the?following?message:\n\n'?+?res['msg']?+?'\n\n'body?+=?'A?complete?dump?of?the?error:\n\n'?+?str(res)mail(sender=sender,?subject=subject,?body=body)def?runner_on_unreachable(self,?host,?res):sender?=?'"Ansible:?%s"?<root>'?%?hostif?isinstance(res,?basestring):subject?=?'Unreachable:?%s'?%?res.strip('\r\n').split('\n')[-1]body?=?'An?error?occured?for?host?'?+?host?+?'?with?the?following?message:\n\n'?+?reselse:subject?=?'Unreachable:?%s'?%?res['msg'].strip('\r\n').split('\n')[0]body?=?'An?error?occured?for?host?'?+?host?+?'?with?the?following?message:\n\n'?+?\res['msg']?+?'\n\nA?complete?dump?of?the?error:\n\n'?+?str(res)mail(sender=sender,?subject=subject,?body=body)def?runner_on_async_failed(self,?host,?res,?jid):sender?=?'"Ansible:?%s"?<root>'?%?hostif?isinstance(res,?basestring):subject?=?'Async?failure:?%s'?%?res.strip('\r\n').split('\n')[-1]body?=?'An?error?occured?for?host?'?+?host?+?'?with?the?following?message:\n\n'?+?reselse:subject?=?'Async?failure:?%s'?%?res['msg'].strip('\r\n').split('\n')[0]body?=?'An?error?occured?for?host?'?+?host?+?'?with?the?following?message:\n\n'?+?\res['msg']?+?'\n\nA?complete?dump?of?the?error:\n\n'?+?str(res)mail(sender=sender,?subject=subject,?body=body)

如果不想發(fā)郵件,又不想搞到數(shù)據(jù)庫(kù)里面,怎么辦? 那來(lái)點(diǎn)低端的?! ≈苯訉懭氲轿募锩妗?/span>

官方給出一個(gè)例子,大家照著模板寫就行了。


import?os import?time import?jsonTIME_FORMAT="%b?%d?%Y?%H:%M:%S" MSG_FORMAT="%(now)s?-?%(category)s?-?%(data)s\n\n"if?not?os.path.exists("/var/log/ansible/hosts"):os.makedirs("/var/log/ansible/hosts")def?log(host,?category,?data):if?type(data)?==?dict:if?'verbose_override'?in?data:#?avoid?logging?extraneous?data?from?factsdata?=?'omitted'else:data?=?data.copy()invocation?=?data.pop('invocation',?None)data?=?json.dumps(data)if?invocation?is?not?None:data?=?json.dumps(invocation)?+?"?=>?%s?"?%?datapath?=?os.path.join("/var/log/ansible/hosts",?host)now?=?time.strftime(TIME_FORMAT,?time.localtime())fd?=?open(path,?"a")fd.write(MSG_FORMAT?%?dict(now=now,?category=category,?data=data))fd.close()class?CallbackModule(object):"""logs?playbook?results,?per?host,?in?/var/log/ansible/hosts"""def?on_any(self,?*args,?**kwargs):passdef?runner_on_failed(self,?host,?res,?ignore_errors=False):log(host,?'FAILED',?res)def?runner_on_ok(self,?host,?res):log(host,?'OK',?res)def?runner_on_skipped(self,?host,?item=None):log(host,?'SKIPPED',?'...')def?runner_on_unreachable(self,?host,?res):log(host,?'UNREACHABLE',?res)def?runner_on_no_hosts(self):passdef?runner_on_async_poll(self,?host,?res,?jid,?clock):passdef?runner_on_async_ok(self,?host,?res,?jid):passdef?runner_on_async_failed(self,?host,?res,?jid):log(host,?'ASYNC_FAILED',?res)def?playbook_on_start(self):passdef?playbook_on_notify(self,?host,?handler):passdef?playbook_on_no_hosts_matched(self):passdef?playbook_on_no_hosts_remaining(self):passdef?playbook_on_task_start(self,?name,?is_conditional):passdef?playbook_on_vars_prompt(self,?varname,?private=True,?prompt=None,?encrypt=None,?confirm=False,?salt_size=None,?salt=None,?default=None):passdef?playbook_on_setup(self):passdef?playbook_on_import_for_host(self,?host,?imported_file):log(host,?'IMPORTED',?imported_file)def?playbook_on_not_import_for_host(self,?host,?missing_file):log(host,?'NOTIMPORTED',?missing_file)def?playbook_on_play_start(self,?name):passdef?playbook_on_stats(self,?stats):pass

原文:?http://rfyiamcool.blog.51cto.com/1030776/1440624?


也可以把結(jié)果以webhooks鉤子的方式,做些你想做的東西。


callbacks的各種狀態(tài)還是很多的,每個(gè)函數(shù)的字眼還是很好理解的。

比如:

on_any ?哪都有他 !任何的狀態(tài)他觸發(fā)。

runner_on_failed 失敗

runner_on_ok ?成功

runner_on_unreachable 網(wǎng)絡(luò)不可達(dá)

runner_on_no_hosts 沒(méi)有主機(jī)

runner_on_async_poll 任務(wù)的異步執(zhí)行

playbook_on_start ?playbook執(zhí)行的時(shí)候

等等。。。。 ?自己嘗試吧 !


class?CallbackModule(object):def?on_any(self,?*args,?**kwargs):passdef?runner_on_failed(self,?host,?res,?ignore_errors=False):log(host,?'FAILED',?res)def?runner_on_ok(self,?host,?res):log(host,?'OK',?res)def?runner_on_skipped(self,?host,?item=None):log(host,?'SKIPPED',?'...')def?runner_on_unreachable(self,?host,?res):log(host,?'UNREACHABLE',?res)def?runner_on_no_hosts(self):passdef?runner_on_async_poll(self,?host,?res,?jid,?clock):passdef?runner_on_async_ok(self,?host,?res,?jid):passdef?runner_on_async_failed(self,?host,?res,?jid):log(host,?'ASYNC_FAILED',?res)def?playbook_on_start(self):passdef?playbook_on_notify(self,?host,?handler):passdef?playbook_on_no_hosts_matched(self):passdef?playbook_on_no_hosts_remaining(self):passdef?playbook_on_task_start(self,?name,?is_conditional):passdef?playbook_on_vars_prompt(self,?varname,?private=True,?prompt=None,?encrypt=None,?confirm=False,?salt_size=None,?salt=None,?default=None):passdef?playbook_on_setup(self):passdef?playbook_on_import_for_host(self,?host,?imported_file):log(host,?'IMPORTED',?imported_file)def?playbook_on_not_import_for_host(self,?host,?missing_file):log(host,?'NOTIMPORTED',?missing_file)def?playbook_on_play_start(self,?name):passdef?playbook_on_stats(self,?stats):pass

原文:?http://rfyiamcool.blog.51cto.com/1030776/1440624?


咱們可以簡(jiǎn)單看看ansible的callbacks源碼。

規(guī)定了兩個(gè)類,一個(gè)是供應(yīng)ansible-playbook用的,還有一個(gè)是供應(yīng)ansible,也就是cli。 根據(jù)各種的情況,調(diào)用不同的函數(shù),首先會(huì)打到終端,再log日志,最后是自定義的callbacks的插件。?




好了,就這樣了 !!!!?


總結(jié)

以上是生活随笔為你收集整理的ansible调用callbacks插件实现结果nosql输出回调的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。