Sonarqube 和 Sonar-scanner的安装和配置

SonarQube 简介

所谓sonarqube 就是代码质量扫描工具。
官网:
https://www.sonarsource.com/sonarqube/

在个人开发学习中用处不大, 我草, 我的代码质量这么高需要这玩意?

但是在公司项目中, 这个可是必须的, 你永远都不知道你的队友写了什么进git 仓库



SonarScanner 简介

至于SanarScanner 就是1个本地工具, 用于把你的代码push 到SonarQube server 用于分析
参考:
https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner/



搭建本地 SonarQube 方案

由于SonarQube 企业版是收费的, GCP上也没有SonarQube 的托管服务。
所以建议还是自己基于SonarQube 社区版搭建1个服务



准备1个有docker 环境的linux server

这个例子是1个WSL2 server

gateman@DESKTOP-UIU9RFJ:~$ neofetch
            .-/+oossssoo+/-.               gateman@DESKTOP-UIU9RFJ 
        `:+ssssssssssssssssss+:`           ----------------------- 
      -+ssssssssssssssssssyyssss+-         OS: Ubuntu 20.04.2 LTS on Windows 10 x86_64 
    .ossssssssssssssssssdMMMNysssso.       Kernel: 5.10.16.3-microsoft-standard-WSL2 
   /ssssssssssshdmmNNmmyNMMMMhssssss/      Uptime: 24 days, 11 hours, 47 mins 
  +ssssssssshmydMMMMMMMNddddyssssssss+     Packages: 807 (dpkg) 
 /sssssssshNMMMyhhyyyyhmNMMMNhssssssss/    Shell: bash 5.0.17 
.ssssssssdMMMNhsssssssssshNMMMdssssssss.   Terminal: /dev/pts/3 
+sssshhhyNMMNyssssssssssssyNMMMysssssss+   CPU: Intel i5-7260U (4) @ 2.207GHz 
ossyNMMMNyMMhsssssssssssssshmmmhssssssso   Memory: 5290MiB / 12689MiB 
ossyNMMMNyMMhsssssssssssssshmmmhssssssso
+sssshhhyNMMNyssssssssssssyNMMMysssssss+                           
.ssssssssdMMMNhsssssssssshNMMMdssssssss.                           
 /sssssssshNMMMyhhyyyyhdNMMMNhssssssss/
  +sssssssssdmydMMMMMMMMddddyssssssss+
   /ssssssssssshdmNNNNmyNMMMMhssssss/
    .ossssssssssssssssssdMMMNysssso.
      -+sssssssssssssssssyyyssss+-
        `:+ssssssssssssssssss+:`
            .-/+oossssoo+/-.

gateman@DESKTOP-UIU9RFJ:~$ docker --version
Docker version 24.0.5, build 24.0.5-0ubuntu1~20.04.1



准备1个Dockerfile

FROM sonarqube:10.6-community

ENTRYPOINT ["/opt/sonarqube/docker/entrypoint.sh"]

其实就是基于官网(docker-hub) 镜像构建1个



构建镜像

git pull && docker build -t gateman/sonarqube:1.0.0 .



运行镜像

docker run -p 9000:9000 gateman/sonarqube:1.0.0

把端口9000暴露出来就行



登陆

打开主机的页面
http://10.0.1.223:9000
在这里插入图片描述

第一次输入 admin:admin 就好, 然后马上会让你修改admin 帐号的密码



创建另1个用户

admin 帐号用于配置, 通常我们需要另1个账户分析代码

在这里插入图片描述


生成sonar token

切换到刚才创建账户登陆
生成1个Global Analysis Token 专门用于代码上传
在这里插入图片描述



安装SonarScanner

好了, 到了这一步服务端基本已经配置好
接下来要安装本地安装CLI 上传代码工具 SonarScanne
下载地址:
https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.1.0.4477-linux-x64.zip?_gl=1xwtft4_gcl_auMTM3NDUxMzczNS4xNzI1NjgyMjI1_gaMTQzNzQ0MDQ1Ni4xNzI1NjgyMjI1_ga_9JZ0GZ5TC6*MTcyNTY4MjIyNC4xLjEuMTcyNTY5MTEzMy42MC4wLjA.



解压
gateman@MoreFine-S500:~/Downloads/sonar$ ls
sonar-scanner-cli-6.1.0.4477-linux-x64.zip
gateman@MoreFine-S500:~/Downloads/sonar$ unzip sonar-scanner-cli-6.1.0.4477-linux-x64.zip 

gateman@MoreFine-S500:~/devtools$ mv ~/Downloads/sonar/sonar-scanner-6.1.0.4477-linux-x64/ .



enable 执行文件
vi ~/.bashrc

...
# sonar-scanner
export PATH="/home/gateman/devtools/sonar-scanner-6.1.0.4477-linux-x64/bin:$PATH"
...



利用 SonarScanner 出发扫描

sonar-scanner -Dsonar.host.url=http://10.0.1.223:9000 -Dsonar.projectKey=my:python-common -Dsonar.sources=/home/gateman/projects/python/python_common -Dsonar.login=sqa_acba1803e527317f966735b2ae664fab8b77753f -Dsonar.exclusions=**/venv/**

具体的参数选项:

参数Desc
-Dsonar.projectKey=project_key指定项目在 SonarQube 中的唯一标识。
-Dsonar.projectName=project_name指定项目在 SonarQube 中显示的名称。
-Dsonar.sources=source_directory指定要分析的源代码目录。
-Dsonar.host.url=sonarqube_server_url指定 SonarQube 服务器的 URL 地址。
-Dsonar.login=authentication_token指定用于连接 SonarQube 服务器的认证令牌。
-Dsonar.language=language指定要分析的编程语言。
-Dsonar.sourceEncoding=utf-8指定源代码的编码格式。
-Dsonar.projectVersion=project_version指定项目的版本号。
-Dsonar.branch.name=branch_name指定分析的分支名称。
-Dsonar.exclusions=pattern指定要排除的文件或目录模式。

默认 SonarQube会自动判断你的代码语言
但是最好用 -Dsonar.exclusions 排除掉那些库的代码(例如 venv of Python)



查看report

这时需要等服务器处理几分钟, 就可以从UI 上查看代码分析报告了
在这里插入图片描述





搭建GCP SonarQube 方案

为什么要搭在云上呢

本地方案有几个痛点

  1. sonarqube 使用频率偏少
  2. sonarqube 扫描时很耗cpu 和内存资源
  3. 我大部分CICD 设在GCP上, 无法连接家庭内网的服务器



首先还是准备一台有docker 环境的云主机

gateman@MoreFine-S500:~$ gcloud compute instances list --filter="status=RUNNING"
WARNING: This command is using service account impersonation. All API calls will be executed as [terraform@jason-hsbc.iam.gserviceaccount.com].
NAME                         ZONE            MACHINE_TYPE    PREEMPTIBLE  INTERNAL_IP   EXTERNAL_IP  STATUS
tf-vpc0-subnet0-main-server  europe-west2-c  n2d-standard-4  true         192.168.0.35  34.39.2.90   RUNNING
tf-vpc0-subnet0-mysql0       europe-west2-c  e2-standard-2   true         192.168.0.42               RUNNING
tf-vpc0-subnet0-vm0          europe-west2-c  n2-highmem-4    true         192.168.0.51               RUNNING
       _,met$$$$$gg.          root@tf-vpc0-subnet0-vm0 
    ,g$$$$$$$$$$$$$$$P.       ------------------------ 
  ,g$$P"     """Y$$.".        OS: Debian GNU/Linux 11 (bullseye) x86_64 
 ,$$P'              `$$$.     Host: Google Compute Engine 
',$$P       ,ggs.     `$$b:   Kernel: 5.10.0-32-cloud-amd64 
`d$$'     ,$P"'   .    $$$    Uptime: 9 hours, 43 mins 
 $$P      d$'     ,    $$P    Packages: 505 (dpkg) 
 $$:      $$.   -    ,d$$'    Shell: bash 5.1.4 
 $$;      Y$b._   _,d$P'      CPU: Intel Xeon (4) @ 2.800GHz 
 Y$$.    `.`"Y$$$$P"'         Memory: 2979MiB / 32112MiB 
 `$$b      "-.__
  `Y$$                                                
   `Y$$.                                              
     `$$b.
       `Y$$b.
          `"Y$b._
              `"""



配置terraform 添加1个cloud build trigger

添加1个trigger

# referring https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloudbuild_trigger
resource "google_cloudbuild_trigger" "sonarqube-service-gce-trigger" {
  name = "sonarqube-service-gce-trigger" # could not contains underscore

  location = var.region_id

  # when use github then should use trigger_template
  github {
    name = "sonarqube-server"
    owner = "nvd11"
    push {
      branch = "main"
      invert_regex = false # means trigger on branch
    }
  }

  substitutions = {
    _VM_HOST = "tf-vpc0-subnet0-vm0"
    _APP_ENV = "prod"
  }

  filename = "cloudbuild-gce.yaml"
  # projects/jason-hsbc/serviceAccounts/terraform@jason-hsbc.iam.gserviceaccount.com
  service_account = data.google_service_account.cloudbuild_sa.id 
}



编写cloudbuild-gce.yaml 以部署sonarqube 到某台GCE (google compute engine)

cloudbuild-gce.yaml

steps:

# https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values
- id: build docker image
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/${_APP_NAME}:${_APP_TAG}', '.']

- id: upload docker image to GAR
  name: 'gcr.io/cloud-builders/docker'
  args: [ 'push', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/${_APP_NAME}:${_APP_TAG}']


- id: check and start VM if not running
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: bash
  args:
    - '-c'
    - |
      set -x
      VM_STATUS=$(gcloud compute instances describe ${_VM_HOST} --zone=europe-west2-c --format='value(status)' 2>/dev/null || true)
      if [ "$$VM_STATUS" != "RUNNING" ]; then
        echo "VM ${_VM_HOST} was not running. Starting now..."
        gcloud compute instances start ${_VM_HOST} --zone=europe-west2-c
      else
        echo "VM ${_VM_HOST} is already running."
      fi

# to prepare ssh private key file
- id: deploy image to GCE
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: bash
  args:
    - '-c'
    - |
      whoami
      gcloud auth list
      set -x
      mkdir -p /root/.ssh
      gcloud secrets versions access latest --secret=gateman-private-ssh-key > /root/.ssh/id_rsa
      gcloud secrets versions access latest --secret=gateman-public-ssh-key > /root/.ssh/id_rsa.pub
      chmod 600 /root/.ssh/id_rsa
      chmod 600 /root/.ssh/id_rsa.pub
      gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "whoami" 
      gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "sudo docker container prune -f; sudo docker ps -a"  
      gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "sudo docker stop ${_APP_NAME} && sudo docker rm ${_APP_NAME}" 
      gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "sudo docker pull europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/${_APP_NAME}:${_APP_TAG}"
      gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "sudo docker run -d -p ${_PORT}:${_CONTAINER_PORT} -e APP_ENVIRONMENT=${_APP_ENV} --name ${_APP_NAME} europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/${_APP_NAME}:${_APP_TAG}"
      echo ok

# https://stackoverflow.com/questions/68779751/error-publishing-source-code-from-cloud-build-to-a-bucket-using-triggers
logsBucket: gs://jason-hsbc_cloudbuild/logs/
options: # https://cloud.google.com/cloud-build/docs/build-config#options
  logging: GCS_ONLY # or CLOUD_LOGGING_ONLY https://cloud.google.com/cloud-build/docs/build-config#logging

# to define

substitutions:
  _APP_NAME: sonarqube-server
  _APP_TAG: latest
  _VM_HOST: "tf-vpc0-subnet0-vm0"
  _PORT: "9000"
  _CONTAINER_PORT: "9000"

检查cloudbuild job, 确保部署成功
在这里插入图片描述


在有外网ip的主机上设置nginx 代理

因为安装 sonarqube 的主机 tf-vpc0-subnet0-vm0 并没有外网ip, 家里并不能访问
所以我们需要在有外网ip的主机上设个nginx 代理, 代理到 tf-vpc0-subnet0-vm0:9000

暴力配置:

upstream sonarqube-server {
    server tf-vpc0-subnet0-vm0:9000;
}

server {
    listen 9000;
    server_name www.jp-gvms.cloud;

    location / {
        proxy_pass http://sonarqube-server;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

}

这时可以打开 sonarqube 页面了, 相信你们也可以
http://www.jp-gcp-vms.cloud:9000/
在这里插入图片描述



登陆,修改admin 密码, 创建用户, 生成token

接下来这几步上面已经介绍过, 不再重复



把token 放入google 的secret manager

在这里插入图片描述sqa_2b62011d73270438f1d37ae0cf6acff4d23ea990



为springboot cloud-order service 创建1个cloudbuild trigger 专门用于sonarqube 扫描

好了, 到了上面一步, 其实sonarqube server 配置已经做好

接下来就是使用

首先创建1个cloudbuild job for 需要扫描的service


resource "google_cloudbuild_trigger" "demo_cloud_order-sonarqube-trigger" {
  name = "demo-cloud-order-sonarqube-trigger" # could not contains underscore

  location = var.region_id

  # when use github then should use trigger_template
  github {
    name = "demo_cloud_order"
    owner = "nvd11"
    push {
      branch = ".*"
      # for all branch
       
      invert_regex = false # means trigger on branch
    }
  }

  filename = "cloudbuild-sonarqube.yaml"
  # projects/jason-hsbc/serviceAccounts/terraform@jason-hsbc.iam.gserviceaccount.com
  service_account = data.google_service_account.cloudbuild_sa.id 
}

为springboot cloud-order service 创建1个cloudbuild-sonarqube yaml 用于定义具体出发sonar 扫描步骤

steps:

  # to prepare ssh private key file
  # as the default user of sonarsource/sonar-scanner-cli is scanner-cli, it could not create any subfolder in /workspace
  # that's why we need to change the permission to 777
  - id: prepare ssh private key file
    name: 'ubuntu'
    entrypoint: bash
    args:
      - '-c'
      - |
        set -x
        pwd
        chmod -R 777 .

  - id: trigger sonarqube scanning
    name: 'sonarsource/sonar-scanner-cli'
    entrypoint: '/bin/sh'
    args:
      - '-c'
      - |
        set -x
        whoami
        pwd
        ls -l
        sonar-scanner -Dsonar.projectKey=my:${_APP_NAME}  -Dsonar.host.url=${_SONARQUBE_HOST} -Dsonar.token=$$SONAR_TOKEN -Dsonar.projectKey=my:${_APP_NAME} -Dsonar.sources=. -Dsonar.java.binaries=./test_scripts
    secretEnv:
      - 'SONAR_TOKEN'


logsBucket: gs://jason-hsbc_cloudbuild/logs/
options: # https://cloud.google.com/cloud-build/docs/build-config#options
  logging: GCS_ONLY # or CLOUD_LOGGING_ONLY https://cloud.google.com/cloud-build/docs/build-config#logging

# to define
availableSecrets:
  secretManager:
    - versionName: projects/$PROJECT_ID/secrets/sonarqube-token-gateman/versions/latest
      env: 'SONAR_TOKEN'

substitutions:
  _SONARQUBE_HOST: http://www.jp-gcp-vms.cloud:9000
  _APP_NAME: cloud-order

检查log
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值