From 4abcf9f61918ad7e5801a2fa3b77ed1de9e87c79 Mon Sep 17 00:00:00 2001 From: Meng JiaFeng Date: Mon, 25 Jul 2022 10:15:08 +0800 Subject: [PATCH 1/3] feat: add artifactory plugin Signed-off-by: Meng JiaFeng --- cmd/plugin/artifactory/main.go | 39 ++++++++++++++++ docs/plugins/artifactory.md | 46 +++++++++++++++++++ docs/plugins/artifactory.zh.md | 45 ++++++++++++++++++ .../pkg/plugin/artifactory/artifactory.go | 5 ++ internal/pkg/plugin/artifactory/create.go | 32 +++++++++++++ internal/pkg/plugin/artifactory/delete.go | 26 +++++++++++ internal/pkg/plugin/artifactory/read.go | 25 ++++++++++ internal/pkg/plugin/artifactory/update.go | 28 +++++++++++ .../pkg/show/config/plugins/artifactory.yaml | 33 +++++++++++++ 9 files changed, 279 insertions(+) create mode 100644 cmd/plugin/artifactory/main.go create mode 100644 docs/plugins/artifactory.md create mode 100644 docs/plugins/artifactory.zh.md create mode 100644 internal/pkg/plugin/artifactory/artifactory.go create mode 100644 internal/pkg/plugin/artifactory/create.go create mode 100644 internal/pkg/plugin/artifactory/delete.go create mode 100644 internal/pkg/plugin/artifactory/read.go create mode 100644 internal/pkg/plugin/artifactory/update.go create mode 100644 internal/pkg/show/config/plugins/artifactory.yaml diff --git a/cmd/plugin/artifactory/main.go b/cmd/plugin/artifactory/main.go new file mode 100644 index 000000000..b46f661db --- /dev/null +++ b/cmd/plugin/artifactory/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "github.com/devstream-io/devstream/internal/pkg/plugin/artifactory" + "github.com/devstream-io/devstream/pkg/util/log" +) + +// NAME is the name of this DevStream plugin. +const NAME = "artifactory" + +// Plugin is the type used by DevStream core. It's a string. +type Plugin string + +// Create implements the create of artifactory. +func (p Plugin) Create(options map[string]interface{}) (map[string]interface{}, error) { + return artifactory.Create(options) +} + +// Update implements the update of artifactory. +func (p Plugin) Update(options map[string]interface{}) (map[string]interface{}, error) { + return artifactory.Update(options) +} + +// Delete implements the delete of artifactory. +func (p Plugin) Delete(options map[string]interface{}) (bool, error) { + return artifactory.Delete(options) +} + +// Read implements the read of artifactory. +func (p Plugin) Read(options map[string]interface{}) (map[string]interface{}, error) { + return artifactory.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) +} diff --git a/docs/plugins/artifactory.md b/docs/plugins/artifactory.md new file mode 100644 index 000000000..d87a2aedd --- /dev/null +++ b/docs/plugins/artifactory.md @@ -0,0 +1,46 @@ +# artifactory Plugin + +This plugin installs [artifactory](https://jfrog.com/artifactory/) in an existing Kubernetes cluster using the Helm chart. + +## Usage + +### Test/Local Dev Environment + +If you want to **test the plugin locally**, The following `values_yaml` configuration can be used + +```yaml +values_yaml: | + artifactory: + service: + type: NodePort + nodePort: 30002 + nginx: + enabled: false +``` + +In this configuration +- Postgresql dependencies are automatically created. +- local disks on machines in the cluster are defaulted used for data mounting. +- Using `nodePort` to expose service, You can access `artifactory` by domain `http://{{k8s node IP}}:30002`. The default account name and password are admin/password (please replace the default account password in the production environment). + +### Production Environment + +#### External Storage + +- Postgresql: Set the `database.url` to Postgresql's address. More info can be found in [config](https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Database). + +#### Disk Storage + +You can set `customVolumes` and `customVolumeMounts` for this service. More info can be found in [Config](https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Filestore). + +#### Network Config + +This plugin support`Ingress`, `ClusterIP`, `NodePort` and `LoadBalancer` , You can give choice to your needs. + +### Config + +```yaml +--8<-- "artifactory.yaml" +``` + +Currently, except for `values_yaml`, all the parameters in the example above are mandatory. \ No newline at end of file diff --git a/docs/plugins/artifactory.zh.md b/docs/plugins/artifactory.zh.md new file mode 100644 index 000000000..337c8a277 --- /dev/null +++ b/docs/plugins/artifactory.zh.md @@ -0,0 +1,45 @@ +# artifactory 插件 + +这个插件使用 helm 在已有的 k8s 集群上安装 [artifactory](https://jfrog.com/artifactory/)。 + +## 使用方法 + +### 测试环境 + +如果你想在**本地测试插件**, 可以使用如下 `values_yaml` 配置。 + +```yaml +values_yaml: | + artifactory: + service: + type: NodePort + nodePort: 30002 + nginx: + enabled: false +``` + +在该配置下 +- helm 会自动创建依赖的 Postgresql; +- 数据挂载的磁盘默认会使用集群上机器的本地磁盘; +- 通过 `NodePort` 对外暴露服务,可使用 `http://{{k8s 节点ip}}:30002` 域名来访问,默认账号名密码为 admin/password (生产环境请替换默认账号密码)。 + +### 生产环境 + +#### 外部存储 + +- Postgresql:设置 `database.url` 来设置数据库地址,具体配置可参考 [config](https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Database) 中的选项。 + +#### 磁盘存储 + +可以设置 `customVolumes` 和 `customVolumeMounts` 来配置挂载磁盘,具体配置可参考 [Config](https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Filestore)。 + +#### 网络层配置 +该插件支持 `Ingress`, `ClusterIP`, `NodePort`, `LoadBalancer` 对外暴露的模式,可以基于需求进行选择。 + +### 配置 + +```yaml +--8<-- "artifactory.yaml" +``` + +目前除了 `values_yaml` 字段,所有示例参数均为必填项。 diff --git a/internal/pkg/plugin/artifactory/artifactory.go b/internal/pkg/plugin/artifactory/artifactory.go new file mode 100644 index 000000000..e6cf841dd --- /dev/null +++ b/internal/pkg/plugin/artifactory/artifactory.go @@ -0,0 +1,5 @@ +package artifactory + +var defaultDeploymentList = []string{ + "artifactory", +} diff --git a/internal/pkg/plugin/artifactory/create.go b/internal/pkg/plugin/artifactory/create.go new file mode 100644 index 000000000..706e09d16 --- /dev/null +++ b/internal/pkg/plugin/artifactory/create.go @@ -0,0 +1,32 @@ +package artifactory + +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) { + // 1. config install operations + runner := &plugininstaller.Runner{ + PreExecuteOperations: []plugininstaller.MutableOperation{ + helm.Validate, + }, + ExecuteOperations: []plugininstaller.BaseOperation{ + helm.DealWithNsWhenInstall, + helm.InstallOrUpdate, + }, + TermateOperations: []plugininstaller.BaseOperation{ + helm.DealWithNsWhenInterruption, + }, + GetStatusOperation: helm.GetPluginStaticStateWrapper(defaultDeploymentList), + } + + // 2. execute installer get status and error + status, err := runner.Execute(plugininstaller.RawOptions(options)) + if err != nil { + return nil, err + } + log.Debugf("Return map: %v", status) + return status, nil +} diff --git a/internal/pkg/plugin/artifactory/delete.go b/internal/pkg/plugin/artifactory/delete.go new file mode 100644 index 000000000..563109868 --- /dev/null +++ b/internal/pkg/plugin/artifactory/delete.go @@ -0,0 +1,26 @@ +package artifactory + +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) { + // 1. config delete operations + runner := &plugininstaller.Runner{ + PreExecuteOperations: []plugininstaller.MutableOperation{ + helm.Validate, + }, + ExecuteOperations: []plugininstaller.BaseOperation{ + helm.Delete, + helm.DealWithNsWhenInterruption, + }, + } + _, err := runner.Execute(plugininstaller.RawOptions(options)) + if err != nil { + return false, err + } + + // 2. return ture if all process success + return true, nil +} diff --git a/internal/pkg/plugin/artifactory/read.go b/internal/pkg/plugin/artifactory/read.go new file mode 100644 index 000000000..f9c4cec61 --- /dev/null +++ b/internal/pkg/plugin/artifactory/read.go @@ -0,0 +1,25 @@ +package artifactory + +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) { + // 1. config read operations + runner := &plugininstaller.Runner{ + PreExecuteOperations: []plugininstaller.MutableOperation{ + helm.Validate, + }, + GetStatusOperation: helm.GetPluginAllState, + } + + status, err := runner.Execute(plugininstaller.RawOptions(options)) + if err != nil { + return nil, err + } + + log.Debugf("Return map: %v", status) + return status, nil +} diff --git a/internal/pkg/plugin/artifactory/update.go b/internal/pkg/plugin/artifactory/update.go new file mode 100644 index 000000000..63ff7a16e --- /dev/null +++ b/internal/pkg/plugin/artifactory/update.go @@ -0,0 +1,28 @@ +package artifactory + +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) { + // 1. config update operations + runner := &plugininstaller.Runner{ + PreExecuteOperations: []plugininstaller.MutableOperation{ + helm.Validate, + }, + ExecuteOperations: []plugininstaller.BaseOperation{ + helm.InstallOrUpdate, + }, + GetStatusOperation: helm.GetPluginStaticStateWrapper(defaultDeploymentList), + } + + // 2. execute update get status and error + status, err := runner.Execute(plugininstaller.RawOptions(options)) + if err != nil { + return nil, err + } + log.Debugf("Return map: %v", status) + return status, nil +} diff --git a/internal/pkg/show/config/plugins/artifactory.yaml b/internal/pkg/show/config/plugins/artifactory.yaml new file mode 100644 index 000000000..b8e56f4ab --- /dev/null +++ b/internal/pkg/show/config/plugins/artifactory.yaml @@ -0,0 +1,33 @@ +tools: +# name of the tool +- name: artifactory + # 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: + create_namespace: true + repo: + name: jfrog + # url of the Helm repo, use self host helm config beacuse official helm does'nt support namespace config + url: https://charts.jfrog.io + # Helm chart information + chart: + # name of the chart + chart_name: jfrog/artifactory + # k8s namespace where Harbor will be installed + namespace: artifactory + # release name of the chart + release_name: artifactory + # 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: 10m + # whether to perform a CRD upgrade during installation + upgradeCRDs: true + # values_yaml: | + # artifactory: + # service: + # type: NodePort + From 3eb6b69303b4d337bf1fbb9e65e740affd155f26 Mon Sep 17 00:00:00 2001 From: Meng JiaFeng Date: Mon, 25 Jul 2022 10:51:25 +0800 Subject: [PATCH 2/3] fix: gem error Signed-off-by: Meng JiaFeng --- internal/pkg/show/config/embed_gen.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/pkg/show/config/embed_gen.go b/internal/pkg/show/config/embed_gen.go index aaa4764ee..7e431994a 100644 --- a/internal/pkg/show/config/embed_gen.go +++ b/internal/pkg/show/config/embed_gen.go @@ -15,6 +15,9 @@ var ( //go:embed plugins/argocdapp.yaml ArgocdappDefaultConfig string + //go:embed plugins/artifactory.yaml + ArtifactoryDefaultConfig string + //go:embed plugins/devlake.yaml DevlakeDefaultConfig string @@ -82,6 +85,7 @@ var ( var pluginDefaultConfigs = map[string]string{ "argocd": ArgocdDefaultConfig, "argocdapp": ArgocdappDefaultConfig, + "artifactory": ArtifactoryDefaultConfig, "devlake": DevlakeDefaultConfig, "github-repo-scaffolding-golang": GithubRepoScaffoldingGolangDefaultConfig, "githubactions-golang": GithubactionsGolangDefaultConfig, From cdce77d962713b22135151ea8811256056f4f1c7 Mon Sep 17 00:00:00 2001 From: Meng JiaFeng Date: Mon, 25 Jul 2022 11:39:31 +0800 Subject: [PATCH 3/3] fix: doc error Signed-off-by: Meng JiaFeng --- docs/plugins/artifactory.md | 2 +- docs/plugins/artifactory.zh.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/plugins/artifactory.md b/docs/plugins/artifactory.md index d87a2aedd..184048a03 100644 --- a/docs/plugins/artifactory.md +++ b/docs/plugins/artifactory.md @@ -27,7 +27,7 @@ In this configuration #### External Storage -- Postgresql: Set the `database.url` to Postgresql's address. More info can be found in [config](https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Database). +- PostgreSQL: Set the `database.url` to Postgresql's address. More info can be found in [Config](https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Database). #### Disk Storage diff --git a/docs/plugins/artifactory.zh.md b/docs/plugins/artifactory.zh.md index 337c8a277..6db7e2d49 100644 --- a/docs/plugins/artifactory.zh.md +++ b/docs/plugins/artifactory.zh.md @@ -27,7 +27,7 @@ values_yaml: | #### 外部存储 -- Postgresql:设置 `database.url` 来设置数据库地址,具体配置可参考 [config](https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Database) 中的选项。 +- PostgreSQL:设置 `database.url` 来设置数据库地址,具体配置可参考 [Config](https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Database) 中的选项。 #### 磁盘存储