Skip to content

Commit

Permalink
Merge pull request #936 from steinliber/feat-plugin-optimize
Browse files Browse the repository at this point in the history
feat: support helm plugin default value
  • Loading branch information
IronCore864 authored Aug 5, 2022
2 parents 1ff41b5 + d001f0f commit b3ba2c5
Show file tree
Hide file tree
Showing 18 changed files with 362 additions and 145 deletions.
13 changes: 12 additions & 1 deletion docs/plugins/argocd.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,15 @@ This plugin installs [ArgoCD](https://argoproj.github.io/cd/) in an existing Kub
--8<-- "argocd.yaml"
```

Currently, except for `values_yaml`, all the parameters in the example above are mandatory.
### Default Configs

| key | default value | description |
| ---- | ---- | ---- |
| chart.chart_name | argo/argo-cd | argocd's official chart name |
| chart.timeout | 5m | this config will wait 5 minutes to deploy argocd |
| upgradeCRDs | true | default update CRD config |
| chart.wait | true | whether to wait until install is complete |
| repo.url | https://argoproj.github.io/argo-helm | helm repo address |
| repo.name | argo | helm repo name |

Currently, except for `values_yaml` and default configs, all the parameters in the example above are mandatory.
31 changes: 13 additions & 18 deletions internal/pkg/plugin/argocd/argocd.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
package argocd

import (
"github.com/devstream-io/devstream/internal/pkg/plugininstaller"
"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 (
defaultRepoURL = "https://argoproj.github.io/argo-helm"
defaultRepoName = "argo"
)

func defaultMissedOption(options plugininstaller.RawOptions) (plugininstaller.RawOptions, error) {
opts, err := helm.NewOptions(options)
if err != nil {
return nil, err
}
if opts.Repo.URL == "" {
opts.Repo.URL = defaultRepoURL
}
if opts.Repo.Name == "" {
opts.Repo.Name = defaultRepoName
}
return opts.Encode()
var defaultHelmConfig = helm.Options{
Chart: helmCommon.Chart{
ChartName: "argo/argo-cd",
Timeout: "5m",
UpgradeCRDs: types.Bool(true),
Wait: types.Bool(true),
},
Repo: helmCommon.Repo{
URL: "https://argoproj.github.io/argo-helm",
Name: "argo",
},
}
2 changes: 1 addition & 1 deletion internal/pkg/plugin/argocd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func Create(options map[string]interface{}) (map[string]interface{}, error) {
// 1. config install operations
runner := &plugininstaller.Runner{
PreExecuteOperations: []plugininstaller.MutableOperation{
defaultMissedOption,
helm.SetDefaultConfig(&defaultHelmConfig),
helm.Validate,
},
ExecuteOperations: helm.DefaultCreateOperations,
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/plugin/argocd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ func Delete(options map[string]interface{}) (bool, error) {
// 1. config delete operations
runner := &plugininstaller.Runner{
PreExecuteOperations: []plugininstaller.MutableOperation{
defaultMissedOption,
helm.SetDefaultConfig(&defaultHelmConfig),
helm.Validate,
},
ExecuteOperations: helm.DefaultDeleteOperations,
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/plugin/argocd/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func Read(options map[string]interface{}) (map[string]interface{}, error) {
// 1. config read operations
runner := &plugininstaller.Runner{
PreExecuteOperations: []plugininstaller.MutableOperation{
defaultMissedOption,
helm.SetDefaultConfig(&defaultHelmConfig),
helm.Validate,
},
GetStatusOperation: helm.GetPluginAllState,
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/plugin/argocd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func Update(options map[string]interface{}) (map[string]interface{}, error) {
// 1. config update operations
runner := &plugininstaller.Runner{
PreExecuteOperations: []plugininstaller.MutableOperation{
defaultMissedOption,
helm.SetDefaultConfig(&defaultHelmConfig),
helm.Validate,
},
ExecuteOperations: helm.DefaultUpdateOperations,
Expand Down
13 changes: 13 additions & 0 deletions internal/pkg/plugininstaller/helm/helm_suit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package helm_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestPlanmanager(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "PluginInstaller Helm Suite")
}
19 changes: 13 additions & 6 deletions internal/pkg/plugininstaller/helm/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (

// Options is the struct for parameters used by the helm install config.
type Options struct {
CreateNamespace bool `mapstructure:"create_namespace"`
Repo helm.Repo
Chart helm.Chart
CreateNamespace bool `mapstructure:"create_namespace"`
Repo helm.Repo `mapstructure:"repo"`
Chart helm.Chart `mapstructure:"chart"`
}

func (opts *Options) GetHelmParam() *helm.HelmParam {
Expand Down Expand Up @@ -41,11 +41,18 @@ func (opts *Options) Encode() (map[string]interface{}, error) {
return options, nil
}

func (opts *Options) fillDefaultValue(defaultOpts *Options) {
chart := &opts.Chart
chart.FillDefaultValue(&defaultOpts.Chart)
repo := &opts.Repo
repo.FillDefaultValue(&defaultOpts.Repo)
}

// NewOptions create options by raw options
func NewOptions(options plugininstaller.RawOptions) (Options, error) {
func NewOptions(options plugininstaller.RawOptions) (*Options, error) {
var opts Options
if err := mapstructure.Decode(options, &opts); err != nil {
return opts, err
return nil, err
}
return opts, nil
return &opts, nil
}
117 changes: 117 additions & 0 deletions internal/pkg/plugininstaller/helm/option_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package helm_test

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

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

var _ = Describe("Options struct", func() {
var (
testOpts helm.Options
testChartName string
testRepoName string
testNameSpace string
expectMap map[string]interface{}
emptyBool *bool
)

BeforeEach(func() {
testChartName = "test_chart"
testRepoName = "test_repo"
testNameSpace = "test_nameSpace"
testOpts = helm.Options{
Chart: helmCommon.Chart{
ChartName: testChartName,
Namespace: testNameSpace,
},
Repo: helmCommon.Repo{
Name: testRepoName,
},
}
expectMap = map[string]interface{}{
"create_namespace": false,
"repo": map[string]interface{}{
"name": "test_repo",
"url": "",
},
"chart": map[string]interface{}{
"version": "",
"release_name": "",
"wait": emptyBool,
"chart_name": "test_chart",
"namespace": "test_nameSpace",
"create_namespace": emptyBool,
"timeout": "",
"upgradeCRDs": emptyBool,
"values_yaml": "",
},
}
})

Context("GetHelmParam method", func() {
It("should pass chart and repo field", func() {
helmParam := testOpts.GetHelmParam()
Expect(helmParam.Chart).Should(Equal(testOpts.Chart))
Expect(helmParam.Repo).Should(Equal(testOpts.Repo))
})
})

Context("CheckIfCreateNamespace method", func() {
It("should equal opts config", func() {
Expect(testOpts.CheckIfCreateNamespace()).Should(Equal(testOpts.CreateNamespace))
})
})

Context("GetNamespace method", func() {
It("should return chart's nameSpace", func() {
Expect(testOpts.GetNamespace()).Should(Equal(testOpts.Chart.Namespace))
})
})

Context("GetReleaseName method", func() {
It("should return chart's ReleaseName", func() {
Expect(testOpts.GetReleaseName()).Should(Equal(testOpts.Chart.ReleaseName))
})
})

Context("Encode method", func() {
It("should return opts map", func() {
result, err := testOpts.Encode()
Expect(err).Error().ShouldNot(HaveOccurred())
Expect(result).Should(Equal(expectMap))
})
})
})

var _ = Describe("NewOptions func", func() {

var (
inputOptions plugininstaller.RawOptions
testRepoName string
testChartName string
)

BeforeEach(func() {
testRepoName = "test_repo"
testChartName = "test_chart"
inputOptions = map[string]interface{}{
"repo": map[string]interface{}{
"name": testRepoName,
},
"chart": map[string]interface{}{
"chart_name": testChartName,
},
}
})

It("should work normal", func() {
opts, err := helm.NewOptions(inputOptions)
Expect(err).Error().ShouldNot(HaveOccurred())
Expect(opts.Chart.ChartName).Should(Equal(testChartName))
Expect(opts.Repo.Name).Should(Equal(testRepoName))
})
})
14 changes: 13 additions & 1 deletion internal/pkg/plugininstaller/helm/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func Validate(options plugininstaller.RawOptions) (plugininstaller.RawOptions, e
if err != nil {
return nil, err
}
errs := helm.DefaultsAndValidate(opts.GetHelmParam())
errs := helm.Validate(opts.GetHelmParam())
if len(errs) > 0 {
for _, e := range errs {
log.Errorf("Options error: %s.", e)
Expand All @@ -23,3 +23,15 @@ func Validate(options plugininstaller.RawOptions) (plugininstaller.RawOptions, e
}
return options, nil
}

// SetDefaultConfig will update options empty values base on import options
func SetDefaultConfig(defaultConfig *Options) plugininstaller.MutableOperation {
return func(options plugininstaller.RawOptions) (plugininstaller.RawOptions, error) {
opts, err := NewOptions(options)
if err != nil {
return nil, err
}
opts.fillDefaultValue(defaultConfig)
return opts.Encode()
}
}
108 changes: 108 additions & 0 deletions internal/pkg/plugininstaller/helm/validate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package helm_test

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"github.com/devstream-io/devstream/internal/pkg/plugininstaller"
"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 _ = Describe("Validate func", func() {
var testOption plugininstaller.RawOptions

When("options is not valid", func() {
BeforeEach(func() {
testOption = map[string]interface{}{
"chart": map[string]string{},
"repo": map[string]string{},
}
})
It("should return error", func() {
_, err := helm.Validate(testOption)
Expect(err).Error().Should(HaveOccurred())
})
})

When("options is valid", func() {
BeforeEach(func() {
testOption = map[string]interface{}{
"chart": map[string]string{
"chart_name": "test",
},
"repo": map[string]string{
"url": "http://test.com",
"name": "test",
},
}
})
It("should return success", func() {
opt, err := helm.Validate(testOption)
Expect(err).Error().ShouldNot(HaveOccurred())
Expect(opt).ShouldNot(BeEmpty())
})
})
})

var _ = Describe("SetDefaultConfig func", func() {
var (
testChartName string
testRepoURL string
testRepoName string
testBool *bool
defaultConfig helm.Options
testOptions plugininstaller.RawOptions
expectChart map[string]interface{}
expectRepo map[string]interface{}
)
BeforeEach(func() {
testChartName = "test_chart"
testRepoName = "test_repo"
testRepoURL = "http://test.com"
testBool = types.Bool(true)
testOptions = map[string]interface{}{
"chart": map[string]string{},
"repo": map[string]string{},
}
defaultConfig = helm.Options{
Chart: helmCommon.Chart{
ChartName: testChartName,
Wait: testBool,
UpgradeCRDs: testBool,
CreateNamespace: testBool,
},
Repo: helmCommon.Repo{
URL: testRepoURL,
Name: testRepoName,
},
}
expectChart = map[string]interface{}{
"chart_name": testChartName,
"wait": testBool,
"namespace": "",
"version": "",
"release_name": "",
"values_yaml": "",
"timeout": "",
"create_namespace": testBool,
"upgradeCRDs": testBool,
}
expectRepo = map[string]interface{}{
"url": testRepoURL,
"name": testRepoName,
}
})
It("should update default value", func() {
updateFunc := helm.SetDefaultConfig(&defaultConfig)
o, err := updateFunc(testOptions)
Expect(err).Error().ShouldNot(HaveOccurred())
oRepo, exist := o["repo"]
Expect(exist).Should(BeTrue())
oChart, exist := o["chart"]
Expect(exist).Should(BeTrue())
Expect(oRepo).Should(Equal(expectRepo))
Expect(oChart).Should(Equal(expectChart))
})
})
Loading

0 comments on commit b3ba2c5

Please sign in to comment.