【问题标题】:Sonarqube quality gate not sending webhook to jenkinsSonarqube 质量门不向詹金斯发送 webhook
【发布时间】:2018-01-23 09:47:20
【问题描述】:

我将 Jenkins 配置为使用 sonarqube 扫描仪。扫描工作正常。詹金斯管道正在工作,詹金斯日志中没有任何问题。

SonarQube 扫描仪 3.0.3.778 詹金斯:2.70 SonarQube Scanner for Jenkins 插件:2.6.1

我使用这个代码:

    stage('SonarQube analysis') {
        sh 'sed -ie "s|_PROJECT_|${PROJECT_CODE}|g" $WORKSPACE/_pipeline/sonar-project.properties'
        // requires SonarQube Scanner 3.0+
        def scannerHome = '/opt/sonar/bin/sonar-scanner';
        withSonarQubeEnv('mscodeanalysis') {
            sh "${scannerHome}/bin/sonar-scanner -Dproject.settings=$WORKSPACE/_pipeline/sonar-project.properties"
        }
    }
    }
    }
}
    }
    // No need to occupy a node
    stage("Quality Gate"){
        timeout(time: 15, unit: 'MINUTES') { // Just in case something goes wrong, pipeline will be killed after a timeout
        def qg = waitForQualityGate() // Reuse taskId previously collected by withSonarQubeEnv
            if (qg.status != 'OK') {
                error "Pipeline aborted due to quality gate failure: ${qg.status}"
            }
        }
    }

我的问题来自质量门。它从不将 json 有效负载发布到詹金斯。我在 jenkins 日志中没有看到 json 条目。但我知道 jenkins 和 sonarqube 服务器之间的连接正在工作,因为我能够使用 curl 从 sonarqube VM 发送 POST。

这里是詹金斯的工作输出:

Timeout set to expire in 15 min
[Pipeline] {
[Pipeline] waitForQualityGate
Checking status of SonarQube task 'AV3irVJXpvBxXXNJYZkd' on server 'mscodeanalysis'
SonarQube task 'AV3irVJXpvBxXXNJYZkd' status is 'PENDING'
Cancelling nested steps due to timeout

这是我从未到达 jenkins 管道的有效负载: 网址:http://sonar-server:9000/api/ce/task?id=AV3irVJXpvBxXXNJYZkd

{"task":{"organization":"default-organization","id":"AV3irVJXpvBxXXNJYZkd","type":"REPORT","componentId":"AV3hrJeCfL_nrF2072FH","componentKey":"POOL-003","componentName":"POOL-003","componentQualifier":"TRK","analysisId":"AV3irVkZszLEB6PsCK9X","status":"SUCCESS","submittedAt":"2017-08-14T21:36:35+0000","submitterLogin":"jenkins","startedAt":"2017-08-14T21:36:37+0000","executedAt":"2017-08-14T21:36:38+0000","executionTimeMs":650,"logs":false,"hasScannerContext":true}}

我无法插入图像,但质量门为通过,分析任务成功。

如果我需要提供更多信息,请告诉我。 谢谢

【问题讨论】:

  • 验证:您确实配置了一个 webhook 以在服务器端处理结束时回传给 Jenkins,对吧?
  • 是的,我在这个页面配置webhook:sonarqube-servert:9000/settings?category=webhooks把nameL Jenkins和url:jenkins-int.domain.com/sonarqube-webhook
  • 你的日志显示 webhook 被触发了?另外,这两个盒子之间有代理或防火墙吗?
  • 在哪个日志中可以看到这个? ce.log 中没有任何内容,我在盒子之间确实有防火墙。但是 curl -H "Content-Type: application/json" -X POST -d "PAYLOAD I already past" jenkins-int.domain.comt/sonarqube-webhook 到达 jenkins 服务器。我可以在詹金斯日志中看到 POST。在詹金斯作业运行之后。我可以看到:SonarQube Quality Gate TEST-003 OK server-side processing: Success On jenkins job page

标签: jenkins sonarqube quality-gate


【解决方案1】:

问题可能是 Jenkins 使用带有自签名证书的 https。那么解决方案是:

  1. 为 SonarQube 生成信任库:

    keytool -import -trustcacerts -alias jenkins-host-name -file cert.crt -keystore sonarqube.jks
    

    密钥库密码:密码

    其中 cert.crt - 是 jenkins 用于 ssl 的证书,jenkins-host-name - 是 docker 网络中 jenkins 的主机名(在 webhook 中使用)

  2. 将信任库添加到 SonarQube Dockerfile:

    FROM sonarqube
    COPY sonarqube.jks /var/sonar_cert/
    COPY sonar.properties /opt/sonarqube/conf/sonar.properties
    
  3. 更新 sonar.properties

    sonar.ce.javaAdditionalOpts=-Djavax.net.ssl.trustStore=/var/sonar_cert/sonarqube.jks -Djavax.net.ssl.trustStorePassword=password
    

如果您在 webhook URL 中提供了正确的 Jenkins 用户名和密码,那么一切都应该正常工作。

已尝试:Jenkins 2.107.2、SonarQube 7.1

【讨论】:

  • 执行此操作后,我收到错误 HTTP 401,并从 ce.log 记录消息:无法发送 webhook url=my-jenkins-ip/sonarqube-webhook/ | message=trustAnchors 参数必须为非空
  • 错误“trustAnchors parameter must be non-empty”表示未找到sonarqube.jks文件,我终于想通了我应该使用绝对路径和-Djavax.net.ssl.trustStore环境。谢谢。
  • 您在配置自签名证书时是否遇到此错误?发送 webhook 'Jenkins CI' 失败 |网址=1.2.3.4:5678/sonarqube-webhook | message=主机名 1.2.3.4 未验证:
  • 您需要使用Jenkins服务器的域名(如果没有,可以在SonarQube服务器上编辑/etc/hosts创建),使用SSL证书时ip地址不ok。跨度>
【解决方案2】:

以下是我们为解决此问题所做的简单示例:

SonarQube 随机挂在“挂起”状态。告诉它重试会刷新它。在本例中,我们将其设置为 10 秒

maxRetry = 200
forloop (i=0; i<maxRetry; i++){
    try {
        timeout(time: 10, unit: 'SECONDS') {
            waitForQualityGate()
        }
    } catch(Exception e) {
        if (i == maxRetry-1) {
            throw e
        }
    }
}

【讨论】:

    【解决方案3】:

    惊讶地发现@Katone Vi 的回答效果很好。根据他们的回答,我们添加了一个成功的快速退出并使用 DSL 来处理原始请求:

        stage('SonarQube') {
          steps {
            withSonarQubeEnv('SonarQube') {
              sh """
                ${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=XXX_${env.STAGE}_lambda
              """
            }
    
            script {
              Integer waitSeconds = 10
              Integer timeOutMinutes = 10
              Integer maxRetry = (timeOutMinutes * 60) / waitSeconds as Integer
              for (Integer i = 0; i < maxRetry; i++) {
                try {
                  timeout(time: waitSeconds, unit: 'SECONDS') {
                    def qg = waitForQualityGate()
                    if (qg.status != 'OK') {
                      error "Sonar quality gate status: ${qg.status}"
                    } else {
                      i = maxRetry
                    }
                  }
                } catch (Throwable e) {
                  if (i == maxRetry - 1) {
                    throw e
                  }
                }
              }
            }
          }
        }
    

    【讨论】:

      【解决方案4】:

      如果您已将 SonarQube 配置为使用 HTTP(S) 代理,请确保您的 jenkins 可以通过代理访问或配置为“非代理主机”。这可以通过http.nonProxyHosts 属性或HTTP_NONPROXYHOSTS 环境变量来完成。另请参阅documentation 了解更多信息和语法。

      【讨论】:

        【解决方案5】:

        如果您使用的是 Jenkinsfile,这是解决方法:

        定义凭据:

         environment { 
          CRED = credentials('jenkins_user_pass') 
         }
        

        然后使用:

        stage("Quality Gate") {
            steps {
                 script {
                        while(true){
                            sh "sleep 2"
                            def url="http://jenkinsURL/job/${env.JOB_NAME.replaceAll('/','/job/')}/lastBuild/consoleText";
                            def sonarId = sh script: "wget -qO- --content-on-error --no-proxy --auth-no-challenge --http-user=${CRED_USR} --http-password=${CRED_PSW} '${url}'  | grep 'More about the report processing' | head -n1 ",returnStdout:true
                            sonarId = sonarId.substring(sonarId.indexOf("=")+1)
                            echo "sonarId ${sonarId}"
                            def sonarUrl = "http://jenkinsURL/sonar/api/ce/task?id=${sonarId}"
                            def sonarStatus = sh script: "wget -qO- '${sonarUrl}' --no-proxy --content-on-error | jq -r '.task' | jq -r '.status' ",returnStdout:true
                            echo "Sonar status ... ${sonarStatus}"
                            if(sonarStatus.trim() == "SUCCESS"){
                                echo "BREAK";
                                break;
                            }
                            if(sonarStatus.trim() == "FAILED "){
                                echo "FAILED"
                                currentBuild.result = 'FAILED'
                                break;
                            }
                        }
                    }
                }
            }
        

        【讨论】:

          【解决方案6】:

          我遇到过类似的问题,而 Sonar 服务器中的质量门后端活动需要不到 20 秒的时间来完成分析。但是 jenkins 作业中 sonar-webhook 的质量门失败/成功响应需要很多时间并且卡住了.

           stage('Sonar:QG') {
                      steps {
                          **sleep(10)  /* Added 10 sec sleep that was suggested in few places*/**
                          script{
                              timeout(time: 10, unit: 'MINUTES') {
                                  def qg = waitForQualityGate abortPipeline: true
                                  if (qg.status != 'OK') {
                                      echo "Status: ${qg.status}"
                                      error "Pipeline aborted due to quality gate failure: ${qg.status}"
                                  }
                              }
                          }
                      }
                  }
          

          基本上检查以下内容:- Webhook 是否在声纳中配置:- SonarQube -> Administration -> Webhooks http://:/sonarqube-webhook/

          或在http://locahlhost:port/sonarqube-webhook/ 中使用 localhost 代替 IP 可以解决我的问题。

          【讨论】:

            【解决方案7】:

            我做出了更简单的决定,但效果相同

            stage("Quality gate") {
                  steps {
                    retry(3){
                        waitForQualityGate abortPipeline: true
                      }
            
                  }
                }
            

            【讨论】:

              【解决方案8】:

              在 stage('SonarQube analysis') 和 stage("Quality Gate") 之间添加一个 sh 'sleep 10' 可以解决此问题。现在詹金斯的工作收到了

              Checking status of SonarQube task 'AV3rHxhp3io6giaQF_OA' on server 'sonarserver'
              SonarQube task 'AV3rHxhp3io6giaQF_OA' status is 'SUCCESS'
              SonarQube task 'AV3rHxhp3io6giaQF_OA' completed. Quality gate is 'OK'
              

              【讨论】:

              • 对我来说,这并不能证明问题已得到解决。这可能只是 SonarQube 端的异步任务不到 10 秒即可完成。因此,您收到“SUCCESS”不是因为 webhook,而仅仅是因为 waitForQualityGate 启动时任务已经完成。
              • 抱歉,这不是解决方案。这种“解决方法”的结果是,工作将冻结!我从github.com/jenkinsci/sonarqube-plugin/blob/master/src/main/java/… 学习了源代码。有两个步骤。 (1) 尝试通过 sonar/api/ce/task?id=xxxxx 直接调用 sonar qube。 (2) 如果结果不成功,那么他们将创建包含监听器 SonarQubeWebHook 的异步任务。但是,ISSUE,那个声纳不叫詹金斯!
              猜你喜欢
              • 2017-06-24
              • 2018-07-21
              • 2016-12-15
              • 2020-12-30
              • 2019-10-21
              • 2016-12-24
              • 2023-04-10
              • 2019-11-24
              • 2019-03-29
              相关资源
              最近更新 更多