SonarQube系统的API文档: http://192.168.1.200:9000/web_api
注意事项:
1.项目没有配置质量,默认使用sonarway
2.默认直接使用sonarscanner,扫描项目,使用内置的默认质量
需求:在代码扫描之前需要手动在sonarqube页面上,创建一个空项目,然后配置质量。
第一步创建项目,通过接口方式,其次配置质量域,也就是两个接口,一个创建项目的接口,一个配置质量的接口。
Jenkins代码中不要存在敏感信息, 将base64格式的SonarQube 用户token YWRtaW46YWRtaW4xMjM0
存储到Jenkins凭据中(Secret Text类型),后续使用withCredentials
将值赋值给变量SONAR_TOKEN
。
考虑到Api的URL都具有相同部分http://192.168.1.200:9000/api
所以单独复制给变量sonarApi
。每个接口返回的都是JSON类型的数据, 这里使用readJSON进行解析和处理。【所以有了下面的代码】
def SonarRequest(apiUrl,method){
withCredentials([string(credentialsId: "52df4ad9-7167-4bf6-a1fc-2f9f17713472", variable: 'SONAR_TOKEN')]) {
sonarApi = "http://192.168.1.200:9000/api"
response = sh returnStdout: true,
script: """
curl --location \
--request ${method} \
"${sonarApi}/${apiUrl}" \
--header "Authorization: Basic ${SONAR_TOKEN}"
"""
try {
response = readJSON text: """ ${response - "\n"} """
} catch(e){
response = readJSON text: """{"errors" : true}"""
}
return response
}
}
判断创建项目是否存在
http://139.198.166.235:9000/api/projects/search?projects=devops-maven-sonarqube
如果是一个不存在的项目
加上认证信息:
curl --location --request GET 'http://139.198.166.235:9000/api/projects/search?projects=devops-maven-sonarqube' \
--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
[root@jenkins-master ~]# curl --location --request GET 'http://139.198.166.235:9000/api/projects/search?projects=devops-maven-sonarqube' \
> --header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
{"paging":{"pageIndex":1,"pageSize":100,"total":1},"components":[{"key":"devops-maven-sonarqube","name":"devops-maven-sonarqube","qualifier":"TRK","visibility":"public","lastAnalysisDate":"2021-09-03T01:56:06+0000","revision":"1b40a1ef3391301102f1972109f26188f62d9581"}]}[root@jenkins-master ~]#
package org.devops
def SonarRequest(apiUrl,method){
sonarApi="http://139.198.166.235:9000/api"
respone=sh returnStdout: true, script:
"""
curl --location \
--request ${method} \
"${sonarApi}/${apiUrl}" \
--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
"""
respone=respone -"\n"
result=readJSON text: "${respone}"
return result
}
def SerarchProject(projectName,method){
apiUrl="projects/search?projects=${projectName}"
respone=SonarRequest(apiUrl,"GET")
if (respone["paging"]["total"] == 1){
return true
}else{
return false
}
}
@Library("devopslib@main") _
def sonarqubeapi = new org.devops.sonarqubeapi()
pipeline {
agent any
stages {
stage('SeacrchProject') {
steps {
script{
println(sonarqubeapi.SerarchProject("devops-maven-service","GET"))
}
}
}
}
}
创建项目:
curl --location --request POST 'http://139.198.166.235:9000/api/projects/create?name=sonar-maven&project=sonar-maven' \
--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
{
"errors": [
{
"msg": "Could not create Project, key already exists: sonar-maven"
}
]
}
package org.devops
def SonarRequest(apiUrl,method){
sonarApi="http://139.198.166.235:9000/api"
respone=sh returnStdout: true, script:
"""
curl --location \
--request ${method} \
"${sonarApi}/${apiUrl}" \
--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
"""
respone=respone -"\n"
result=readJSON text: "${respone}"
return result
}
def SerarchProject(projectName,method){
apiUrl="projects/search?projects=${projectName}"
respone=SonarRequest(apiUrl,"GET")
if (respone["paging"]["total"] == 1){
return true
}else{
return false
}
}
def CreateProject(projectName,method){
apiUrl="projects/create?name=${projectName}&project=${projectName}"
echo "${apiUrl}"
respone=SonarRequest(apiUrl,"POST")
try{
if (respone["project"]["name"] == "${projectName}"){
println("project create success")
return true
}
}catch(e){
println(respone.errors)
return false
}
}
最后就是给项目配置质量,现在这个项目里面什么都没有
http://139.198.166.235:9000/api/qualityprofiles/add_project?language=java&project=sonarqube-api-test&qualityProfile=maven
注意这个api调用成功是没有返回值的,所以这里是readjson要使用try catche来包围
def SonarRequest(apiUrl,method){
sonarApi="http://139.198.166.235:9000/api"
respone=sh returnStdout: true, script:
"""
curl --location \
--request ${method} \
"${sonarApi}/${apiUrl}" \
--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
"""
respone=respone -"\n"
try{
result=readJSON text: "${respone}"
}catch(e){
result=""
}
return result
}
def UpdateQualityProfile(language,projectName,qualityProfile){
apiUrl="qualityprofiles/add_project?language=${language}&project=${projectName}&qualityProfile=${qualityProfile}"
respone=SonarRequest(apiUrl,"POST")
if(respone==""){
println("language ${language} ${qualityProfile} bind ${projectName} success")
}else{
println("language ${language} ${qualityProfile} bind ${projectName} failed")
}
}
如果不放在共享库,那么可以简化为下面一个脚本
@Library("devopslib@main") _
def project = new org.devops.build()
def buildTools = ["maven": "/usr/local/apache-maven-3.8.1"]
def credentials = ["devops-maven-sonarqube": "f8b33d17-c1cf-428e-aa31-99d4038e59d0"]
String buildType = "${env.buildType}"
String projectDescription = "this is maven project"
currentBuild.description = "maven project"
pipeline {
agent {
label 'build'
}
stages {
stage("createProject"){
steps{
script{
if(searchProject(env.JOB_NAME) == false){
createProject(env.JOB_NAME)
}
}
}
}
stage('updateQualityProfile'){
steps{
script{
UpdateQualityProfile("java",env.JOB_NAME,"maven")
}
}
}
}
}
def sonarHttpRequest(method,apiUrl){
sonarApi = "http://139.198.166.235:9000/api"
response = sh returnStdout: true, script:
"""
curl --location \
--request ${method} \
"${sonarApi}/${apiUrl}" \
--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
"""
response = response - "\n"
try{
result = readJSON text: "${response}"
}catch(e){
result = ""
}
return result
}
def searchProject(projectName){
apiUrl = "projects/search?projects=${projectName}"
response = sonarHttpRequest("GET",apiUrl)
println(response)
if (response["paging"]["total"] == 1){
return true
}else{
return false
}
}
def createProject(projectName){
apiUrl="projects/create?name=${projectName}&project=${projectName}"
response=sonarHttpRequest("POST",apiUrl)
println(response)
try{
if (response["project"]["name"] == "${projectName}"){
println("project create success")
return true
}
}catch(e){
println(response.errors)
return false
}
}
def UpdateQualityProfile(language,projectName,qualityProfile){
apiUrl="qualityprofiles/add_project?language=${language}&project=${projectName}&qualityProfile=${qualityProfile}"
response=sonarHttpRequest("POST",apiUrl)
if(response==""){
println("language ${language} ${qualityProfile} bind ${projectName} success")
}else{
println("language ${language} ${qualityProfile} bind ${projectName} failed")
}
}
Running on build-01 in /data/cicd/jenkinsagent/workspace/sonar-api
[Pipeline] {
[Pipeline] stage
[Pipeline] { (createProject)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ curl --location --request GET 'http://139.198.166.235:9000/api/projects/search?projects=sonar-api' --header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 145 100 145 0 0 734 0 --:--:-- --:--:-- --:--:-- 732
100 145 100 145 0 0 733 0 --:--:-- --:--:-- --:--:-- 732
[Pipeline] readJSON
[Pipeline] echo
{"paging":{"pageIndex":1,"pageSize":100,"total":1},"components":[{"key":"sonar-api","name":"sonar-api","qualifier":"TRK","visibility":"public"}]}
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (updateQualityProfile)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ curl --location --request POST 'http://139.198.166.235:9000/api/qualityprofiles/add_project?language=java&project=sonar-api&qualityProfile=maven' --header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
[Pipeline] readJSON
[Pipeline] echo
language java maven bind sonar-api success
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS