背景: 看到Harbor有Webhook功能,想用起來,當產品組有新的容器鏡像發布時,就自動觸發部署到環境中。
Harbor部分
Webhook的POST請求JSON樣例:
{
"type": "pushImage",
"occur_at": 1591172171,
"event_data": {
"resources": [{
"digest": "sha256:8896bb6b310b53ff03c2172db6b2fa7841233d0de516021e9a4912bdef11aed3",
"tag": "20200603",
"resource_url": "test-docker.jchl.com/sbpt/icap-gateway-main:20200603"
}],
"repository": {
"date_created": 1588750292,
"name": "icap-gateway-main",
"namespace": "sbpt",
"repo_full_name": "sbpt/icap-gateway-main",
"repo_type": "public"
}
},
"operator": "sbpt"
}
基礎知識: JSONPath的語法,需要從json中獲取所需要的值
JSONPath項目地址:https://github.com/json-path/JsonPath
JSONPath驗證地址: https://jsonpath.curiousconcept.com/
Webhook endpoint: http://<user>:<password>@<JenkinsIP>:<JenkinsPort>/generic-webhook-trigger/invoke
Jenkins部分
安裝插件:Generic Webhook Trigger Plugin

解釋:使用JSONPath表達式$.type獲取POST的JSON值內容,然后賦值給harbor_type,Jenkins可以通過$harbor_type使用該值。


同理,其他值的獲取配置如下:
Variable: harbor_image
Expression: $.event_data.resources[0].resource_url
Variable: harbor_namespace
Expression: $.event_data.repository.namespace
Variable: repo_name
Expression: $.event_data.repository.name
Optional filter

Expression: pushImage#sbpt#icap-gateway-main
Text: $harbor_type#$harbor_namespace#$repo_name
解釋:這里是Job觸發的過濾器,根據上面的取值,拼接為Text,然后根據正則表達式檢查匹配情況,匹配成功則觸發Job否則忽略。
這里的例子是說同時滿足 pushImage事件#sbpt項目#icap-gateway-main倉庫名稱 時就觸發Job。
效果:
Jenkins構建環節配置執行Shell:
echo harbor_type=$harbor_type
echo harbor_image=$harbor_image
echo repo_name=$repo_name
echo harbor_namespace=$harbor_namespace
echo "do something..."
kubectl set image deployment.apps/$repo_name $repo_name=$harbor_image

PS: 我並不知道Harbor的Webhook樣例,然而又翻不動Harbor的代碼,還寫了server配上去用來打印POST過來的內容,其實后來才發現Jenkins可以勾選“Print post content”。希望本文能節省你的時間,對你有用:)
