Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add plugin sonar #1089

Merged
merged 1 commit into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions cmd/plugin/sonarqube/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"github.com/devstream-io/devstream/internal/pkg/plugin/sonarqube"
"github.com/devstream-io/devstream/pkg/util/log"
)

// NAME is the name of this DevStream plugin.
const NAME = "sonarqube"

// Plugin is the type used by DevStream core. It's a string.
type Plugin string

// Create implements the create of sonar.
func (p Plugin) Create(options map[string]interface{}) (map[string]interface{}, error) {
return sonarqube.Create(options)
}

// Update implements the update of sonar.
func (p Plugin) Update(options map[string]interface{}) (map[string]interface{}, error) {
return sonarqube.Update(options)
}

// Delete implements the delete of sonar.
func (p Plugin) Delete(options map[string]interface{}) (bool, error) {
return sonarqube.Delete(options)
}

// Read implements the read of sonar.
func (p Plugin) Read(options map[string]interface{}) (map[string]interface{}, error) {
return sonarqube.Read(options)
}

// DevStreamPlugin is the exported variable used by the DevStream core.
var DevStreamPlugin Plugin

func main() {
log.Infof("%T: %s is a plugin for DevStream. Use it with DevStream.\n", DevStreamPlugin, NAME)
}
9 changes: 9 additions & 0 deletions docs/plugins/sonarqube.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# sonarqube plugin

TODO(jiafeng meng): I will add this document later.

## Usage

``` yaml
--8<-- "sonarqube.yaml"
```
111 changes: 111 additions & 0 deletions docs/plugins/sonarqube.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# sonarqube 插件

`sonarqube` 插件用于部署、管理 [SonarQube](https://www.sonarqube.org/) 应用。

## 1. 前置要求

- 有一个可用的 Kubernetes 集群,版本 1.19+。
- 运行 Sonarqube 小规模服务至少需要 2GB 的 RAM 内存。
- Sonarqube 官方镜像目前只支持 linux/amd64 架构。
- 更多硬件配置可参考[官方网站](https://docs.sonarqube.org/latest/requirements/hardware-recommendations/)。

## 2、部署架构

Sonarqube 内部会使用 Elastcisearch 来做搜索的索引,所以生产环境中需要通过挂载目录的方式持久化数据。
另外 Sonarqube 也需要一个外部数据库来存储数据,目前支持 `PostgreSQL`,`Oracle`,`Microsoft SQL Sever`,默认使用 `PostgreSQL`。

## 3、开始部署

下文将介绍如何配置 `sonarqube` 插件,完成 Sonarqube 应用的部署。

### 3.1、默认配置

`sonarqube` 插件的配置项多数都有默认值,具体默认值信息如下表:

| 配置项 | 默认值 | 描述 |
|-------------------| ---- | ---- |
| chart.chartName | sonarqube/sonarqube | helm chart 包名称 |
| chart.timeout | 20m | helm install 的超时时间 |
| chart.upgradeCRDs | true | 是否更新 CRDs(如果有) |
| chart.releaseName | sonarqube | helm 发布名称 |
| chart.wait | true | 是否等待部署完成 |
| chart.namespace | sonarqube | 部署的命名空间 |
| repo.url | https://SonarSource.github.io/helm-chart-sonarqube| helm 仓库地址 |
| repo.name | sonarqube | helm 仓库名 |

因此完整的配置文件应该是这样:

```yaml
--8<-- "sonarqube.yaml"
```

### 3.2、测试环境

在测试环境中可以使用如下配置:

```yaml
tools:
- name: harbor
instanceID: default
dependsOn: [ ]
options:
chart:
valuesYaml: |
prometheusExporter:
enabled: false
```

在该配置下:
- sonarqube 存储使用集群默认的 `StorageClass`。
- 默认使用 `PostgreSQL` 数据库来存储数据,使用集群默认的 `StorageClass`。
- 默认使用 `NodePort` 对外暴露 9000 端口。

### 3.3、生产环境

#### 3.3.1、证书配置

- 使用已有证书
1. 在集群中创建 `Secret` 保存证书信息。
2. 在 `valuesYaml` 配置项中增加如下证书配置。

```yaml
valuesYaml: |
tls:
# secret 名称
- secretName: chart-example-tls
hosts:
# 证书对应的域名
- chart-example.local
```

#### 3.3.2、存储配置

- 数据库配置(以 PostgreSQL 为例)
1. 在外部配置高可用数据库。
2. 在 `valuesYaml` 配置项中增加配置:

```yaml
valuesYaml: |
postgresql:
enabled: false
jdbcOverwrite:
enabled: true
# PostgreSQL 数据库连接配置
jdbcUrl: "jdbc:postgresql://myPostgress/myDatabase?socketTimeout=1500"
jdbcUsername: "sonarUser"
jdbcPassword: "sonarPass"
```

- SonarQube 存储配置
1. 在集群中创建需要的 `StorageClass`。
2. 在 `valuesYaml` 配置项中增加配置:

```yaml
valuesYaml: |
persistence:
enabled: true
# 使用集群中创建的 storageclass 名称
storageclass: prod-storageclass
# 使用的磁盘大小
size: 20g
```
1 change: 0 additions & 1 deletion internal/pkg/plugin/argocd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,4 @@ func Delete(options map[string]interface{}) (bool, error) {

// 2. return ture if all process success
return true, nil

}
28 changes: 28 additions & 0 deletions internal/pkg/plugin/sonarqube/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package sonarqube

import (
"github.com/devstream-io/devstream/internal/pkg/plugininstaller"
"github.com/devstream-io/devstream/internal/pkg/plugininstaller/helm"
"github.com/devstream-io/devstream/pkg/util/log"
)

func Create(options map[string]interface{}) (map[string]interface{}, error) {
// Initialize Operator with Operations
operator := &plugininstaller.Operator{
PreExecuteOperations: plugininstaller.PreExecuteOperations{
helm.SetDefaultConfig(&defaultHelmConfig),
helm.Validate,
},
ExecuteOperations: helm.DefaultCreateOperations,
TerminateOperations: helm.DefaultTerminateOperations,
steinliber marked this conversation as resolved.
Show resolved Hide resolved
GetStateOperation: helm.GetPluginAllState,
}

// Execute all Operations in Operator
status, err := operator.Execute(plugininstaller.RawOptions(options))
if err != nil {
return nil, err
}
log.Debugf("Return map: %v", status)
return status, nil
}
24 changes: 24 additions & 0 deletions internal/pkg/plugin/sonarqube/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package sonarqube

import (
"github.com/devstream-io/devstream/internal/pkg/plugininstaller"
"github.com/devstream-io/devstream/internal/pkg/plugininstaller/helm"
)

func Delete(options map[string]interface{}) (bool, error) {
// Initialize Operator with Operations
operator := &plugininstaller.Operator{
PreExecuteOperations: plugininstaller.PreExecuteOperations{
helm.SetDefaultConfig(&defaultHelmConfig),
helm.Validate,
},
ExecuteOperations: helm.DefaultDeleteOperations,
}
_, err := operator.Execute(plugininstaller.RawOptions(options))
if err != nil {
return false, err
}

// 2. return ture if all process success
return true, nil
}
26 changes: 26 additions & 0 deletions internal/pkg/plugin/sonarqube/read.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package sonarqube

import (
"github.com/devstream-io/devstream/internal/pkg/plugininstaller"
"github.com/devstream-io/devstream/internal/pkg/plugininstaller/helm"
"github.com/devstream-io/devstream/pkg/util/log"
)

func Read(options map[string]interface{}) (map[string]interface{}, error) {
// Initialize Operator with Operations
operator := &plugininstaller.Operator{
PreExecuteOperations: plugininstaller.PreExecuteOperations{
helm.SetDefaultConfig(&defaultHelmConfig),
helm.Validate,
},
GetStateOperation: helm.GetPluginAllState,
}

// 2. get plugin status
status, err := operator.Execute(plugininstaller.RawOptions(options))
if err != nil {
return nil, err
}
log.Debugf("Return map: %v", status)
return status, nil
}
22 changes: 22 additions & 0 deletions internal/pkg/plugin/sonarqube/sonar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package sonarqube

import (
"github.com/devstream-io/devstream/internal/pkg/plugininstaller/helm"
helmCommon "github.com/devstream-io/devstream/pkg/util/helm"
"github.com/devstream-io/devstream/pkg/util/types"
)

var defaultHelmConfig = helm.Options{
Chart: helmCommon.Chart{
ChartName: "sonarqube/sonarqube",
Timeout: "20m",
Wait: types.Bool(true),
UpgradeCRDs: types.Bool(true),
ReleaseName: "sonarqube",
Namespace: "sonarqube",
},
Repo: helmCommon.Repo{
URL: "https://SonarSource.github.io/helm-chart-sonarqube",
Name: "sonarqube",
},
}
27 changes: 27 additions & 0 deletions internal/pkg/plugin/sonarqube/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package sonarqube

import (
"github.com/devstream-io/devstream/internal/pkg/plugininstaller"
"github.com/devstream-io/devstream/internal/pkg/plugininstaller/helm"
"github.com/devstream-io/devstream/pkg/util/log"
)

func Update(options map[string]interface{}) (map[string]interface{}, error) {
// Initialize Operator with Operations
operator := &plugininstaller.Operator{
PreExecuteOperations: plugininstaller.PreExecuteOperations{
helm.SetDefaultConfig(&defaultHelmConfig),
helm.Validate,
},
ExecuteOperations: helm.DefaultCreateOperations,
GetStateOperation: helm.GetPluginAllState,
}

// Execute all Operations in Operator
status, err := operator.Execute(plugininstaller.RawOptions(options))
if err != nil {
return nil, err
}
log.Debugf("Return map: %v", status)
return status, nil
}
4 changes: 4 additions & 0 deletions internal/pkg/show/config/embed_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions internal/pkg/show/config/plugins/sonarqube.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
tools:
# name of the tool
- name: sonarqube
# id of the tool instance
instanceID: default
# format: name.instanceID; If specified, dtm will make sure the dependency is applied first before handling this tool.
dependsOn: [ ]
# options for the plugin
options:
# Helm repo information, this section is optional
repo:
# name of the Helm repo
name: sonarqube
# url of the Helm repo
url: https://SonarSource.github.io/helm-chart-sonarqube
# Helm chart information
chart:
# name of the chart
chartName: sonarqube/sonarqube
# release name of the chart
releaseName: sonarqube
# k8s namespace where SonarQube will be installed
namespace: sonarqube
# whether to wait for the release to be deployed or not
wait: true
# the time to wait for any individual Kubernetes operation (like Jobs for hooks). This defaults to 5m0s
timeout: 20m
# whether to perform a CRD upgrade during installation
upgradeCRDs: true
# custom configuration (Optional). You can refer to [SonarQube values.yaml](https://github.com/SonarSource/helm-chart-sonarqube/blob/master/charts/sonarqube/values.yaml)
valuesYaml: |