系列目錄html
WebHook近些年來變得愈來愈流行,github,gitlab等代碼託管平臺都提供webhook功能.關於webhook這裏不作詳細介紹,你們能夠參閱讀相關互聯網書籍或者材料來更深瞭解.能夠把它簡單理解爲某一事件完成之後的一個回調.git
在持續集成環境裏,咱們能夠使用Sonarqube的webhook功能來實現持續發佈和發佈包歸檔功能.大體思路是當項目構建成功後咱們能夠經過webhook通知服務器構建任務已完成,接下來web 服務器能夠根據webhook傳遞的參數決定要處理的包是哪一個項目的包(經過項目的key來判斷),如何對包進行歸檔以及如何把包發佈到遠程服務器(經過http,ftp等方式).github
要想實現webhook,必須有一個預先設計好的web服務器供回調.咱們預先建好了一個web項目(新建一個mvc項目便可)web
因爲是測試,咱們這裏就用Visual的模板生成一個mvc項目,而後在Home控制器下新建一個Action,代碼以下:數據庫
public IActionResult HookTest([FromBody]SonarQubeVm sonar) { return new EmptyResult(); }
因爲Sonarqube webhook是經過post方式提交,所以action必須支持Post方式請求.服務器
參數sonar是SonarQubeVm
類型的參數,是根據Sonarqube請求規格文檔構建的,代碼以下:mvc
public class SonarQubeVm { public DateTime? AnalysedAt { get; set; } public SonarProjectInfo project { get; set; } public string ServerUrl { get; set; } public string Status { get; set; } public string TaskId { get; set; } } public class SonarProjectInfo { public string Key { get; set; } public string Name { get; set; } }
注意以上參數並不徹底包含Sonarqube返回的全部參數,咱們只取了部分.關於Sonarqube webhook完整請求參數請查看
http://localhost:9000/documentation/webhooks
,localhost:9000是默認的服務器的端口號,若是你更改了端口號或者從外網請求,則要更改成實際的ip地址(或者域名)加上指定的端口號.ide
在Sonarqube裏能夠經過兩種方式調用webhook,全局模式和項目模式.全局模式每當一個構建成功後就會觸發.項目模式則只有指定的項目構建之後纔會觸發.gitlab
如上圖示,咱們點擊全局Administration
而後點擊configuration在出現的下拉列表裏選擇WebHooks,此時右上角有一個create
按鈕,點擊後出現一個彈出框,要求輸入名稱和url,而後點擊肯定.post
咱們以調試模式啓動web項目,而後執行一個Sonarqube項目構建,執行完成後看看是否有請求到達web服務器.
MSBuild.SonarQube.Runner.exe begin /k:"mytest" /n:"mytest" /v:"v3.0" /d:sonar.cs.opencover.reportsPaths="%CD%\testcover.xml" msbuild.exe "E:\personalproject\newTest2018\ConsoleApp1\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe" -output:"%CD%\testcover.xml" -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" -targetargs:"%CD%\bin\Debug\NunitTest.dll" MSBuild.SonarQube.Runner.exe end
以上是咱們上一節講單元測試的時候執行的代碼只修改了版本號.咱們執行它.
等等以上代碼都執行完成,稍等片刻咱們就能夠看到http請求擊中斷點
經過serverurl是來自localhost:9000,咱們能夠肯定是Sonarqube發來的請求.項目的key和name都是咱們設定的mytest
以上僅是個示例程序,沒有有用代碼,實際項目中咱們能夠根據webhook請求的key來獲取到構建的是哪一個項目,而後根據預先設定的邏輯決定把它歸檔到哪裏,以及把它發佈到哪些web服務器下的哪些目錄裏(前面咱們講過經過ftt方式發佈web項目,能夠在這裏使用)
項目模式與全局模式設置徹底同樣,只是入口不一樣,項目模式須要進入項目的Administration
標籤裏進行設置.仍然以mytest項目爲例子,咱們打開mytest項目,進入到Administration標籤裏選擇webhooks便可.
設置和全局設置同樣,這裏再也不贅述.
經過以上配置,咱們成功搞好了webhook功能,然而以上代碼根本沒法使用到生產環境中,由於沒有對請求進行認證,若是任何人均可以調用構建服務器地址則後果不堪設想.咱們必須對請求進行認證,而後再決定是否執行相應邏輯.
因爲sonaqube不支持設置header,所以咱們沒法使用複雜的請求認證.只能使用基本的http認證
咱們在服務端增長如下類
public class BasicAuthenticationAttribute: ActionFilterAttribute { protected string Username { get; set; } = "sto"; protected string Password { get; set; } = "sto"; public override void OnActionExecuting(ActionExecutingContext filterContext) { var req = filterContext.HttpContext.Request; var auth = req.Headers["Authorization"].ToString(); if (!String.IsNullOrEmpty(auth)) { var cred = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':'); var user = new { Name = cred[0], Pass = cred[1] }; if (user.Name == Username && user.Pass == Password) return; } filterContext.Result = new UnauthorizedResult(); } }
以上代碼中,咱們經過硬編碼方式指定了用戶名和密碼,實際生產環境中咱們能夠經過查詢數據庫來獲取用戶名和密碼. 在OnActionExecuting
重寫方法中咱們經過頭信息Authorization
獲取加密的Base64字符串,而後經過:
分割獲取到用戶名和密碼.而後和真實用戶名密碼作對比而後決定下一步動做.
咱們把這個filter加到請求方法上.
改造後的代碼以下:
[BasicAuthentication] public IActionResult HookTest([FromBody]SonarQubeVm sonar) { return new EmptyResult(); }
咱們把webhook的url更新爲以下:
http://sto:sto1@localhost:49442/home/HookTest
實際上服務端邏輯要求帳戶和密碼都必須是sto能請求,咱們故意把密碼改成sto1看看請求是否能成功.
咱們仍然執行前面的構建代碼,只是把版本號增長一下.
咱們再進入webhook管理界面,能夠看到請求失敗了
咱們點擊失日期後面的四框
圖標,能夠看到失敗的狀態是401
咱們把請求地址更改成以下
http://sto:sto@localhost:49442/home/HookTest
這裏sto1改成服務器期待的sto,請求就能成功了.