ods-jenkins-shared-library icon indicating copy to clipboard operation
ods-jenkins-shared-library copied to clipboard

SonarQube integration with Git repository (PR decoration)

Open BraisVQ opened this issue 4 years ago • 35 comments

This feature will make the result of Sonarqube scan for the Pull request made in a repository available directly from the Git repository, without the necessity to access SonarQube (except if you want to see the full report of the scan).

Sonar Documentation about PR decoration: https://docs.sonarqube.org/8.2/analysis/pr-decoration/

Requirements:

  • Configure ALM integration in Sonarqube for a Git repository (Bitbucket, Github, Gitlab...)

image

  • Configure the Sonar project to make use of PR decoration

image

Right now this requirements are needed to be done manually, even the 2º needs to be done for each project in SonarQube but the Shared library should be able to do this for SonarQube editions Developer and above when each project in Sonarqube is created

When this configuration is done and we create a PR in our Git repositories it will look like this: image

We will be even able to see the warnings from Sonarqube directly in the Diff in the PR: image

@metmajer @felipecruz91 @borja44

BraisVQ avatar Jun 11 '21 11:06 BraisVQ

Hi, isn't that exactly what's already been implemented? :) See https://github.com/opendevstack/ods-jenkins-shared-library/blob/master/src/org/ods/services/SonarQubeService.groovy#L36-L46.

Note that the one limitation with this is that the PR needs to exist at the time the pipeline runs. That requires the developers to create the PR before pushing. To circumvent that issue we'd need to run pipelines on pr:opened events as well ...

michaelsauter avatar Jun 11 '21 13:06 michaelsauter

@michaelsauter - For us the PR decoration in our Bitbucket repositories is not happening unless we follow the requirements I mention above.

BraisVQ avatar Jun 11 '21 14:06 BraisVQ

@michaelsauter I prefer the way we are integrating Aqua with Bitbucket: each commit on a component is decorated with SonarQube scan results. We should follow the same approach here. @braisvq1996 the decoration of a PR itself is absolutely secondary since a commit is uniquely identified in Git and a decoration of a commit that is part of a PR works equally well.

@renedupont and @michaelsauter since you were involved in the SonarQube integration, do you have any feedback on creating a similar approach? Do you have cycles to support us while we finish the Aqua integration?

FYI @s2oBCN @jorge-romero @hrcornejo @borja44 @segator

metmajer avatar Jun 13 '21 08:06 metmajer

I can only repeat that all that is mentioned above is already implemented. The Aqua integration (attaching a code report) is actually based on the SonarQube integration: I tried to figure out how SonarQube is doing it, found out about code insights, and suggested to do the same for Aqua.

The code snippet I linked above sets all the parameters which can be seen in the screenshot. When we released 3.x the code insight and the PR integration worked out of the box with no config in SQ necessary.

If this does not work right now I suggest to investigate ... maybe something changed in a newer SQ version?

michaelsauter avatar Jun 14 '21 06:06 michaelsauter

AFAIK this is the issue in that Michael implemented this in the past: https://github.com/opendevstack/ods-jenkins-shared-library/issues/174

renedupont avatar Jun 14 '21 07:06 renedupont

@borja44 I had specifically mentioned that we want to see the use of the existing integration into ODS, which was recently fixed via https://github.com/opendevstack/ods-core/issues/966.

@braisvq1996 the screenshots you show depict an integration between the SonarQube server and Bitbucket, which would be an alternative to the ODS integration.

metmajer avatar Jun 14 '21 08:06 metmajer

@renedupont - can you provide screenshots (bitbucket PR) how this currently looks like?

clemensutschig avatar Jun 14 '21 09:06 clemensutschig

@braisvq1996 - can you share your jenkinsfile setup (and SQ scan stage config)?

clemensutschig avatar Jun 14 '21 09:06 clemensutschig

OK some googling revealed https://community.sonarsource.com/t/bitbucket-server-pr-decorator-fails-to-use-scanner-properties/17217. Unfortunately it does not say which version this is. But I guess right now that in 7.9 (LTS) it worked but in 8.2 it does not work anymore. Now the question is if we can get it to work by providing a global config (Bitbucket Server URL and token) and then selecting that one from the scanner invocation.

michaelsauter avatar Jun 14 '21 10:06 michaelsauter

@michaelsauter - there is an interesting comment:

Either by updating to the SQ 8.2 and creating your project from the UI by selecting a BitBucket Server or by calling the webAPI api/alm_integrations/import_bitbucketserver_project

maybe we can call the API during quickstarter provisioning=?

clemensutschig avatar Jun 14 '21 10:06 clemensutschig

This is the error we get in SonarQube when trying PR decoration without the configuration mentioned at the start of the issue:

Pull request decoration did not happen. Configuration missing to decorate the Bitbucket Server pull request: BitbucketServerPrConfiguration{serverUrl=null, project='alphatest2', repository='alphatest2-pythontest', id=1, headSha='ZZZZZZZZZZZZZZZZZZZZZZZZ', token=null}

BraisVQ avatar Jun 14 '21 10:06 BraisVQ

I talked with @michaelsauter about this .. the sq wide setting we could do during the setup of sq .. and project setting needs to happen either in the quickstarter or component pipeline

as admin (during SQ setup) -> POST api/alm_settings/create_bitbucket

and later (from quickstarter / component) -> POST api/alm_settings/set_bitbucket_binding

this has ONE big catch (the bitbucket access token needs to be from a user with GLOBAL / all repos! write rights ... )

clemensutschig avatar Jun 14 '21 12:06 clemensutschig

@clemensutschig The Bitbucket Code Insight feature used for the aqua integration consists basically just of a link to the report on the aqua server: pic

renedupont avatar Jun 14 '21 13:06 renedupont

An update, it seems that the SonarQube token does not have enought rights to set the PR decoration into the project with the api call mentioned by @clemensutschig :

{"errors":[{"msg":"Insufficient privileges"}]}sh-4.2$

If we try with the admin account it does work @michaelsauter

BraisVQ avatar Jun 15 '21 15:06 BraisVQ

@braisvq1996 which permissions were you using before?

metmajer avatar Jun 15 '21 15:06 metmajer

We need to be admin of the Sonarqube Project we want to edit:

Bind a Bitbucket ALM instance to a project. If the project was already bound to a previous Bitbucket ALM instance, the binding will be updated to the new one. Requires the 'Administer' permission on the project

@metmajer , before I was using the admin account of SonarQube

BraisVQ avatar Jun 15 '21 15:06 BraisVQ

it will be nice if we can update prov-app so instead of calling to specific user jenkins project is calling to jenkins master(there we can have admin accounts) then we apply all the needed actions like create sonarQ project, configure ALM and any high administrative task, afterward we call to specific jenkins project as we are doing now. This should be easy to implement playing with webhook proxy calls. @metmajer what do you think? this will fix the issue and is a solution for any other processes that require admin accesses for component provisioning.

segator avatar Jun 15 '21 16:06 segator

@segator, One thing to take into account if we do it is that the PVC for Jenkins-master will be filled up quickly as there would be more Pipelines stored there

BraisVQ avatar Jun 15 '21 16:06 BraisVQ

@metmajer @clemensutschig @michaelsauter

Another option could be to use this api call: POST api/alm_integrations/import_bitbucketserver_project https://next.sonarqube.com/sonarqube/web_api/api/alm_integrations/import_bitbucketserver_project?internal=true&query=import_bitbucketserver_project

This will import the project from Bitbucket and configure PR decoration for the project. It only needs 'Create Project' permissions so the SonarQube token should be able to do it

BraisVQ avatar Jun 16 '21 13:06 BraisVQ

@braisvq1996 @michaelsauter @clemensutschig @segator we cannot go live with ODS 4.x in July without an automated solution. has someone evaluated the most simple and effective solution for an implementation or is this still not clear?

metmajer avatar Jun 24 '21 10:06 metmajer

the bitbucket project is created from the admin jenkins in the ods namespace - so maybe your idea (@braisvq1996 could work).. BUT .. what rights are needed, for bitbuckets project we have rights (As we create it there) - but what else?

and secondly - what happens if repos are added (via quickstarters from the specific project jenkins)..

I just checked the apidoc for import ...

<html>
<body>
<!--StartFragment-->

repositorySlugrequired | BitbucketServer repository slug | Maximum length200
-- | -- | --


<!--EndFragment-->
</body>
</html>
```- so this only works from the project's jenkins ... did you try to run this with the sq token ?

clemensutschig avatar Jun 24 '21 12:06 clemensutschig

so here is my idea: take the token out of the project and also the secret data - and see if you can call the API 🗡️

clemensutschig avatar Jun 24 '21 12:06 clemensutschig

An update, it seems that the SonarQube token does not have enought rights to set the PR decoration into the project with the api call mentioned by @clemensutschig :

{"errors":[{"msg":"Insufficient privileges"}]}sh-4.2$

If we try with the admin account it does work @michaelsauter

what account are you talking about ? also which API do you use here ... ? see my comment above and lets to to get it to work this way :)

clemensutschig avatar Jun 24 '21 12:06 clemensutschig

@renedupont and I tried ...

a) ONE bitbucket integration per SQ instance (that means you need a "super user with write everwhere :(" b) only then you can call import .. (with u/pw)

clemensutschig avatar Jun 24 '21 13:06 clemensutschig

@clemensutschig
One of the api call I tried is POST api/alm_settings/set_bitbucket_binding with the SonarQube token we have in all ODS projects. But it does not have enought rights, it needs Administer level permission: https://next.sonarqube.com/sonarqube/web_api/api/alm_settings/set_bitbucket_binding?query=api%2Falm_settings%2Fset_bitbucket_binding

BraisVQ avatar Jun 24 '21 14:06 BraisVQ

indeed - and it needs a global write BB user :(

clemensutschig avatar Jun 24 '21 14:06 clemensutschig

Also I have been trying to use the api call I last mentioned POST api/alm_integrations/import_bitbucketserver_project But in our DEV environment It seems that the connection between SonarQube and Bitbucket is blocked somewhere so I have not been able to test it yet

BraisVQ avatar Jun 24 '21 14:06 BraisVQ

ha @renedupont found out that on enterprise edition you can create multiple bb integrations (which could mean for us to create one per edp project) from ods' jenkins - the problem we have is the SQ token in each project has no username /pw which you would need to auth for the binding

clemensutschig avatar Jun 24 '21 15:06 clemensutschig

@clemensutschig it is posible, but if we go for that option it could be possible that we cannot import projects from Bitbucket: https://docs.sonarqube.org/8.2/analysis/pr-decoration/

imagen

BraisVQ avatar Jun 24 '21 16:06 BraisVQ

I have experimented with the idea of doing the pull request decoration ourselves from the shared lib. In this scenario, we would run the SonarQube scan, then query the SQ API for results, and then use this result to attach a code insight to Bitbucket. The advantage of that approach would be that SQ does not need permissions in Bitbucket at all.

The scanner invocation would change from:

sonar-scanner -Dsonar.host.url=https://example.com -Dsonar.auth.token=****** \
  -Dsonar.scm.provider=git -Dsonar.projectKey=michael-sample-app \
  -Dsonar.projectName=michael-sample-app -Dsonar.projectVersion=8f372324 \
  -Dsonar.pullrequest.provider=Bitbucket Server' \
  -Dsonar.pullrequest.bitbucketserver.serverUrl=https://bitbucket.bix-digital.com \
  -Dsonar.pullrequest.bitbucketserver.token.secured=**** \
  -Dsonar.pullrequest.bitbucketserver.project=Michael \
  -Dsonar.pullrequest.bitbucketserver.repository=michael-sample-app \
  -Dsonar.pullrequest.key=4 \
  -Dsonar.pullrequest.branch=feature/pr-analysis-test \
  -Dsonar.pullrequest.base=master

to this:

sonar-scanner -Dsonar.host.url=https://example.com -Dsonar.auth.token=****** \
  -Dsonar.scm.provider=git -Dsonar.projectKey=michael-sample-app \
  -Dsonar.projectName=michael-sample-app -Dsonar.projectVersion=8f372324 \
  -Dsonar.pullrequest.key=4 \
  -Dsonar.pullrequest.branch=feature/pr-analysis-test \
  -Dsonar.pullrequest.base=master

Basically cutting all -Dsonar.pullrequest.bitbucketserver.* parameters.

Once we have this, we can query the SQ API for information. In order to achieve feature parity with the integration provided by SQ we'd need to get comments on source lines changed in the PR. I was not able to find an endpoint that does that. GET api/sources/lines is close (it has line information with e.g. coverage) but it does not have findings per line. More importantly, it is internal and I think we should avoid these - internal APIs may change or be removed without warning. An example response of that endpoint:

{
  "sources": [
    {
      "line": 4,
      "code": "\t<span class=\"s\">\"fmt\"</span>",
      "scmRevision": "",
      "scmAuthor": "",
      "scmDate": "2021-02-26T10:19:20+0000",
      "duplicated": false,
      "isNew": false
    },
    {
      "line": 13,
      "code": "\tfmt.Println(quote.Hello())",
      "scmRevision": "",
      "scmAuthor": "",
      "scmDate": "2021-02-26T10:19:20+0000",
      "utLineHits": 0,
      "lineHits": 0,
      "duplicated": false,
      "isNew": false
    }
  ]
}

Apart from source code level info, we have a few API endpoints with higher-level info:

One is GET api/measures/component?component=michael-sample-app&pullRequest=4&metricKeys=ncloc,complexity,violations:

{
  "component": {
    "id": "AXpCXju-x_mCpeFyltf6",
    "key": "michael-sample-app",
    "name": "michael-sample-app",
    "qualifier": "TRK",
    "measures": [
      {
        "metric": "violations",
        "value": "0",
        "bestValue": true
      }
    ],
    "pullRequest": "4"
  }
}

Sometimes there are more measures, seems to depend on the state of the repo.

Then we have GET api/components/app?component=michael-sample-app&pullRequest=4:

{
  "key": "michael-sample-app",
  "uuid": "AXpCXju-x_mCpeFyltf6",
  "name": "michael-sample-app",
  "longName": "michael-sample-app",
  "q": "TRK",
  "project": "michael-sample-app",
  "projectName": "michael-sample-app",
  "pullRequest": "4",
  "fav": false,
  "canMarkAsFavorite": true,
  "measures": {
    "coverage": "0.0",
    "duplicationDensity": "0.0",
    "issues": "0.0"
  }
}

Finally, and probably best fitting is GET api/project_pull_requests/list?project=michael-sample-app:

{
  "pullRequests": [
    {
      "key": "4",
      "title": "Jenkinsfile edited online with Bitbucket",
      "branch": "feature/pr-analysis-test",
      "base": "master",
      "status": {
        "qualityGateStatus": "OK",
        "bugs": 0,
        "vulnerabilities": 0,
        "codeSmells": 0
      },
      "analysisDate": "2021-06-25T08:51:45+0000",
      "url": "https://bitbucket.example.com/projects/MICHAEL/repos/michael-sample-app/pull-requests/4",
      "target": "master"
    }
  ]
}

All of these do not require any special permissions and can be run with the auth token in Jenkins. I think the status field of the API response of the last endpoint could be fed into a Bitbucket code insight to at least get high-level feedback and a link to the detailed SQ report.

Thoughts?

michaelsauter avatar Jun 25 '21 10:06 michaelsauter