1 环境准备
1.1 安装sonarqube
/app/module/sonarqube
1.2 安装sonar-scanner
/app/module/sonar-scanner
1.3 安装SonarQube Scanner插件
略
1.4 Jenkins配置sonar凭据
1.5 Jenkins配置Sonarqube服务地址
1.6 Jenkins配置Sonar-Scanner
1.7 sonarqube强制登录
2 Jenkins项目分析
2.1 手动分析项目
/app/module/sonar-scanner/bin/sonar-scanner \
-Dsonar.host.url=http://192.168.137.130:9000 \
-Dsonar.login=d6cfa716cbebcc03c51f8306f86ced69150e2295 \
-Dsonar.projectKey=web_demo \
-Dsonar.projectName=web_demo \
-Dsonar.projectVersion=1.0 \
-Dsonar.ws.timeout=30 \
-Dsonar.projectDescription='my first project!' \
-Dsonar.links.homepage=http://www.baidu.com \
-Dsonar.sources=src \
-Dsonar.sourceEncoding=UTF-8 \
-Dsonar.java.binaries=target/classes \
-Dsonar.java.surefire.report=target/surefire-reports
2.2 配置共享库
/src/org/devops/sonarqube.groovy
package org.devops
//scan
def SonarScan(projectName,projectDesc,projectPath){
def scannerHome = tool 'sonar-scanner'
def sonarServer = "http://192.168.137.130:9000"
def sonarDate = sh returnStdout: true, script: 'date +%Y%m%d%H%M%S'
sonarDate = sonarDate - "\n"
sh """
${scannerHome}/bin/sonar-scanner \
-Dsonar.host.url=${sonarServer} \
-Dsonar.login=d6cfa716cbebcc03c51f8306f86ced69150e2295 \
-Dsonar.projectKey=${projectName} \
-Dsonar.projectName=${projectName} \
-Dsonar.projectVersion=${sonarDate} \
-Dsonar.ws.timeout=30 \
-Dsonar.projectDescription=${projectDesc} \
-Dsonar.links.homepage=http://www.baidu.com \
-Dsonar.sources=${projectPath} \
-Dsonar.sourceEncoding=UTF-8 \
-Dsonar.java.binaries=target/classes \
-Dsonar.java.surefire.report=target/surefire-reports
"""
}
2.3 jenkinsfile配置
2.4 构建结果
2.5 分析项目结果
3 支持多sonar服务
3.1 配置共享库
/src/org/devops/sonarqube.groovy进行修改
支持多sonar服务
package org.devops
//scan
def SonarScan(sonarServer,projectName,projectDesc,projectPath){
//定义服务器列表
//因为SonarQube servers系统设置就配置了一个name为SonarQube
def servers = ["dev":"SonarQube","test":"SonarQube"]
withSonarQubeEnv("${servers[sonarServer]}"){
def scannerHome = tool 'sonar-scanner'
//def sonarServer = "http://192.168.137.130:9000" 将认证url和token都可以删除了
def sonarDate = sh returnStdout: true, script: 'date +%Y%m%d%H%M%S'
sonarDate = sonarDate - "\n"
sh """
${scannerHome}/bin/sonar-scanner \
//-Dsonar.host.url=${sonarServer} \
//-Dsonar.login=d6cfa716cbebcc03c51f8306f86ced69150e2295 \
-Dsonar.projectKey=${projectName} \
-Dsonar.projectName=${projectName} \
-Dsonar.projectVersion=${sonarDate} \
-Dsonar.ws.timeout=30 \
-Dsonar.projectDescription=${projectDesc} \
-Dsonar.links.homepage=http://www.baidu.com \
-Dsonar.sources=${projectPath} \
-Dsonar.sourceEncoding=UTF-8 \
-Dsonar.java.binaries=target/classes \
-Dsonar.java.surefire.report=target/surefire-reports
"""
}
}
3.2 Jenkinsfile配置
3.3 分析项目结果
4 Sonarqube项目管理
4.1 规则使用
4.1.1 质量配置
1、新增质量配置
2、给质量配置绑定规则
3、给项目绑定质量规则
4.1.2 质量阈
4.1.3 构建结果
4.1.4 分析项目结果
4.2 质量阈错误通知管理员并终止流水线
4.2.1 配置共享库
/src/org/devops/sonarapi.groovy
package org.devops
//封装HTTP
def HttpReq(reqType,reqUrl,reqBody){
def sonarServer = "http://192.168.137.130:9000/api"
result = httpRequest authentication: 'sonar-admin-auth',
httpMode: reqType,
contentType: "APPLICATION_JSON",
consoleLogResponseBody: true,
ignoreSslErrors: true,
requestBody: reqBody,
url: "${sonarServer}/${reqUrl}"
//quiet: true
return result
}
//获取Sonar质量阈状态
def GetProjectStatus(projectName){
apiUrl = "project_branches/list?project=${projectName}"
response = HttpReq("GET",apiUrl,'')
response = readJSON text: """${response.content}"""
result = response["branches"][0]["status"]["qualityGateStatus"]
//println(response)
return result
}
//搜索Sonar项目
def SerarchProject(projectName){
apiUrl = "projects/search?projects=${projectName}"
response = HttpReq("GET",apiUrl,'')
response = readJSON text: """${response.content}"""
result = response["paging"]["total"]
if(result.toString() == "0"){
return "false"
} else {
return "true"
}
}
//创建Sonar项目
def CreateProject(projectName){
apiUrl = "projects/create?name=${projectName}&project=${projectName}"
response = HttpReq("POST",apiUrl,'')
println(response)
}
//配置项目质量规则
def ConfigQualityProfiles(projectName,lang,qpname){
apiUrl = "qualityprofiles/add_project?language=${lang}&project=${projectName}&qualityProfile=${qpname}"
response = HttpReq("POST",apiUrl,'')
println(response)
}
//获取质量阈ID
def GetQualtyGateId(gateName){
apiUrl= "qualitygates/show?name=${gateName}"
response = HttpReq("GET",apiUrl,'')
response = readJSON text: """${response.content}"""
result = response["id"]
return result
}
//配置项目质量阈
def ConfigQualityGates(projectName,gateName){
gateId = GetQualtyGateId(gateName)
apiUrl = "qualitygates/select?gateId=${gateId}&projectKey=${projectName}"
response = HttpReq("POST",apiUrl,'')
println(response)println(response)
}
4.2.2 创建sonar账号密码凭据
4.2.3 jenkinsfile配置
4.2.4 构建结果
4.2.5 邮箱信息
4.3 查找项目
4.4 新建项目
4.5 配置项目质量规则
4.6 更新质量阈
5 附录
5.1 jenkinsfile
#!groovy
@Library('jenkinslib') _
def tools = new org.devops.tools()
def build = new org.devops.build()
def gitlab = new org.devops.gitlab()
def toemail = new org.devops.toemail()
def sonar = new org.devops.sonarqube()
def sonarapi = new org.devops.sonarapi()
def WebHookData = readJSON text : allData
String branch=WebHookData.ref
String userName=WebHookData.user_username
String projectId=WebHookData.project.id
String commitSha=WebHookData.checkout_sha
pipeline {
agent {
node {
label "built-in"
}
}
environment {
String GsrcUrl="${env.srcUrl}"
String GbranchName="${env.branchName}"
String GbuildType="${env.buildType}"
String GbuildShell="${env.buildShell}"
String qpName = "demo" //Sonar%20way
}
stages {
stage('CheckOut') {
steps {
script {
if ("$runOpts" == "GitlabPush"){
GbranchName = branch - 'refs/heads/'
currentBuild.description = "Trigger by user ${userName} \n branch: ${GbranchName}"
gitlab.ChangeCommitStatus(projectId,commitSha,"running")
}
tools.PrintMes("获取代码",'green')
checkout scmGit(branches: [[name: "${GbranchName}"]],
extensions: [cleanBeforeCheckout()],
userRemoteConfigs: [[credentialsId: '8c8a0774-7d4c-48a9-8f52-dd1a04f71320',
url: "${GsrcUrl}"]])
}
}
}
stage("Build") {
steps {
script {
tools.PrintMes("执行打包",'green')
build.Build(GbuildType,GbuildShell)
}
}
}
stage('QA') {
steps {
script {
tools.PrintMes("搜索项目",'green')
result = sonarapi.SerarchProject("${JOB_NAME}")
println(result)
if ( result == 'false' ){
println("${JOB_NAME}---项目不存在,准备创建项目---> ${JOB_NAME}!")
sonarapi.CreateProject("${JOB_NAME}")
} else {
println("${JOB_NAME}---项目已存在")
}
tools.PrintMes("配置项目质量规则","green")
sonarapi.ConfigQualityProfiles("${JOB_NAME}","web",qpName)
tools.PrintMes("配置质量阈","green")
sonarapi.ConfigQualityGates("${JOB_NAME}",qpName)
tools.PrintMes("代码扫描",'green')
sonar.SonarScan("dev","${JOB_NAME}","${JOB_NAME}","src")
sh "sleep 20"
tools.PrintMes("获取扫描结果",'green')
result = sonarapi.GetProjectStatus("${JOB_NAME}")
println(result)
if ( result.toString() == "ERROR" ){
toemail.Email("代码质量阈错误,请及时修复!",userEmail)
error "代码质量阈错误,请及时修复!"
}else {
println(result)
}
}
}
}
}
post {
always {
script {
println("always")
}
}
success {
script {
println("success")
gitlab.ChangeCommitStatus(projectId,commitSha,"success")
toemail.Email("流水线成功了",userEmail)
}
}
failure {
script {
println("failure")
gitlab.ChangeCommitStatus(projectId,commitSha,"failed")
toemail.Email("流水线失败了",userEmail)
}
}
aborted {
script {
println("aborted")
gitlab.ChangeCommitStatus(projectId,commitSha,"canceled")
toemail.Email("流水线被取消了",userEmail)
}
}
}
}
5.2 Ldap认证
1.准备工作
获取LDAP服务信息、admin账号、安装sonarldap插件。
2.LDAP配置
#LDAP settings
#admin
sonar.security.realm=LDAP
ldap.url=ldap://192.168.1.200:389
ldap.bindDn=cn=admin,dc=devops,dc=com
ldap.bindPassword=ldap12344
#users
ldap.user.baseDn=ou=jenkins,dc=devops,dc=com
ldap.user.request=(&(objectClass=inetOrgPerson)(cn={login}))
ldap.user.realNameAttribute=cn
ldap.user.emailAttribute=mail
3.测试验证
重启sonarqube
systemctl restart sonarqube
5.3 Gitlab认证
1、安装插件
sonar插件地址:https://github.com/gabrie-allaigre/sonar-auth-gitlab-plugin
安装插件: 下载插件然后通过maven打包然后放入到sonar的插件目录中(/home/sonar/sonarqube/extensions/plugins),重启sonarqube。
2、gitlab配置
创建应用,填写sonar地址(必须是https)
3、sonarqube配置
配置》gitlab 启动gitlab认证,填写gitlab地址,应用ID,secret信息