Jenkins API+Pipeline深度實踐之input的自動化

目錄

  • 1律适、pipeline input 概述

  • 2腔长、背景概述

  • 3袭祟、推理及測試

  • 3.1 通過 Crumb 安全操作 Jenkins

  • 3.2 通過 Token 安全操作 Jenkins

  • 3.3 API 操作

  • 3.4 input 的改造

  • 4、自動化 input 的最終實現(xiàn)

  • 5捞附、小結(jié)

圖片

本文分享的小Tips是在我前面的文章DevOps建設(shè)之基于釘釘OA審批流的自動化上線[1]中提到的巾乳,當通過API自動觸發(fā)Jenkins Pipeline流水線執(zhí)行時,如果原來的流水線中定義了在構(gòu)建正式開始后還需要接收用戶input的步驟故俐,想要自動繞過或自動執(zhí)行input的方法

1想鹰、pipeline input 概述

首先回過頭再來看看pipeline input的語法及功能,參考我之前總結(jié)的JenkinsPipeline語法概要[2]

input指令stage允許使用input step提示輸入药版。在stage將暫停任何后options已被應用辑舷,并在進入前agent塊為stage或評估when的條件stage。如果input批準槽片,stage則將繼續(xù)何缓。作為input提交的一部分提供的任何參數(shù)將在其余的環(huán)境中可用stage

可選項

  • message 必需的还栓,這將在用戶提交時顯示給用戶input
  • id 可選標識符input碌廓,默認為stage名稱
  • okinput表單上“確定”按鈕的可選文本
  • submitter 可選的逗號分隔列表,這些列表允許用戶提交此用戶或外部組名input剩盒。默認為允許任何用戶谷婆。
  • submitterParameter 環(huán)境變量的可選名稱,用該submitter名稱設(shè)置(如果存在)
  • parameters 提示提交者提供的可選參數(shù)列表辽聊。請參閱Pipeline parameters[3]以獲取更多信息

2纪挎、背景概述

基于上面的語法描述,我這里線上發(fā)布流水線中input的功能僅僅是需要用戶進行確認跟匆,所以沒有傳遞任何參數(shù)异袄,通過這種簡單的input控制及timeout超時機制,實現(xiàn)了用戶選擇參數(shù)并點擊開始構(gòu)建后需要在 60 秒內(nèi)二次確認的功能玛臂,流水線的部分內(nèi)容如下

<pre data-tool="mdnice編輯器" style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(89, 89, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.75px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">stage('Deploy to prod'){ when { environment name: 'PerformType', value: 'Deploy' } steps{ timeout(time:60, unit:'SECONDS') { input "確認要部署到線上環(huán)境嗎烤蜕?" script{ try { ... } catch (exc) { ... throw(exc) } } } } } </pre>

到這里問題就產(chǎn)生了封孙,input的過程是在流水線運行過程中動態(tài)出現(xiàn)的,如果是想要在釘釘OA審批通過后自動通過調(diào)用jenkins api并傳入?yún)?shù)讓整個流水線自動執(zhí)行讽营,并且自動進行input的確認操作或者繞過input虎忌,應該怎么做呢?

3斑匪、推理及測試

剛開始沒有任何思路呐籽,唯一想到的辦法就是把input的過程從pipeline中去除掉,這樣就沒有任何煩惱了

但是為了保留原有pipeline設(shè)計的完整性蚀瘸,顯然這種做法不夠友好狡蝶,只是避開了這個難點,是不可取的

通過查找發(fā)現(xiàn)這方面的資料很少贮勃,最終有用的資料如下

  • input 官方說明[4]

input語法中可選字段包含id贪惹,每個input步驟都有一個唯一的ID。在生成的URL中可以使用它來繼續(xù)或中止

例如寂嘉,可以使用特定的ID來機械地響應來自某些外部過程/工具的輸入

這篇文章中講到了如何通過Jenkins REST API恢復暫停的管道奏瞬?作為參考起到了一定幫助

為了完成整個自動化input的過程,具體的演進流程如下

3.1 通過 Crumb 安全操作 Jenkins

Crumb指的是JenkinsCSRF token泉孩,Jenkins服務(wù)器為了阻止不安全的跨域請求硼端,默認開啟了CSRF保護,參考Jenkins 遠程 API 訪問[5]

Jenkins 的 CSRF 配置[6]可以在「系統(tǒng)管理」——> 「全局安全配置」——> 「CSRF Protection」相關(guān)配置中關(guān)閉此保護寓搬,跨站請求偽造這是一個很常見的安全問題珍昨,為了安全起見建議不關(guān)閉。如果關(guān)閉句喷,這里的內(nèi)容可以略過镣典。

Jenkins開啟CSRF保護后,可以通過固定的接口獲得一個安全的Crumb以便于通過API操作Jenkins唾琼,以curl請求為例兄春,請求的可選方式一般是兩種,如下

<pre data-tool="mdnice編輯器" style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(89, 89, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.75px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">`方法一:
curl -u <username>:<password> 'https://jenkins.ssgeek.com/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
Jenkins-Crumb:dc78dfb9615fb56bbf2001fb99c64dbd3331c5e14c8d4edd54722e7ca790529e%

方法二:
curl -u <username>:<password> 'https://jenkins.ssgeek.com/crumbIssuer/api/json'
{"_class":"hudson.security.csrf.DefaultCrumbIssuer","crumb":"52d605f43328f15303c2e68eb492b9656e229ce124c2f5f2e39b6f552f54e4ac","crumbRequestField":"Jenkins-Crumb"}%` </pre>

以上兩種方式都可以獲取一個Crumb锡溯,然后就能帶著它去請求JenkinsAPI

<pre data-tool="mdnice編輯器" style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(89, 89, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.75px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">curl -u <username>:<password> -X POST -H "Jenkins-Crumb:b220147dbdf3cfebbeba4c29048c2e33" -d <data> 'https://jenkins.ssgeek.com/<jenkins api url>' </pre>

3.2 通過 Token 安全操作 Jenkins

在官方文檔的描述中有這樣一句話:API tokens are preferred instead of crumbs for CSRF protection.

意為在開啟了CSRF的情況下赶舆,首選的是通過API token操作而不是crumb,這里的API token指的就是Jenkins中用戶的API token

可以通過「用戶」——> 「設(shè)置」——> 「API Token」——> 「添加新 Token」來獲得一個api token祭饭,有了這個Token之后涌乳,以curl請求為例操作JenkinsAPI方式如下

<pre data-tool="mdnice編輯器" style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(89, 89, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.75px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">curl -u user_id:user_api_token -X POST -d <data> 'https://jenkins.ssgeek.com/<jenkins api url>' </pre>

3.3 API 操作

參考上面的文檔資料使用 Jenkins REST API 恢復暫停的管道[7]

對于input有這樣的api接口地址可以使用,用于將輸入發(fā)送到等待的輸入步驟甜癞。url格式如下

<pre data-tool="mdnice編輯器" style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(89, 89, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.75px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">http://<JenkinsURL>/<JobURL>/<Build#>/input/<InputID>/submit </pre>

需要滿足的條件

  • 如果Jenkins啟用了CSRF保護,則您需要使用CrumbAPI Token

  • 請求通過POST方式發(fā)送

  • 需要提供參數(shù)名為proceed的值宛乃,并且以OK作為參數(shù)值

  • 為了提供數(shù)據(jù)悠咱,需要帶有json格式的參數(shù)蒸辆,這些參數(shù)就是在input階段需要接收的參數(shù),格式為

    <pre style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">{ "parameter":[ { "name":"param1", "value":"valueOfParam1" }, { "name":"param2", "value":"valueOfParam2" } ] } </pre>

    如果沒有發(fā)送有效的json參數(shù)析既,則流水線也將繼續(xù)進行躬贡,只是不會獲得任何參數(shù)(這也可能導致流水線最終執(zhí)行失敗)眼坏,如果成功則返回302狀態(tài)碼并重定向到用戶界面

  • 必須填寫input id拂玻,因此要從外部連接到的input步驟配置唯一的id

  • 也可以使用下面的 url,如果流水線成功宰译,則返回狀態(tài)碼為200且響應為空

    <pre style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">http://<Jenkins URL>/job/<YOUR_PROJECT>/<BUILD_NUMBER>/wfapi/inputSubmit </pre>

其他可用的api接口地址以及作用

  • 用于中止流水線

<pre data-tool="mdnice編輯器" style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(89, 89, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.75px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">http://<Jenkins URL>/job/<YOUR_PROJECT>/<BUILD_NUMBER>/input/<INPUT_ID>/abort </pre>

  • 不傳入任何參數(shù)并繼續(xù)進行流水線

<pre data-tool="mdnice編輯器" style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(89, 89, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.75px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">http://<Jenkins URL>/job/<YOUR_PROJECT>/<BUILD_NUMBER>/input/<INPUT_ID>/proceedEmpty </pre>

對于本文中我的需求檐蚜,只需要在input執(zhí)行時自動確認且無需傳入任何參數(shù)即可,因此使用的接口地址為上面的最后一種(其余接口地址未測試)

3.4 input 的改造

為了實現(xiàn)在input執(zhí)行時自動確認沿侈,需要對流水線的input部分進行改造闯第,加入一個固定的id即可

由于定義的id都是固定的,因此可以利用腳本對所有的流水線涉及到這種input的部分批量更新缀拭,這里就不列出具體方法了

最終我的流水線調(diào)整如下

<pre data-tool="mdnice編輯器" style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(89, 89, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.75px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">stage('Deploy to prod'){ when { beforeInput true environment name: 'PerformType', value: 'Deploy' } options { timeout(time:60, unit:'SECONDS') } input { message "確認要部署到線上環(huán)境嗎咳短?" id "CustomId" } steps{ script{ try { ... } catch (exc) { ... throw(exc) } } } } </pre>

4、自動化 input 的最終實現(xiàn)

經(jīng)過上面的推理和測試蛛淋,解決了通過API自動執(zhí)行input進行流水線確認的問題

這里還剩下最后一個問題咙好,通過測試發(fā)現(xiàn),想要自動執(zhí)行input過程褐荷,其接口對應的url地址并不是一直存在的勾效,而是在流水線執(zhí)行開始后到達input的時候才會出現(xiàn),出現(xiàn)時通過瀏覽器訪問查看如下

圖片

而其余時間發(fā)送請求都會返回404狀態(tài)碼诚卸,此時是無法接收post請求的葵第,因此想要自動化執(zhí)行input并不只是簡單的向接口發(fā)送POST請求了

我這里的解決思路

在發(fā)送流水線開始執(zhí)行的請求后,立即通過代碼循環(huán)請求并判斷接口地址返回的狀態(tài)碼是否是200

如果不是合溺,那么表示流水線還沒執(zhí)行到這里卒密;如果是,就可以完美的向這個地址發(fā)送自動執(zhí)行的請求了

python語言調(diào)用Jenkins api為例棠赛,用到了python-jenkins這個包哮奇,在觸發(fā)構(gòu)建時使用build_job這個方法,這個方法返回值剛好是job任務(wù)的build number睛约,這恰好是接口地址組成中需要的一部分

好了鼎俘,上最終的部分代碼

<pre data-tool="mdnice編輯器" style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(89, 89, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.75px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">def auto_job_input(self, server_url, job_name, build_number): """ 根據(jù)input階段生成的url http狀態(tài)碼,判斷當前job流水線運行的stage否進行到了input步驟 自動執(zhí)行input or 繼續(xù)判斷 :param job_name: :param build_number: :return: """ # https://jenkins.ssgeek.com/job/input-demo/64/input get_url = server_url + "/job/" + job_name + "/" + str(build_number) + "/input" # https://jenkins.ssgeek.com/job/input-demo/64/input/CustomId/proceedEmpty post_url = get_url + "/CustomId/proceedEmpty" s = requests.Session() res_code_get = s.get(url=get_url, auth=('user_id', 'user_token')).status_code while res_code_get != 200: res_code_get = s.get(url=get_url, auth=('user_id', 'user_token')).status_code res_code_post = s.post(url=post_url, auth=('user_id', 'user_token'), data=None).status_code return res_code_post </pre>

關(guān)鍵部分代碼量很少辩涝,利用request并且攜帶認證參數(shù)進行請求贸伐,如果有大佬有更好的方案歡迎與我交流

5、小結(jié)

到這里怔揩,通過一步步推理演進捉邢,在流水線中input的自動化執(zhí)行就完美實現(xiàn)了脯丝,最終既實現(xiàn)了調(diào)用api觸發(fā)自動構(gòu)建并執(zhí)行input進行自動確認,同時也保留了原流水線的input設(shè)計伏伐,對原有流水線只需要做很小的調(diào)整宠进。

參考資料

[1]

DevOps建設(shè)之基于釘釘OA審批流的自動化上線: https://www.ssgeek.com/post/devops-jian-she-zhi-ji-yu-ding-ding-oa-shen-pi-liu-de-zi-dong-hua-shang-xian/ [2]

JenkinsPipeline語法概要: https://www.ssgeek.com/post/jenkinspipeline-yu-fa-gai-yao/#310-input [3]

Pipeline parameters: https://www.jenkins.io/doc/book/pipeline/syntax/#parameters [4]

input官方說明: https://www.jenkins.io/doc/pipeline/steps/pipeline-input-step/ [5]

Jenkins遠程API訪問: https://www.jenkins.io/doc/book/using/remote-access-api/ [6]

Jenkins的CSRF配置: https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery [7]

使用Jenkins REST API恢復暫停的管道: https://www.thinbug.com/q/48799442

本文摘選 地址————————————點擊傳送

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市藐翎,隨后出現(xiàn)的幾起案子材蹬,更是在濱河造成了極大的恐慌,老刑警劉巖吝镣,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堤器,死亡現(xiàn)場離奇詭異,居然都是意外死亡赤惊,警方通過查閱死者的電腦和手機吼旧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來未舟,“玉大人圈暗,你說我怎么就攤上這事≡0颍” “怎么了员串?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長昼扛。 經(jīng)常有香客問我寸齐,道長,這世上最難降的妖魔是什么抄谐? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任渺鹦,我火速辦了婚禮,結(jié)果婚禮上蛹含,老公的妹妹穿的比我還像新娘毅厚。我一直安慰自己,他們只是感情好浦箱,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布吸耿。 她就那樣靜靜地躺著,像睡著了一般酷窥。 火紅的嫁衣襯著肌膚如雪咽安。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天蓬推,我揣著相機與錄音妆棒,去河邊找鬼。 笑死,一個胖子當著我的面吹牛糕珊,可吹牛的內(nèi)容都是我干的蛋铆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼放接,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了留特?” 一聲冷哼從身側(cè)響起纠脾,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜕青,沒想到半個月后苟蹈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡右核,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年慧脱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贺喝。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡菱鸥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出躏鱼,到底是詐尸還是另有隱情氮采,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布染苛,位于F島的核電站鹊漠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茶行。R本人自食惡果不足惜躯概,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望畔师。 院中可真熱鬧娶靡,春花似錦、人聲如沸茉唉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽度陆。三九已至艾凯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間懂傀,已是汗流浹背趾诗。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恃泪。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓郑兴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贝乎。 傳聞我的和親對象是個殘疾皇子情连,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容