Search code examples
jenkinssonarqubejenkins-pipelinesonarqube-scan

waitForQualityGate return 401


I have a SonarQube server & sonar-scanner + Jenkins setup on my server (no docker). The problem I have is that the Quality gate step always return a 401, even tough the analysis is working fine. I suspect there might be an authorization issue, but I cannot figure how to send the to waitForQualityGate method.

INFO: Analysis total time: 12.972 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 14.641s
INFO: Final Memory: 13M/50M
INFO: ------------------------------------------------------------------------
[Pipeline] }
[Pipeline] // withSonarQubeEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Quality gate)
[Pipeline] waitForQualityGate
Checking status of SonarQube task 'AXoxAunUF1YE_9gTnBHP' on server 'SonarQube'
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
org.sonarqube.ws.client.HttpException: Error 401 on https://<sonar-url>/api/ce/task?id=AXoxAunUF1YE_9gTnBHP : 
    at org.sonarqube.ws.client.BaseResponse.failIfNotSuccessful(BaseResponse.java:36)
    at hudson.plugins.sonar.client.HttpClient.getHttp(HttpClient.java:38)
    at hudson.plugins.sonar.client.WsClient.getCETask(WsClient.java:51)
    at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.checkTaskCompleted(WaitForQualityGateStep.java:234)
    at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.start(WaitForQualityGateStep.java:171)
    at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:319)
    at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:193)
    at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
    at jdk.internal.reflect.GeneratedMethodAccessor544.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:163)
    at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:157)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:161)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:165)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:135)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
    at WorkflowScript.run(WorkflowScript:25)

My Jenkinsfile looks like this

pipeline {
    agent any

    stages {
        stage('Clone sources') {
            steps {
                git branch: 'main', 
                credentialsId: '<github-credentials-id>',
                url: '<github-url>'
            }
        }
        stage('SonarQube analysis') {
            steps {
                withSonarQubeEnv('SonarQube') { 
                    sh "sonar-scanner \
                        -Dsonar.projectKey=<project-key> \
                        -Dsonar.sources=. \
                        -Dsonar.host.url=https://<sonar-url> \
                        -Dsonar.login=<scanner-user-token>"
                }
            }
        }
        stage("Quality gate") {
            steps {
                timeout(time: 1, unit: 'HOURS') {
                    waitForQualityGate abortPipeline: true
                }
            }
        }
    }
}

In order to generate that <scanner-user-token> I created a new user (scanner-user) inside my SonarQube and generated a token for it.

What I've tried so far

  • adding the <scanner-user-token> as a Global secret text in my Jenkins instance + adding credentialsId in Quality gate step with the credentials id generated for the secret text.
...
        stage("Quality gate") {
            steps {
                timeout(time: 1, unit: 'HOURS') {
                    waitForQualityGate abortPipeline: true,
                    credentialsId: '<global-scanner-user-token-id>',
                }
            }
        }
...
  • Removing the Force Login inside SonarQube.

Other configurations

  • I think the webhook is properly set inside SonarQube since it delivers just fine.

  • SonarQube server is set in Jenkins like this

  • The user I'm using to do the analysis has proper permissions over the project

Versions

  • Jenkins 2.289.1
  • SonarQube 8.9.1
  • SonarScanner 4.6.2

Thank you!


Solution

  • I managed to fix the issue like this:

    1. remove the -Dsonar.login from the SonarQube analysis step
           stage('SonarQube analysis') {
                steps {
                    withSonarQubeEnv('SonarQube') { 
                        sh "sonar-scanner \
                            -Dsonar.projectKey=<project-key> \
                            -Dsonar.sources=. \
                            -Dsonar.host.url=https://<sonar-url> "
                    }
                }
            }
    
    1. create in Jenkins a global secret text using the
    2. Inside Jenkins go to **Configure System -> SonarQube servers ** and set the Server authentication token, the global secret set at point 2. Also check Environment variables