Skip to content

Commit

Permalink
feat: imporve cluster register and addon (#442)
Browse files Browse the repository at this point in the history
Co-authored-by: yipeng1030 <[email protected]>
  • Loading branch information
yipeng1030 and yipeng1030 authored Sep 25, 2024
1 parent a62d94c commit ef8ac80
Show file tree
Hide file tree
Showing 18 changed files with 630 additions and 172 deletions.
17 changes: 13 additions & 4 deletions docs/user_docs/cli/kbcli_addon_install.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,24 @@ kbcli addon install [flags]
# install an addon with a specified version default index
kbcli addon install apecloud-mysql --version 0.7.0
# install an addon with a specified version and cluster chart of different version.
kbcli addon install apecloud-mysql --version 0.7.0 --cluster-chart-version 0.7.1
# install an addon with a specified version and local path.
kbcli addon install apecloud-mysql --version 0.7.0 --path /path/to/local/chart
```

### Options

```
--force force install the addon and ignore the version check
-h, --help help for install
--index string specify the addon index index, use 'kubeblocks' by default (default "kubeblocks")
--version string specify the addon version
--cluster-chart-repo string specify the repo of cluster chart, use the url of 'kubeblocks-addons' by default (default "https://jihulab.com/api/v4/projects/150246/packages/helm/stable")
--cluster-chart-version string specify the cluster chart version, use the same version as the addon by default
--force force install the addon and ignore the version check
-h, --help help for install
--index string specify the addon index, use 'kubeblocks' by default (default "kubeblocks")
--path string specify the local path contains addon CRs and needs to be specified when operating offline
--version string specify the addon version
```

### Options inherited from parent commands
Expand Down
25 changes: 24 additions & 1 deletion docs/user_docs/cli/kbcli_addon_search.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,33 @@ Search the addon from index
kbcli addon search [flags]
```

### Examples

```
# install an addon from default index
kbcli addon install apecloud-mysql
# install an addon from default index and skip KubeBlocks version compatibility check
kbcli addon install apecloud-mysql --force
# install an addon from a specified index
kbcli addon install apecloud-mysql --index my-index
# install an addon with a specified version default index
kbcli addon install apecloud-mysql --version 0.7.0
# install an addon with a specified version and cluster chart of different version.
kbcli addon install apecloud-mysql --version 0.7.0 --cluster-chart-version 0.7.1
# install an addon with a specified version and local path.
kbcli addon install apecloud-mysql --version 0.7.0 --path /path/to/local/chart
```

### Options

```
-h, --help help for search
-h, --help help for search
--path string the local directory contains addon CRs
```

### Options inherited from parent commands
Expand Down
18 changes: 12 additions & 6 deletions docs/user_docs/cli/kbcli_addon_upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ kbcli addon upgrade [flags]
# upgrade an addon with a specified version default index
kbcli addon upgrade apecloud-mysql --version 0.7.0
# upgrade an addon with a specified version, default index and a different version of cluster chart
kbcli addon upgrade apecloud-mysql --version 0.7.0 --cluster-chart-version 0.7.1
# non-inplace upgrade an addon with a specified version
kbcli addon upgrade apecloud-mysql --inplace=false --version 0.7.0
Expand All @@ -33,12 +36,15 @@ kbcli addon upgrade [flags]
### Options

```
--force force upgrade the addon and ignore the version check
-h, --help help for upgrade
--index string specify the addon index index, use 'kubeblocks' by default (default "kubeblocks")
--inplace when inplace is false, it will retain the existing addon and reinstall the new version of the addon, otherwise the upgrade will be in-place. The default is true. (default true)
--name string name is the new version addon name need to set by user when inplace is false, it also will be used as resourceNamePrefix of an addon with multiple version.
--version string specify the addon version
--cluster-chart-repo string specify the repo of cluster chart, use the url of 'kubeblocks-addons' by default (default "https://jihulab.com/api/v4/projects/150246/packages/helm/stable")
--cluster-chart-version string specify the cluster chart version, use the same version as the addon by default
--force force upgrade the addon and ignore the version check
-h, --help help for upgrade
--index string specify the addon index index, use 'kubeblocks' by default (default "kubeblocks")
--inplace when inplace is false, it will retain the existing addon and reinstall the new version of the addon, otherwise the upgrade will be in-place. The default is true. (default true)
--name string name is the new version addon name need to set by user when inplace is false, it also will be used as resourceNamePrefix of an addon with multiple version.
--path string specify the local path contains addon CRs and needs to be specified when operating offline
--version string specify the addon version
```

### Options inherited from parent commands
Expand Down
17 changes: 11 additions & 6 deletions docs/user_docs/cli/kbcli_cluster_register.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: kbcli cluster register
Pull the cluster chart to the local cache and register the type to 'create' sub-command

```
kbcli cluster register [NAME] --source [CHART-URL] [flags]
kbcli cluster register [NAME] [flags]
```

### Examples
Expand All @@ -15,16 +15,21 @@ kbcli cluster register [NAME] --source [CHART-URL] [flags]
kbcli cluster register orioledb --source https://github.com/apecloud/helm-charts/releases/download/orioledb-cluster-0.6.0-beta.44/orioledb-cluster-0.6.0-beta.44.tgz
# Register a cluster type from a local path file
kbcli cluster register neon -source pkg/cli/cluster/charts/neon-cluster.tgz
kbcli cluster register neon --source pkg/cli/cluster/charts/neon-cluster.tgz
# Register a cluster type from a Helm repository, specifying the version and engine.
kbcli cluster register mysql --engine mysql --version 0.9.0 --repo https://jihulab.com/api/v4/projects/150246/packages/helm/stable
```

### Options

```
--alias string Set the cluster type alias
--auto-approve Skip interactive approval when registering an existed cluster type
-h, --help help for register
-S, --source string Specify the cluster type chart source, support a URL or a local file path
--alias string Set the cluster type alias
--engine string Specify the cluster chart name in helm repo
-h, --help help for register
--repo string Specify the url of helm repo which contains cluster charts (default "https://jihulab.com/api/v4/projects/150246/packages/helm/stable")
-S, --source string Specify the cluster type chart source, support a URL or a local file path
--version string Specify the version of cluster chart to register
```

### Options inherited from parent commands
Expand Down
83 changes: 80 additions & 3 deletions pkg/cluster/external_charts.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package cluster

import (
"compress/gzip"
"encoding/json"
"fmt"
"io"
"io/fs"
Expand Down Expand Up @@ -155,7 +156,7 @@ func ClearCharts(c ClusterType) {
}
}

// TypeInstance reference to a cluster type instance in config
// TypeInstance reference to a cluster type instance in config and implement the cluster.chartLoader interface
type TypeInstance struct {
Name ClusterType `yaml:"name"`
URL string `yaml:"helmChartUrl"`
Expand Down Expand Up @@ -214,7 +215,8 @@ func (h *TypeInstance) getAlias() string {

func (h *TypeInstance) register(subcmd ClusterType) error {
if _, ok := ClusterTypeCharts[subcmd]; ok {
return fmt.Errorf("cluster type %s already registered", subcmd)
// replace built-in cluster chart
klog.V(2).Info(fmt.Sprintf("cluster chart of %s is replaced manully\n", subcmd.String()))
}
ClusterTypeCharts[subcmd] = h

Expand All @@ -223,7 +225,82 @@ func (h *TypeInstance) register(subcmd ClusterType) error {
return nil
}
}
return fmt.Errorf("can't find the %s in cache, please use 'kbcli cluster pull %s --url %s' first", h.Name.String(), h.Name.String(), h.URL)
return fmt.Errorf("can't find the %s in cache, please use 'kbcli cluster register %s --url %s' first", h.Name.String(), h.Name.String(), h.URL)
}

func (h *TypeInstance) PatchNewClusterType() error {
if err := h.PreCheck(); err != nil {
return fmt.Errorf("the chart of %s pre-check unsuccssful: %s", h.Name, err.Error())
}
isChartExist := false
for _, item := range GlobalClusterChartConfig {
if h.Name == item.Name {
isChartExist = true
}
}
if isChartExist {
GlobalClusterChartConfig.UpdateConfig(h)
} else {
GlobalClusterChartConfig.AddConfig(h)
}
return GlobalClusterChartConfig.WriteConfigs(CliClusterChartConfig)
}

var StandardSchema = map[string]interface{}{
"properties": map[string]interface{}{
"replicas": nil,
"cpu": nil,
"memory": nil,
"storage": nil,
},
}

func (h *TypeInstance) ValidateChartSchema() (bool, error) {
file, err := h.loadChart()
if err != nil {
return false, err
}
defer file.Close()

c, err := loader.LoadArchive(file)
if err != nil {
return false, err
}

data := c.Schema
if len(data) == 0 {
return false, fmt.Errorf("register cluster chart of %s failed, schema of the chart doesn't exist", h.Name)
}

var schema map[string]interface{}
if err := json.Unmarshal(data, &schema); err != nil {
return false, fmt.Errorf("register cluster chart of %s failed, error decoding JSON: %s", h.Name, err)
}

if err := validateSchema(schema, StandardSchema); err != nil {
return false, err
}

return true, nil
}

func validateSchema(schema, standard map[string]interface{}) error {
for key, val := range standard {
if subStandard, ok := val.(map[string]interface{}); ok {
subSchema, ok := schema[key].(map[string]interface{})
if !ok {
return fmt.Errorf("register cluster chart failed, schema missing required map key '%s'", key)
}
if err := validateSchema(subSchema, subStandard); err != nil {
return err
}
} else {
if _, exists := schema[key]; !exists {
return fmt.Errorf("register cluster chart failed, schema missing required key '%s'", key)
}
}
}
return nil
}

var _ chartLoader = &TypeInstance{}
Expand Down
5 changes: 4 additions & 1 deletion pkg/cluster/register_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var _ = Describe("cluster register", func() {
Expect(err).Should(Succeed())
})

It("test external chart", func() {
It("test fake chart", func() {
fakeChart := &TypeInstance{
Name: "fake",
URL: "www.fake-chart-hub/fake.tgz",
Expand All @@ -58,6 +58,9 @@ var _ = Describe("cluster register", func() {
_, err := fakeChart.loadChart()
Expect(err).Should(HaveOccurred())
Expect(fakeChart.register("fake")).Should(HaveOccurred())
Expect(fakeChart.PatchNewClusterType()).Should(HaveOccurred())
_, err = fakeChart.ValidateChartSchema()
Expect(err).Should(HaveOccurred())
})

Context("test Config reader", func() {
Expand Down
4 changes: 3 additions & 1 deletion pkg/cmd/addon/addon.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
viper "github.com/apecloud/kubeblocks/pkg/viperx"

"github.com/apecloud/kbcli/pkg/action"
clusterCmd "github.com/apecloud/kbcli/pkg/cmd/cluster"
"github.com/apecloud/kbcli/pkg/cmd/plugin"
"github.com/apecloud/kbcli/pkg/printer"
"github.com/apecloud/kbcli/pkg/types"
Expand Down Expand Up @@ -111,7 +112,7 @@ func NewAddonCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.C
newEnableCmd(f, streams),
newDisableCmd(f, streams),
newIndexCmd(streams),
newSearchCmd(streams),
newSearchCmd(f, streams),
newInstallCmd(f, streams),
newUninstallCmd(f, streams),
newUpgradeCmd(f, streams),
Expand Down Expand Up @@ -224,6 +225,7 @@ func newEnableCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.
util.CheckErr(o.complete(o, cmd, []string{name}))
util.CheckErr(o.CmdComplete(cmd))
util.CheckErr(o.Run())
util.CheckErr(clusterCmd.RegisterClusterChart(f, streams, "", name, o.addon.Spec.Version, types.ClusterChartsRepoURL))
}
},
}
Expand Down
Loading

0 comments on commit ef8ac80

Please sign in to comment.