|
| 1 | +# SonarQube Connector |
| 2 | + |
| 3 | +## 概述 |
| 4 | + |
| 5 | +用户可以通过 SonarQube Connector 在 Kubernetes 集群中以 SecretLess 的形式完成对 SonarQube 的一些操作。 |
| 6 | + |
| 7 | +## 核心能力 |
| 8 | + |
| 9 | +### 功能需求清单 |
| 10 | + |
| 11 | +1. 用户能够通过 API, UI 的形式,在集群中接入 SonarQube,从而在 K8S Workload (Job, Tekton Pipeline 等) 中, 将分析结果推送到 SonarQube 服务器。 |
| 12 | +2. 用户能够通过 API, UI 的形式,在集群中接入 SonarQube,从而在 K8S Workload 中, 调用 SonarQube 的 REST API 完成代码质量相关操作。 |
| 13 | + |
| 14 | +## 功能设计 |
| 15 | + |
| 16 | +### 前提条件 |
| 17 | + |
| 18 | +- 部署 Connectors-Operator |
| 19 | +- 安装 ConnectorsCore 和 ConnectorsSonarQube 组件. |
| 20 | + |
| 21 | +## 创建 SonarQube Connector |
| 22 | + |
| 23 | +按照以下操作流程,完成 SonarQube Connector 的创建,并且 SonarQube Connector 的状态为 Ready 状态。 |
| 24 | + |
| 25 | +### UI 创建 SonarQube Connector |
| 26 | + |
| 27 | +前提:需要在对应集群安装 connectors-operator, connectors-core 以及 connectors-sonarqube 组件。 |
| 28 | + |
| 29 | +1. 点击 创建 Connector 按钮, 选择 SonarQube 类型。 |
| 30 | +2. 输入 SonarQube 的地址, 例如 `https://sonarqube.example.com` |
| 31 | +3. 输入 SonarQube 的凭据, 可选。 |
| 32 | + - 凭据支持 Token 认证。 |
| 33 | + - 能够正常完成 Token 的校验 |
| 34 | +4. 点击提交,完成创建。 |
| 35 | + |
| 36 | +### Yaml 创建 SonarQube Connector |
| 37 | + |
| 38 | +通过以下 yaml 完成创建: |
| 39 | + |
| 40 | +```yaml |
| 41 | +--- |
| 42 | +apiVersion: v1 |
| 43 | +data: |
| 44 | + token: <base64 string> |
| 45 | +kind: Secret |
| 46 | +metadata: |
| 47 | + name: sonarqube-secret |
| 48 | +type: connectors.cpaas.io/bearer-token |
| 49 | +--- |
| 50 | +apiVersion: operator.connectors.alauda.io/v1alpha1 |
| 51 | +kind: Connector |
| 52 | +metadata: |
| 53 | + name: sonarqube-connector |
| 54 | +spec: |
| 55 | + connectorClassName: sonarqube |
| 56 | + address: https://sonarqube.example.com |
| 57 | + auth: |
| 58 | + name: tokenAuth |
| 59 | + secretRef: |
| 60 | + name: sonarqube-secret |
| 61 | +``` |
| 62 | +
|
| 63 | +### User Story 1: 用户能够通过 API, UI 的形式,在集群中接入 SonarQube,从而在 K8S Workload (Job, Tekton Pipeline 等) 中, 将分析结果推送到 SonarQube 服务器 |
| 64 | +
|
| 65 | +描述:作为平台用户,我希望以无密钥(SecretLess)的方式在 Kubernetes 中将sonar 分析结果上传到 SonarQube 服务器,从而避免在工作负载中直接暴露 SonarQube 凭据。 |
| 66 | +
|
| 67 | +#### 前置条件 |
| 68 | +
|
| 69 | +- 已安装 Connectors Operator、ConnectorsCore 与 ConnectorsSonarQube 组件。 |
| 70 | +- 已具备可用的 SonarQube 地址与凭据(若目标仓库匿名可读,可不配置凭据)。 |
| 71 | +
|
| 72 | +#### 操作步骤 |
| 73 | +
|
| 74 | +1. 创建命名空间(示例): |
| 75 | +
|
| 76 | + ```bash |
| 77 | + kubectl create ns connectors-sonarqube-demo |
| 78 | + ``` |
| 79 | + |
| 80 | +2. (可选)创建凭据与 Connector(示例): |
| 81 | + |
| 82 | + ```yaml |
| 83 | + apiVersion: v1 |
| 84 | + kind: Secret |
| 85 | + metadata: |
| 86 | + name: sonarqube-secret |
| 87 | + type: connectors.cpaas.io/bearer-token |
| 88 | + stringData: |
| 89 | + token: "<YOUR_SONARQUBE_TOKEN>" |
| 90 | + --- |
| 91 | + apiVersion: connectors.alauda.io/v1alpha1 |
| 92 | + kind: Connector |
| 93 | + metadata: |
| 94 | + name: sonarqube-connector |
| 95 | + spec: |
| 96 | + connectorClassName: sonarqube |
| 97 | + address: https://sonarqube.example.com |
| 98 | + auth: |
| 99 | + name: tokenAuth |
| 100 | + secretRef: |
| 101 | + name: sonarqube-secret |
| 102 | + ``` |
| 103 | + |
| 104 | +3. 创建执行 sonarscanner 的 Job,并通过 CSI 挂载 `sonar-scanner.properties` 配置: |
| 105 | + |
| 106 | + ```yaml |
| 107 | + apiVersion: batch/v1 |
| 108 | + kind: Job |
| 109 | + metadata: |
| 110 | + name: sonarqube-scanner |
| 111 | + spec: |
| 112 | + backoffLimit: 0 |
| 113 | + template: |
| 114 | + spec: |
| 115 | + restartPolicy: Never |
| 116 | + containers: |
| 117 | + - name: sonarqube-scanner |
| 118 | + image: sonarsource/sonar-scanner-cli:latest |
| 119 | + command: ["sh","-c"] |
| 120 | + args: |
| 121 | + - | |
| 122 | + cd /root/src |
| 123 | + sonar-scanner -X \ |
| 124 | + -Dsonar.projectKey=test-project \ |
| 125 | + -Dsonar.sources=. |
| 126 | + volumeMounts: |
| 127 | + - name: sonar-scanner-properties |
| 128 | + mountPath: /root/.sonar/sonar-scanner.properties |
| 129 | + subPath: sonar-scanner.properties |
| 130 | + volumes: |
| 131 | + - name: sonar-scanner-properties |
| 132 | + csi: |
| 133 | + readOnly: true |
| 134 | + driver: connectors-csi |
| 135 | + volumeAttributes: |
| 136 | + connector.name: "sonarqube-connector" |
| 137 | + configuration.names: "sonar-scanner" |
| 138 | + ``` |
| 139 | + |
| 140 | +#### 关键点说明 |
| 141 | + |
| 142 | +- 通过 `connectors-csi` 驱动挂载 `sonar-scanner.properties`,内容由 SonarQube ConnectorClass 模板生成,其中已配置代理与认证参数,无需在容器内直接配置凭据。 |
| 143 | + |
| 144 | +#### 验收标准 |
| 145 | + |
| 146 | +- `Connector` 资源 `READY=True`,`status.proxy.httpAddress` 已就绪。 |
| 147 | +- `Job` 成功完成,能够在 Sonarqube 查询到上传的分析结果。 |
| 148 | + |
| 149 | +### User Story 2: 用户能够通过 API, UI 的形式,在集群中接入 SonarQube,从而在 K8S Workload 中, 调用 SonarQube 的 REST API 完成代码质量相关操作 |
| 150 | + |
| 151 | +#### 前置条件 |
| 152 | + |
| 153 | +参考 User Story 1 的前置条件 |
| 154 | + |
| 155 | +#### 操作步骤 |
| 156 | + |
| 157 | +参考 User Story 1 的操作步骤,创建 Job 时,修改容器命令为调用 SonarQube REST API,例如查询项目列表: |
| 158 | + |
| 159 | +```yaml |
| 160 | + ```yaml |
| 161 | + apiVersion: batch/v1 |
| 162 | + kind: Job |
| 163 | + metadata: |
| 164 | + name: sonarqube-scanner |
| 165 | + spec: |
| 166 | + backoffLimit: 0 |
| 167 | + template: |
| 168 | + spec: |
| 169 | + restartPolicy: Never |
| 170 | + containers: |
| 171 | + - name: sonarqube-scanner |
| 172 | + image: sonarsource/sonar-scanner-cli:latest |
| 173 | + command: ["sh","-c"] |
| 174 | + args: |
| 175 | + - | |
| 176 | + source /root/.sonar/.env |
| 177 | + curl -X GET http://sonarqube.com/api/projects/search" |
| 178 | + { |
| 179 | + "paging": { |
| 180 | + "pageIndex": 1, |
| 181 | + "pageSize": 100, |
| 182 | + "total": 2 |
| 183 | + }, |
| 184 | + "components": [ |
| 185 | + { |
| 186 | + "key": "test-local", |
| 187 | + "name": "test-local", |
| 188 | + "qualifier": "TRK", |
| 189 | + "visibility": "public", |
| 190 | + "lastAnalysisDate": "2025-12-22T11:35:04+0000", |
| 191 | + "managed": false |
| 192 | + }, |
| 193 | + { |
| 194 | + "key": "test-project", |
| 195 | + "name": "Test Project", |
| 196 | + "qualifier": "TRK", |
| 197 | + "visibility": "public", |
| 198 | + "lastAnalysisDate": "2025-12-22T11:38:07+0000", |
| 199 | + "managed": false |
| 200 | + } |
| 201 | + ] |
| 202 | + } |
| 203 | + volumeMounts: |
| 204 | + - name: sonar-scanner-properties |
| 205 | + mountPath: /root/.sonar/sonar-scanner.properties |
| 206 | + subPath: sonar-scanner.properties |
| 207 | + volumes: |
| 208 | + - name: sonar-scanner-properties |
| 209 | + csi: |
| 210 | + readOnly: true |
| 211 | + driver: connectors-csi |
| 212 | + volumeAttributes: |
| 213 | + connector.name: "sonarqube-connector" |
| 214 | + configuration.names: "sonar-scanner" |
| 215 | + ``` |
| 216 | +
|
| 217 | +### 非功能需求清单 |
| 218 | +
|
| 219 | +#### 升级需求说明 |
| 220 | +
|
| 221 | +- 系统升级后, ConnectorsSonarQube 组件能够平滑升级 |
| 222 | +- 系统升级后,用户存量的 SonarQube Connector 资源状态正常,使用存量 SonarQube Connector 创建的 K8S Workload 能够正常运行。 |
| 223 | +
|
| 224 | +#### 安全需求说明 |
| 225 | +
|
| 226 | +- 用户进入到运行的 k8s workload 中,无法获取原始的 SonarQube 凭据。 |
| 227 | +- k8s workload 中的中间凭据,应具有有效期,在有效期过期后,该凭据无法使用。 |
| 228 | +- 在 k8s workload 中,用户应当仅能挂载自己有权限访问的 Connector. |
| 229 | +
|
| 230 | +#### 兼容性需求说明 |
| 231 | +
|
| 232 | +- 参考升级需求说明,存量的 SonarQube Connector 资源状态以及使用正常,用户无需做资源变更。 |
| 233 | +
|
0 commit comments