服务器无法访问SonarQube Webhook到Jenkins

0qx6xfy6  于 2023-06-21  发布在  Jenkins
关注(0)|答案(2)|浏览(344)

我们有两台服务器,一台在Docker Swarm中运行Jenkins,另一台运行SonarQube。在过去的几年里,Jenkins管道成功地触发了Sonar扫描,并将webhooks报告给Jenkins。
但是在Jenkins端的SSL证书更新(在集群的ALB上)之后,webhook只是不断地说“服务器无法到达”。jenkins的URL根本没有更改。

而在jenkins方面,日志只是等待质量门超时。

SonarQube task 'AXz95fbXYt_5WKK0bZ00' status is 'IN_PROGRESS'
Cancelling nested steps due to timeout

Jenkinsfile在质量门阶段看起来像这样:

timeout(time: 5, unit: 'MINUTES') {                    
         waitForQualityGate abortPipeline: true
     }
xdnvmnnf

xdnvmnnf1#

正如我在评论中提到的,我们遇到了几乎完全相同的事件序列。在他们在我们的Jenkins示例上重新配置SSL的那天,我们从SonarQube到Jenkins的webhook开始失败。那是一年多以前的事了。我们从来没有找到任何线索来解释为什么会这样。
在某个时候,我得出的结论是,这将永远不会被修复,所以我决定找出一个变通办法。理解"waitForQualityGate"中发生的逻辑很有帮助。它做的第一件事是对SonarQube进行REST调用,以确定后台任务是否完成。如果不是,则进入等待任务完成的循环,该循环将不会成功完成。
因此,解决方法是确保当“waitForQualityGate”启动时,我们确保后台任务已完成。有两种方法可以做到这一点。有一种策略非常简单,但也有缺点,还有一种稍微复杂一点的策略更聪明。
非常简单的策略就是在"waitForQualityGate"之前添加一个"sleep"。你睡多久真的取决于。如果你睡得太短,一些后台任务可能还没有完成,再次进入循环。如果你睡得太久,那么你就浪费时间坐在那里,什么都不做。
更好的策略是本质上使用“waitForQualityGate”中使用的相同逻辑,在重试循环中对SonarQube进行REST调用以检查后台任务的状态,并在状态报告任务完成时退出循环。
其逻辑如下所示:

String authString = "${sonarProps['sonar.login']}:${sonarProps['sonar.password']}"
// If webhooks aren't going to work, then we have to poll for the task ourselves. First, we have to figure
// out the task id.
def reportFilePath = "target/sonar/report-task.txt"
def reportTaskFileExists = fileExists "${reportFilePath}"
if (reportTaskFileExists) {
    echo "Found report task file"
    def taskProps = readProperties file: "${reportFilePath}"
    echo "taskId[${taskProps['ceTaskId']}]"
    while (true) {
        sleep 20
        def taskStatusResult    =
            sh(returnStdout: true,
               script: "curl -s -X GET -u ${authString} \'${sonarProps['sonar.host.url']}/api/ce/task?id=${taskProps['ceTaskId']}\'")
            echo "taskStatusResult[${taskStatusResult}]"
        def taskStatus  = new JsonSlurper().parseText(taskStatusResult).task.status
        echo "taskStatus[${taskStatus}]"
        // Status can be SUCCESS, ERROR, PENDING, or IN_PROGRESS. The last two indicate it's
        // not done yet.
        if (taskStatus != "IN_PROGRESS" && taskStatus != "PENDING") {
            break;
        }
    }
}
z5btuh9x

z5btuh9x2#

第一件事是找到问题的根源。FWIW,每当http状态代码不>= 200且< 300时,就会显示“服务器无法到达”消息。为什么会这样的部分细节在下面的代码行中:
https://github.com/SonarSource/sonarqube/blob/HEAD/server/sonar-web/src/main/js/apps/webhooks/components/DeliveryItem.tsx#L40
https://github.com/SonarSource/sonarqube/blob/HEAD/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseResponse.java#L28
(when httpStatus未填充,因为它未成功,显示消息“服务器无法访问”)。
但由于该消息没有帮助,因此需要获取实际的错误消息。为此,您需要将日志级别更改为DEBUG或TRACE(“管理”页面,“系统”选项卡,“日志级别”设置)。然后你需要用webhook重现这个问题。然后你下载计算引擎的日志,你会得到这样一行:
DEBUG ce[xxxxxx][o. s. s.w. WebHooksImpl]无法发送webhook“Jenkins”|URL=https://yourjenkins/sonarqube-webhook/|消息=无法找到请求目标的有效证书路径
因此,问题是Jenkins服务器的SSL证书不受SonarQube服务器(充当http客户端)的信任,这是典型的自签名证书,或由您的组织创建的根证书颁发机构(CA)签名。
解决方案是将CA根证书添加到SonarQube服务器使用的Java安装的cacerts文件中。对于在Windows上运行的SonarQube,这通常是文件%JAVA_HOME%\lib\security\cacerts

相关问题