.net持續集成sonarqube篇之 sonarqube觸發webhook

系列目錄html

WebHook近些年來變得愈來愈流行,github,gitlab等代碼託管平臺都提供webhook功能.關於webhook這裏不作詳細介紹,你們能夠參閱讀相關互聯網書籍或者材料來更深瞭解.能夠把它簡單理解爲某一事件完成之後的一個回調.git

在持續集成環境裏,咱們能夠使用Sonarqube的webhook功能來實現持續發佈和發佈包歸檔功能.大體思路是當項目構建成功後咱們能夠經過webhook通知服務器構建任務已完成,接下來web 服務器能夠根據webhook傳遞的參數決定要處理的包是哪一個項目的包(經過項目的key來判斷),如何對包進行歸檔以及如何把包發佈到遠程服務器(經過http,ftp等方式).github

Web服務器搭建

要想實現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

WebHook調用

在Sonarqube裏能夠經過兩種方式調用webhook,全局模式和項目模式.全局模式每當一個構建成功後就會觸發.項目模式則只有指定的項目構建之後纔會觸發.gitlab

全局模式

avatar

如上圖示,咱們點擊全局Administration而後點擊configuration在出現的下拉列表裏選擇WebHooks,此時右上角有一個create按鈕,點擊後出現一個彈出框,要求輸入名稱和url,而後點擊肯定.post

avatar

咱們以調試模式啓動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請求擊中斷點

avatar

經過serverurl是來自localhost:9000,咱們能夠肯定是Sonarqube發來的請求.項目的key和name都是咱們設定的mytest

以上僅是個示例程序,沒有有用代碼,實際項目中咱們能夠根據webhook請求的key來獲取到構建的是哪一個項目,而後根據預先設定的邏輯決定把它歸檔到哪裏,以及把它發佈到哪些web服務器下的哪些目錄裏(前面咱們講過經過ftt方式發佈web項目,能夠在這裏使用)

項目模式

項目模式與全局模式設置徹底同樣,只是入口不一樣,項目模式須要進入項目的Administration標籤裏進行設置.仍然以mytest項目爲例子,咱們打開mytest項目,進入到Administration標籤裏選擇webhooks便可.

avatar

設置和全局設置同樣,這裏再也不贅述.

請求認證

經過以上配置,咱們成功搞好了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管理界面,能夠看到請求失敗了

avatar

咱們點擊失日期後面的四框圖標,能夠看到失敗的狀態是401

avatar

咱們把請求地址更改成以下

http://sto:sto@localhost:49442/home/HookTest

這裏sto1改成服務器期待的sto,請求就能成功了.

相關文章
相關標籤/搜索