美文网首页
基于Sonarqube Api---Jenkins集成发布质量控

基于Sonarqube Api---Jenkins集成发布质量控

作者: IT软件技术分享 | 来源:发表于2020-09-27 20:15 被阅读0次

    1.Sonarqube Api介绍

    sonarqube开放了很多api接口,用户及权限,项目及扫描结果,还有相关系统及配置等api。

    api清单可以在sonar平台直接查看,默认地址为:http://localhost:9000/web_api/,localhost:9000是sonar的访问路径需要替换成你的地址,笔者的是绑定了域名的sonar.xxx.cn

    SonarqubeApi页面

    2.获取扫描结果并与Jenkins集成控制发布质量

    上文我们通过Jenkins实现了自动化扫描,但我们并没有对扫描结果进行获取或处理,这样导致整个扫描在整体发布流程中变成一个可有可无的弱势环节。

    接下来我们将提升扫描环节的重要度,通过对其结果获取控制发布流程,思路发下:

    1.通过api获取我们所需要采集的扫描指标值(每公司或团队关注的指标会有略有差异)

    2.对指标质量规则建模,实现控制方案的数据模型

    3.包装成一个可直接使用的接口供jenkins集成

    4.jenkins通过调用我们包装好的接口获取扫描结果,并根据结果控制流程

    步骤1:API获取指标

    通过对API分析,我们找到如下获取指标的API

    http://sonar.xxxx.cn/api/measures/search?projectKeys=项目 key&metricKeys=code_smells,bugs,coverage,duplicated_lines_density,ncloc,security_rating,vulnerabilities,comment_lines_density

    调用后返回结果如下:

    {    "measures": [{        "metric": "bugs",        "value": "0",        "component": "netCore01",        "bestValue": true    }, {        "metric": "code_smells",        "value": "3",        "component": "netCore01",        "bestValue": false    }, {        "metric": "comment_lines_density",        "value": "2.8",        "component": "netCore01",        "bestValue": false    }, {        "metric": "coverage",        "value": "0.0",        "component": "netCore01",        "bestValue": false    }, {        "metric": "duplicated_lines_density",        "value": "0.0",        "component": "netCore01",        "bestValue": true    }, {        "metric": "ncloc",        "value": "138",        "component": "netCore01"    }, {        "metric": "security_rating",        "value": "1.0",        "component": "netCore01",        "bestValue": true    }, {        "metric": "vulnerabilities",        "value": "0",        "component": "netCore01",        "bestValue": true    }]}说明:具体指标获取可以在项目--指标然后左侧各种指标点击查看,URL中会有该指标的字段名

    步骤2:质量规则建模

    以上接口我们获取了一些主要的扫描结果,但这些指标数据如何控制更合理,是每个团队需要考虑的事情,本例为演示技术实现为主,建模不具实际业务参考。

    强制规则:首先我们认为BUG及安全漏洞是系统不能允许出现的,一旦有这两项,则需要先修复才能部署

    扣分规则:不同的问题类型我们扣分权重不同,通过加权*数量进行扣分计算

    通过阈值:如果强制规则通过,则验证最低通过分阈值判断是否通过

    策略是否通过扣分对应字段

    漏洞大于0否漏洞数*5vulnerabilities  安全漏洞数量

    BUG大于0否BUG数*5bugs BUG数量

    code_smells数量扣分code_smells*2code_smells 代码坏味道数量

    duplicated_lines_density扣分duplicated_lines_density>5%则单独扣分规则duplicated_lines_density重复行比例

    comment_lines_density扣分comment_lines_density<7%则单独扣分规则comment_lines_density代码注释比例

    还有其他几个指标,不再逐一讲解。

    步骤3:对数据模型及sonar Api包装成专用api

    服务接口采用.netCore开发,主要是vs开发工具的确太好用,然后用k8s部署即可

    主要代码逻辑如下:

    API层:

    [Route("[controller]/[action]")][ApiController]publicclassSonarController:Controller{staticstringfields="code_smells,bugs,coverage,duplicated_lines_density,ncloc,security_rating,vulnerabilities,comment_lines_density";staticstringsonarRootUrl="http://sonarqube.default:9000";staticfloatminScore=70f;//分数通过阈值publicSonarResultScan(stringprojectKey){stringurl=string.Format(sonarRootUrl+"/api/measures/search?projectKeys="+projectKey+"&metricKeys="+fields);stringresult=HttpHelper.HttpGet(url,"application/json");SonarScanResultscanResult=result.FromJSON<SonarScanResult>();returnnewSonarResult(scanResult,minScore);}}

    数据处理部分

    publicclassSonarScanResult{publicList<SonarScanResultItem>measures{get;set;}}publicclassSonarScanResultItem{publicstringmetric{get;set;}publicstringvalue{get;set;}publicstringcomponent{get;set;}publicboolbestValue{get;set;}}publicclassSonarResult{publicList<SonarScanResultItem>measures;/// <summary>/// 坏味道/// </summary>publicfloatcode_smells{get;set;}/// <summary>/// BUG/// </summary>publicfloatbugs{get;set;}/// <summary>/// 覆盖率/// </summary>publicfloatcoverage{get;set;}/// <summary>/// 重复率/// </summary>publicfloatduplicated_lines_density{get;set;}/// <summary>/// 代码行数/// </summary>publicfloatncloc{get;set;}//代码行数/// <summary>/// /// </summary>publicfloatsecurity_rating{get;set;}/// <summary>/// 漏洞数量/// </summary>publicfloatvulnerabilities{get;set;}/// <summary>/// 可靠性/// </summary>publicfloatreliability_rating{get;set;}/// <summary>/// 注释占比/// </summary>publicfloat?comment_lines_density{get;set;}/// <summary>/// 总体得分/// </summary>publicfloatScore{get;set;}/// <summary>/// 是否通过/// </summary>publicboolPass{get;set;}publicstringMsg{get;set;}privatefloatminScore;publicSonarResult(SonarScanResultresult,floatminScore){this.minScore=minScore;if(result!=null&&result.measures!=null){this.measures=result.measures;}else{this.measures=newList<SonarScanResultItem>();}this.OutputResult();}/// <summary>/// 计算输出结果/// </summary>publicvoidOutputResult(){this.code_smells=GetMetricValue("code_smells");this.bugs=GetMetricValue("bugs");this.coverage=GetMetricValue("coverage");this.duplicated_lines_density=GetMetricValue("duplicated_lines_density");this.ncloc=GetMetricValue("ncloc");this.security_rating=GetMetricValue("security_rating");this.vulnerabilities=GetMetricValue("vulnerabilities");this.reliability_rating=GetMetricValue("reliability_rating");comment_lines_density=GetMetricValue2("comment_lines_density");this.Pass=true;if(bugs>0||vulnerabilities>0){//强制不通过,分数0,别怪我为难程序员,我也是被刁难了多年this.Pass=false;this.Score=0;this.Msg=string.Format("漏洞:{0},BUG:{1},不满足发布策略",vulnerabilities,bugs);}else{doublecutScore=bugs*5+code_smells*2+security_rating*2.5+vulnerabilities*5;if(comment_lines_density.HasValue&&comment_lines_density<7)//7.0%的注释为一个及格线,大于7%不扣分{cutScore+=(7-comment_lines_density.Value);}if(duplicated_lines_density>5){cutScore+=(comment_lines_density.Value-5);//重复率每增加1百分比,扣1分}this.Score=100-(float)cutScore;this.Pass=this.Score>=minScore;if(!this.Pass)this.Msg="该代码综合质量评分过低,需改进后方可准入部署环境";elsethis.Msg="代码综合质量分为:"+this.Score+",允许部署";}}privatefloatGetMetricValue(stringkey){varitem=this.measures.FirstOrDefault(p=>p.metric==key);if(item==null)return0f;returnConvertHelper.Tofloat(item.value,0f);}privatefloat?GetMetricValue2(stringkey){varitem=this.measures.FirstOrDefault(p=>p.metric==key);if(item==null)returndefault(float?);returnConvertHelper.Tofloat2(item.value);}}

    部署接口到k8s,然后验证接口返回

    {"code_smells":3,"bugs":0,"coverage":0,"duplicated_lines_density":0,"ncloc":138,"security_rating":1,"vulnerabilities":0,"reliability_rating":0,"comment_lines_density":2.8,"score":87.3,"pass":true,"msg":"代码综合质量分为:87.3,允许部署"}

    步骤4:Jenkins集成质量检查Api控制发布流程

    在昨天我们Jenkins执行扫描完毕环节后添加发下脚本:

    //说明:sonarCheckUrl是我们上面用.net core实现的API,地址:http://xxxxx/checkApi/Sonar/Scan?projectKey=$sonarKey          def response = httpRequest acceptType: 'APPLICATION_JSON', contentType: 'APPLICATION_JSON', httpMode: 'GET',  url: "$sonarCheckUrl?projectKey=$sonarKey"                  def responseBodyJson = readJSON text: response.content            if (responseBodyJson.pass) {              println("#############################################代码质量检测通过,综合得分:"+responseBodyJson.score+ "##################################################")          } else {                                    println("#############################################代码质量检测不通过,综合得分:"+responseBodyJson.score+"原因" + responseBodyJson.msg+ ",流水线退出##################################################")              sh "exit 1"          }

    修改完毕后,我们重新执行发布过程,发布结果输出如下:

    这里是刚扫描结束INFO:Totaltime:5.882sINFO:FinalMemory:12M/44MINFO:------------------------------------------------------------------------TheSonarQubeScannerhas finished12:40:54.591Post-processing succeeded.[Pipeline]echo #############################################代码质量检查完毕##################################################[Pipeline]echo #############################################开始请求质量检查结果##################################################[Pipeline]httpRequest HttpMethod:GETURL:[http://api.xxxx.cn/checkApi//onar/Scan?projectKey=netCore01](http://api.xxxx.cn/checkApi//Sonar/Scan?projectKey=netCore01)Content-Type:application/jsonAccept:application/jsonSendingrequest to url:[http://api.xxxx.cn/checkApi/Sonar/Scan?projectKey=netCore01](http://api.xxx.cn/checkApi/Sonar/Scan?projectKey=netCore01)ResponseCode:HTTP/1.1200OKSuccesscodefrom[100‥399][Pipeline]echo sonar Response:Status:200[Pipeline]echo response.content:{"code_smells":3,"bugs":0,"coverage":0,"duplicated_lines_density":0,"ncloc":138,"security_rating":1,"vulnerabilities":0,"reliability_rating":0,"comment_lines_density":2.8,"score":87.3,"pass":true,"msg":"代码综合质量分为:87.3,允许部署"}[Pipeline]readJSON[Pipeline]echo#############################################代码质量检测通过,综合得分:87.3################################################## [Pipeline]}[Pipeline]// withEnv

    3. 小结

    本文通过对Sonar Api扩展及集成,实现了自定义的代码质量控制模型及策略,这种方案相对更灵活一些。

    您也可以使用sonarqube中自带的【质量阈】,通过界面配置不同的策略进行控制的方式。

    另外API获取数据的方案您也可以改为从sonar数据库中查询数据的方式获取,但该方式容易因为版本升级出现不兼容问题。

    3.1 Sonar质量阈方案

    Sonarqube质量阈控制

    3.2 SQL查询数据方案

    先查出项目uuid:

    SELECT project_uuid,kee FROM projects where kee='projName'

    --BUG

    SELECT * FROM issues WHERE project_uuid='项目UUID' and issue_type=2

    --漏洞

    SELECT * FROM issues WHERE project_uuid='项目UUID' and issue_type=3

    --坏味道

    SELECT * FROM issues WHERE project_uuid='项目UUID' and issue_type=1

    若要分级别获取,可以再加上条件

    severity =

    ['BLOCKER','CRITICAL',"MAJOR",'MINOR','INFO']

    对应含义:阻断/严重/主要/次要/提示

    作者:上岸的魚

    链接:https://www.jianshu.com/p/a0d77b0b4809

    来源:简书

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

          本文标题:基于Sonarqube Api---Jenkins集成发布质量控

          本文链接:https://www.haomeiwen.com/subject/ygwluktx.html