自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

改進(jìn)你的 Ansible 劇本的 4 行代碼

運(yùn)維 系統(tǒng)運(yùn)維
在系統(tǒng)自動(dòng)化的過程中,很少有比那些通過粘合 API 創(chuàng)建的象牙塔更脆弱的塔。這是一個(gè)脆弱的世界。要讓它“工作起來”,交付它,然后繼續(xù)前進(jìn),壓力巨大。

[[377986]]

只要付出一點(diǎn)點(diǎn)努力,你就可以幫助下一個(gè)人,不只是繪制出安全路徑,還可以留下危險(xiǎn)的警告。

在博客圈里,人們對基礎(chǔ)架構(gòu)即代碼、持續(xù)集成/持續(xù)交付(CI/CD)管道、代碼審查和測試制度贊不絕口,但人們很容易忘記,這種精心設(shè)計(jì)的象牙塔只是一種理想,而不是現(xiàn)實(shí)。雖然不完美的系統(tǒng)困擾著我們,但我們必須交付一些東西。

在系統(tǒng)自動(dòng)化的過程中,很少有比那些通過粘合 API 創(chuàng)建的象牙塔更脆弱的塔。這是一個(gè)脆弱的世界。要讓它“工作起來”,交付它,然后繼續(xù)前進(jìn),壓力巨大。

要解決的問題

想象一個(gè)簡單的功能請求:編寫一些 Ansible 代碼,在外部系統(tǒng)中創(chuàng)建幾條記錄,以記錄一個(gè) VLAN 的一些詳細(xì)信息。我最近很想做一些實(shí)驗(yàn)室的管理工作來完成這個(gè)任務(wù)。這個(gè)外部系統(tǒng)是一個(gè)常見的互聯(lián)網(wǎng)協(xié)議地址管理Internet Protocol Address Management(IPAM)工具,但對于一個(gè)更抽象的配置管理數(shù)據(jù)庫Configuration Management DataBase(CMDB)或一個(gè)與網(wǎng)絡(luò)無關(guān)的記錄來說,困難是一樣的。在這個(gè)例子中,我創(chuàng)建一個(gè)記錄的直接愿望就是讓系統(tǒng)保存記錄而已。

如果我們的目標(biāo)是一個(gè)超緊湊的、直接的、笨拙的宏,那么它可能用 100 行代碼就能寫出來。如果我記得 API,我也許能在一個(gè)小時(shí)內(nèi)把它敲出來,該代碼的作用不會(huì)超過預(yù)期,除了確切的成品之外,什么也沒留下。對它的目的而言是完美的,但是對未來的擴(kuò)展毫無用處。

如今,我希望幾乎每個(gè)人都能從一個(gè)角色role和幾個(gè)任務(wù)task文件開始這項(xiàng)任務(wù),準(zhǔn)備擴(kuò)展到十幾個(gè)創(chuàng)建、讀取、更新和刪除(CRUD)操作。因?yàn)槲也涣私膺@個(gè) API,我可能會(huì)花上幾個(gè)小時(shí)到幾天的時(shí)間,僅僅是擺弄它,弄清楚它的內(nèi)部模式和工藝,彌和它的功能和我用代碼編寫出來的意圖之間的差距。

在研究 API 的時(shí)候,我發(fā)現(xiàn)創(chuàng)建一個(gè) VLAN 記錄需要一個(gè)父對象引用 vlan_view_ref。這看起來像一個(gè)路徑片段,里面有隨機(jī)字符。也許它是一個(gè)哈希,也許它真的是隨機(jī)的,我不確定。我猜想,許多在泥濘中掙扎的人,在迫在眉睫的截止日期前,可能會(huì)把這個(gè)任意的字符串復(fù)制粘貼到 Ansible 中,然后繼續(xù)混下去。忽略這個(gè)角色role的實(shí)現(xiàn)細(xì)節(jié),顯而易見這個(gè)劇本playbook級(jí)的任務(wù)應(yīng)該是這樣:

  1. - name: "Create VLAN"
  2. include_role:
  3. name: otherthing
  4. tasks_from: vlan_create.yml
  5. vars:
  6. vlan_name: "lab-infra"
  7. vlan_tag: 100
  8. vlan_view_ref: "vlan_view/747f602d-0381"

不幸的是,除了通過 API,vlan_view_ref 標(biāo)識(shí)符是不可用的,所以即使把它移到清單文件inventory或額外的變量中也沒有什么幫助。劇本playbook的用戶需要對系統(tǒng)有一些更深入的理解,才能找出正確的引用 ID。

在實(shí)驗(yàn)室建設(shè)的情況下,我會(huì)經(jīng)常重新部署這個(gè)記錄系統(tǒng)。因此,這個(gè)父對象引用 ID 每天都會(huì)發(fā)生變化,我不希望每次都要手動(dòng)找出它。所以,我肯定要按名稱搜索該引用。沒問題:

  1. - name: Get Lab vlan view reference
  2.   include_role:
  3.     name: otherthing
  4.     tasks_from: search_for.yml
  5.   vars:
  6.     _resource: vlan_view
  7.     _query: "name={{ vlan_parent_view_name }}"

最終,它進(jìn)行了一個(gè) REST 調(diào)用。這將“返回” 一個(gè) JSON,按照慣例,為了便于在角色外訪問,我把它填充進(jìn)了 _otherthing_search_result 中,。search_for.yml 的實(shí)現(xiàn)是抽象的,它總是返回一個(gè)包含零或多個(gè)結(jié)果的字典。

正如我讀過的幾乎所有真實(shí)世界的 Ansible 代碼所證明的那樣,大多數(shù) Ansible 開發(fā)者將會(huì)繼續(xù)前進(jìn),好像一切都很好,并且可以直接訪問預(yù)期的單個(gè)結(jié)果:

  1. - name: Remember our default vlan view ref
  2. set_fact:
  3. _thatthig_vlan_view_ref: "{{ _otherthing_search_result[0]._ref }}"
  4.  
  5. - name: "Create VLAN"
  6. include_role:
  7. name: otherthing
  8. tasks_from: vlan_create.yml
  9. vars:
  10. vlan_name: "lab-infra"
  11. vlan_tag: 100
  12. vlan_view_ref: "{{ vlan_parent_view_name }}"

但有時(shí) _otherthing_search_result[0] 是未定義的,所以 _thatthig_vlan_view_ref 也將是未定義的。很有可能是因?yàn)榇a運(yùn)行在不同的真實(shí)環(huán)境中,而有人忘記了在清單中或在命令行中更新 {{ vlan_parent_view_name }}?;蛘撸瑹o論公平與否,也許有人進(jìn)入了工具的圖形用戶界面(GUI),刪除了記錄或更改了它的名稱什么的。

我知道你在想什么。

“好吧,不要這樣做。這是一個(gè)沒有啞巴的場所。不要那么笨。”

也許我對這種情況還算滿意,反駁道:“Ansible 會(huì)很正確的告訴你錯(cuò)誤是:list 對象沒有元素 0,甚至?xí)€(gè)行號(hào)。你還想怎樣?”作為開發(fā)者,我當(dāng)然知道這句話的意思 —— 我剛寫的代碼。我剛從三天的和 API 斗智斗勇中走出來,我的腦子很清醒。

明天是另一個(gè)故事

但是到了明天,我可能會(huì)忘記什么是父對象引用,我肯定會(huì)忘記第 30 行上的內(nèi)容。如果一個(gè)月后出了問題,就算你能找到我,我也得花一個(gè)下午的時(shí)間重新解讀 API 指南,才能搞清楚到底出了什么問題。

而如果我出門了呢?如果我把代碼交給了一個(gè)運(yùn)維團(tuán)隊(duì),也許是一個(gè)實(shí)習(xí)生通過 Tower 來運(yùn)行,把 vlan_view_name 手動(dòng)輸入到表單之類的東西呢?那第 30 行出的問題是對他們沒有幫助的。

你說,加注釋吧! 嗯,是的。我可以在代碼中寫一些梗概,以幫助下周或下個(gè)月的開發(fā)人員。這對運(yùn)行代碼的人沒有幫助,他的“工作”剛剛失敗,當(dāng)然對于企業(yè)也無濟(jì)于事。

記住,我們此刻無所不能。在寫代碼或者跳過寫代碼的時(shí)候,我們是站在實(shí)力和知識(shí)的立場上進(jìn)行的。我們花了幾個(gè)小時(shí),甚至幾天的時(shí)間,研究了文檔、現(xiàn)實(shí)、其他 bug、其他問題,我們留下了代碼、注釋,甚至可能還有文檔。我們寫的代碼是分享成功的,而成功正是我們用戶想要的。但是在這種學(xué)習(xí)中也有很多失敗的地方,我們也可以留下這些。

在代碼中留言

“第 30 行有錯(cuò)誤”對任何人都沒有幫助。至少,我可以用更好的錯(cuò)誤信息來處理明顯的錯(cuò)誤情況:

  1.   - name: Fail if zero vlan views returned
  2.      fail:
  3.        msg: "Got 0 results from searching for VLAN view {{ vlan_parent_view_name }}. Please verify exists in otherthing, and is accessible by the service account."
  4.      when: _otherthing_search_result | length == 0

在這四行代碼中(沒有額外的思考),我把具體的、有用的建議留給了下一個(gè)人 —— 那個(gè)無助的運(yùn)維團(tuán)隊(duì)成員,或者更有可能是一個(gè)月后的我 —— 這是關(guān)于現(xiàn)實(shí)世界中的問題,其實(shí)根本不是關(guān)于代碼的。這條消息可以讓任何人發(fā)現(xiàn)一個(gè)簡單的復(fù)制/粘貼錯(cuò)誤,或者記錄系統(tǒng)發(fā)生了變化。不需要 Ansible 知識(shí),不需要凌晨 3 點(diǎn)給開發(fā)人員發(fā)短信“看看第 30 行”。

但是等等!還有更多!

在了解 otherthing 的過程中,我了解到它在一個(gè)關(guān)鍵的方面,嗯,還挺笨的。它的許多記錄類型(如果不是全部的話)沒有唯一性約束,可能存在幾個(gè)相同的記錄。VLAN 視圖被定義為有一個(gè)名稱、一個(gè)開始 ID 和一個(gè)結(jié)束 ID;其他記錄類型也同樣簡單,顯然這應(yīng)該是一個(gè)唯一的元組 —— 基于現(xiàn)實(shí)和數(shù)據(jù)庫規(guī)范化的抽象概念。但 otherthing 允許重復(fù)的元組,盡管在概念上講永遠(yuǎn)不可能。

在我的實(shí)驗(yàn)室里,我很樂意嘗試并記住不要這樣做。在企業(yè)生產(chǎn)環(huán)境中,我可能會(huì)寫一個(gè)策略。不管是哪種方式,經(jīng)驗(yàn)告訴我,系統(tǒng)會(huì)被破壞,會(huì)在倒霉的時(shí)候被破壞,而且可能需要很長時(shí)間才能讓這些問題發(fā)酵成,嗯,一個(gè)問題。

對于 “第 30 行有錯(cuò)誤”,一個(gè)本來有豐富經(jīng)驗(yàn)的 Ansible 開發(fā)者可能會(huì)認(rèn)識(shí)到這是“記錄沒有找到”,而不用知道其他的事情就足以解決這個(gè)問題。但如果 _otherthing_search_result[0] 只有有時(shí)是正確的 vlan_view_ref,那就糟糕多了,它讓整個(gè)世界被破壞,而悄無聲息。而這個(gè)錯(cuò)誤可能完全表現(xiàn)在其他地方,也許六個(gè)月后的安全審計(jì)會(huì)將其標(biāo)記為記錄保存不一致,如果有多種工具和人工訪問方式,可能需要幾天或幾周的時(shí)間才能發(fā)現(xiàn)這個(gè)特定代碼出錯(cuò)的事實(shí)。

在幾天對 API 的摸索中,我學(xué)到了這一點(diǎn)。我不是在找問題,如果有記錄,我沒有看到。所以我來到了這篇文章的重點(diǎn)。我沒有因?yàn)樗且粋€(gè)實(shí)驗(yàn)室,修復(fù)它,然后繼續(xù)前進(jìn)而忽略了這種不可能的情況,而是花了兩分鐘留下了_代碼_ —— 不是注釋,不是心理筆記,不是文檔 —— 而是會(huì)一直運(yùn)行的代碼,涵蓋了這種不可能的情況:

  1.   - name: Fail if > 1 views returned
  2.      fail:
  3.        msg: "Got {{ _otherthing_search_result | length }} results from searching for VLAN view {{ vlan_parent_view_name }}. Otherthing allows this, but is not handled by this code."
  4.      when: _otherthing_search_result | length > 1

我手動(dòng)創(chuàng)建了失敗條件,所以我可以手動(dòng)測試這個(gè)條件。我希望它永遠(yuǎn)不會(huì)在實(shí)際使用中運(yùn)行,但我覺得它會(huì)。

如果(當(dāng))這個(gè)錯(cuò)誤發(fā)生在生產(chǎn)環(huán)境中,那么有人可以決定該怎么做。我希望他們能修復(fù)壞數(shù)據(jù)。如果它經(jīng)常發(fā)生,我希望他們能追蹤到另一個(gè)損壞的系統(tǒng)。如果他們要求刪除這段代碼,而這段代碼做了未定義和錯(cuò)誤的事情,那是他們的特權(quán),也是我不想工作的地方。代碼是不完美的,但它是完整的。這是匠人的工作。

現(xiàn)實(shí)世界中的自動(dòng)化是一個(gè)迭代的過程,它與不完美的系統(tǒng)進(jìn)行斗爭,并平等地使用。它永遠(yuǎn)不會(huì)處理所有的特殊情況。它甚至可能無法處理所有的正常情況。通過 Lint、代碼審查和驗(yàn)收測試的工作代碼是處理安全和所需路徑的代碼。只要付出一點(diǎn)點(diǎn)努力,你就可以幫助下一個(gè)人,不僅僅是繪制安全路徑,還可以對你發(fā)現(xiàn)的危險(xiǎn)留下警告。 

責(zé)任編輯:龐桂玉 來源: Linux中國
相關(guān)推薦

2021-06-29 08:00:00

Ansible開發(fā)工具

2021-03-02 06:32:03

Ansible系統(tǒng)運(yùn)維

2023-06-26 08:06:39

重構(gòu)代碼冗余

2019-11-15 15:50:41

JS代碼React前端

2019-06-26 08:37:23

Python數(shù)據(jù)處理編程語言

2021-08-25 15:32:47

腳本程序參數(shù)任務(wù)

2011-05-06 09:25:56

海量代碼

2022-02-23 14:37:48

代碼Pythonbug

2010-01-08 11:04:06

ASP.NET 4SEO

2015-10-28 17:35:35

自動(dòng)化運(yùn)維Ansible配置管理

2017-03-30 08:23:50

測試前端代碼

2022-04-08 10:31:28

美團(tuán)代碼建設(shè)

2021-12-25 15:00:50

LinuxMarkdown編輯器

2024-01-10 17:24:00

2021-08-23 17:49:02

代碼開發(fā)模型

2019-06-28 12:34:34

Python情感分析NLP

2020-02-19 15:02:23

代碼開發(fā)工具

2014-03-04 09:55:26

密碼用戶體驗(yàn)

2020-02-25 11:15:46

代碼開發(fā)AI

2018-07-03 15:46:35

數(shù)據(jù)集訓(xùn)練模型
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)