|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +# this script will |
| 4 | +# - create a sonarqube server using the default configuration |
| 5 | +# - setup basic things (account, project, token) |
| 6 | +# - start a scan (takes >= 1 hour on mac) |
| 7 | +# - create a report file |
| 8 | +# - shutdown sonarqube server |
| 9 | + |
| 10 | +source scripts/requireCommand.sh |
| 11 | + |
| 12 | +requireCommand curl |
| 13 | +requireCommand docker |
| 14 | +requireCommand jq |
| 15 | + |
| 16 | +# Check for install/updates at https://github.com/SonarSource/sonarqube |
| 17 | + |
| 18 | +sonar_port="9876" |
| 19 | +sonar_host="http://localhost:$sonar_port" |
| 20 | +sonar_project="benchmark" |
| 21 | +sonar_user="admin" |
| 22 | +sonar_default_password="admin" |
| 23 | +sonar_password="password" |
| 24 | + |
| 25 | +echo "Creating temporary SonarQube instance" |
| 26 | + |
| 27 | +docker pull sonarqube |
| 28 | + |
| 29 | +# start local sonarqube |
| 30 | +container_id=$(docker run --rm -d -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p "$sonar_port:9000" sonarqube) |
| 31 | + |
| 32 | +echo "Waiting for instance to come up" |
| 33 | + |
| 34 | +# wait for container to come up |
| 35 | +while [[ "$(curl --connect-timeout 5 --max-time 5 --retry 60 --retry-delay 0 --retry-max-time 120 -s -o /dev/null -w '%{http_code}' "$sonar_host")" != "200" ]]; do |
| 36 | + sleep 3; |
| 37 | +done |
| 38 | + |
| 39 | +# wait for sonarqube to be started |
| 40 | +while [[ "$(curl --silent "$sonar_host/api/system/status" | jq -r '.status')" != "UP" ]]; do |
| 41 | + sleep 3; |
| 42 | +done |
| 43 | + |
| 44 | +echo "Setting up instance" |
| 45 | + |
| 46 | +# change default password |
| 47 | +curl "$sonar_host/api/users/change_password" --silent -u "$sonar_user:$sonar_default_password" -X POST --data-raw "login=$sonar_user&password=$sonar_password&previousPassword=$sonar_default_password" -o /dev/null |
| 48 | + |
| 49 | +# create project |
| 50 | +curl "$sonar_host/api/projects/create" --silent -u "$sonar_user:$sonar_password" -X POST --data-raw "project=$sonar_project&name=$sonar_project" -o /dev/null |
| 51 | + |
| 52 | +# create token |
| 53 | +sonar_token=$(curl "$sonar_host/api/user_tokens/generate" --silent -u "$sonar_user:$sonar_password" -X POST --data-raw "name=$(date)" | jq -r '.token') |
| 54 | + |
| 55 | +echo "Starting scan (might take some time!)" |
| 56 | + |
| 57 | +# run scan (using net=host to be able to connect to localhost sonarqube) |
| 58 | +docker run --env SONAR_SCANNER_OPTS=-Xmx4g --net=host --rm -v ~/.m2:/root/.m2 -v "$(pwd)":"$(pwd)" -w "$(pwd)" sonarsource/sonar-scanner-cli \ |
| 59 | + -Dsonar.java.binaries="target" -Dsonar.projectKey="$sonar_project" -Dsonar.host.url="$sonar_host" -Dsonar.login="$sonar_token" \ |
| 60 | + -Dsonar.sources="src" -Dsonar.exclusions="results/**,scorecard/**,scripts/**,tools/**,VMs/**" |
| 61 | + |
| 62 | +echo "Waiting for SonarQube CE to finish task" |
| 63 | + |
| 64 | +while [[ "$(curl --silent -u "$sonar_token:" "$sonar_host/api/ce/component?component=$sonar_project" | jq -r '.current.status')" != "SUCCESS" ]]; do |
| 65 | + sleep 3; |
| 66 | +done |
| 67 | + |
| 68 | +echo "Generating report..." |
| 69 | + |
| 70 | +benchmark_version=$(scripts/getBenchmarkVersion.sh) |
| 71 | +sonarqube_version=$(curl --silent -u "$sonar_token:" "$sonar_host/api/server/version") |
| 72 | +result_file="results/Benchmark_$benchmark_version-sonarqube-v$sonarqube_version.json" |
| 73 | + |
| 74 | +# SonarQube does not provide a download option so we've to create the result file manually :( |
| 75 | + |
| 76 | +result='{"issues":[], "hotspots": []}' |
| 77 | +rules='[]' |
| 78 | + |
| 79 | +# sonarqube does not allow us to grab more than 10k issues, but most of them are information exposure which is not even |
| 80 | +# considered by benchmark so let's just get all relevant rules and receive results for only those rules |
| 81 | + |
| 82 | +rules_count=$(curl --silent -u "$sonar_token:" "$sonar_host/api/rules/search?p=1&ps=1" | jq -r '.total') |
| 83 | +page=1 |
| 84 | + |
| 85 | +while (((page - 1) * 500 < rules_count)); do |
| 86 | + rules=$(echo "$rules" | jq ". += $(curl --silent -u "$sonar_token:" "$sonar_host/api/rules/search?p=$page&ps=500" | jq '.rules | map( .key ) | map( select(. | contains("java:") ) )')") |
| 87 | + page=$((page+1)) |
| 88 | +done |
| 89 | + |
| 90 | +rules=$(echo "$rules" | jq '. | join(",")' | sed 's/java:S1989,//') |
| 91 | + |
| 92 | +issues_count=$(curl --silent -u "$sonar_token:" "$sonar_host/api/issues/search?p=1&ps=1&types=VULNERABILITY&componentKeys=$sonar_project&rules=$rules" | jq -r '.paging.total') |
| 93 | +page=1 |
| 94 | + |
| 95 | +while (((page - 1) * 500 < issues_count)); do |
| 96 | + issues_page=$(curl --silent -u "$sonar_token:" "$sonar_host/api/issues/search?types=VULNERABILITY&p=$page&ps=500&componentKeys=$sonar_project&rules=$rules" | jq '.issues') |
| 97 | + |
| 98 | + result=$(echo "$result" | jq ".issues += $issues_page") |
| 99 | + page=$((page+1)) |
| 100 | +done |
| 101 | + |
| 102 | +hotspot_count=$(curl --silent -u "$sonar_token:" "$sonar_host/api/hotspots/search?projectKey=benchmark&p=1&ps=1" | jq -r '.paging.total') |
| 103 | +page=1 |
| 104 | + |
| 105 | +while (((page - 1) * 500 < hotspot_count)); do |
| 106 | + result=$(echo "$result" | jq ".hotspots += $(curl --silent -u "$sonar_token:" "$sonar_host/api/hotspots/search?projectKey=$sonar_project&p=$page&ps=500" | jq '.hotspots')") |
| 107 | + page=$((page+1)) |
| 108 | +done |
| 109 | + |
| 110 | +echo "$result" > "$result_file" |
| 111 | + |
| 112 | +echo "Shutting down SonarQube" |
| 113 | + |
| 114 | +docker stop "$container_id" |
0 commit comments