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: support helm plugin default value #936

Merged
merged 3 commits into from
Aug 5, 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
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 |
aFlyBird0 marked this conversation as resolved.
Show resolved Hide resolved
| 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