Skip to content
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
2 changes: 0 additions & 2 deletions docs/user_docs/cli/kbcli_cluster_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,10 @@ kbcli cluster create [ClusterType] [flags]
* [kbcli cluster create kafka](kbcli_cluster_create_kafka.md) - Create a kafka cluster.
* [kbcli cluster create mongodb](kbcli_cluster_create_mongodb.md) - Create a mongodb cluster.
* [kbcli cluster create mysql](kbcli_cluster_create_mysql.md) - Create a mysql cluster.
* [kbcli cluster create oriol](kbcli_cluster_create_oriol.md) - Create a oriol cluster.
* [kbcli cluster create postgresql](kbcli_cluster_create_postgresql.md) - Create a postgresql cluster.
* [kbcli cluster create qdrant](kbcli_cluster_create_qdrant.md) - Create a qdrant cluster.
* [kbcli cluster create rabbitmq](kbcli_cluster_create_rabbitmq.md) - Create a rabbitmq cluster.
* [kbcli cluster create redis](kbcli_cluster_create_redis.md) - Create a redis cluster.
* [kbcli cluster create tidb](kbcli_cluster_create_tidb.md) - Create a tidb cluster.

#### Go Back to [CLI Overview](cli.md) Homepage.

126 changes: 3 additions & 123 deletions pkg/cmd/addon/addon.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,41 +29,31 @@ import (
"strconv"
"strings"

kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1"
"github.com/apecloud/kubeblocks/pkg/constant"
viper "github.com/apecloud/kubeblocks/pkg/viperx"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
helmaction "helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/releaseutil"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericiooptions"
discoverycli "k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/templates"
"k8s.io/utils/strings/slices"
"sigs.k8s.io/yaml"

extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1"
"github.com/apecloud/kubeblocks/pkg/constant"
viper "github.com/apecloud/kubeblocks/pkg/viperx"

"github.com/apecloud/kbcli/pkg/action"
"github.com/apecloud/kbcli/pkg/cluster"
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"
"github.com/apecloud/kbcli/pkg/util"
"github.com/apecloud/kbcli/pkg/util/helm"
)

type addonEnableFlags struct {
Expand Down Expand Up @@ -236,7 +226,6 @@ func newEnableCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.
util.CheckErr(o.validate())
util.CheckErr(o.complete(o, cmd, []string{name}))
util.CheckErr(o.CmdComplete(cmd))
util.CheckErr(o.process09ClusterDefAndComponentVersions())
util.CheckErr(o.Run())
if isEngineAddon(&o.addon) {
util.CheckErr(clusterCmd.RegisterClusterChart(f, streams, "", name, getAddonVersion(&o.addon), types.ClusterChartsRepoURL))
Expand Down Expand Up @@ -1034,112 +1023,3 @@ func (o *addonCmdOpts) checkBeforeDisable() error {
}
return CheckAddonUsedByCluster(o.dynamic, o.Names, o.In)
}

func (o *addonCmdOpts) process09ClusterDefAndComponentVersions() error {
kbDeploys, err := util.GetKBDeploys(o.client, util.KubeblocksAppComponent, metav1.NamespaceAll)
if err != nil || len(kbDeploys) < 2 {
return err
}
if !strings.HasPrefix(o.addon.Spec.Version, "1.0") {
return nil
}
var newKBNamespace string
for _, v := range kbDeploys {
if strings.HasPrefix(v.Labels[constant.AppVersionLabelKey], "1.0") {
newKBNamespace = v.Namespace
break
}
}
// 1. get manifests from the helm repo
chartsDownloader, err := helm.NewDownloader(helm.NewConfig(newKBNamespace, "", "", false))
if err != nil {
return err
}
// DownloadTo can't specify the saved name, so download it to TempDir and rename it when copy
chartPath, _, err := chartsDownloader.DownloadTo(o.addon.Spec.Helm.ChartLocationURL, "", cluster.CliChartsCacheDir)
if err != nil {
return err
}
// 2. overwrite the spec of ClusterDefinition and ComponentVersion with the new version
actionCfg, err := helm.NewActionConfig(helm.NewConfig(newKBNamespace, "", "", false))
if err != nil {
return err
}
chart, err := loader.Load(chartPath)
if err != nil {
return err
}
renderer := helmaction.NewInstall(actionCfg)
renderer.ReleaseName = o.addon.Name + "for-upgrade"
renderer.Namespace = newKBNamespace
renderer.DryRun = true
renderer.Replace = true
renderer.ClientOnly = true
valuesMap := map[string]interface{}{}
if o.addon.Spec.Helm != nil {
for _, v := range o.addon.Spec.Helm.InstallValues.SetValues {
keyValues := strings.Split(v, "=")
if len(keyValues) != 2 {
return fmt.Errorf("invalid install value: %s", v)
}
valuesMap[keyValues[0]] = keyValues[1]
}
}
release, err := renderer.Run(chart, valuesMap)
if err != nil {
return err
}

updateObject := func(obj runtime.Object, gvr schema.GroupVersionResource) error {
unstructuredObj := obj.(*unstructured.Unstructured)
targetObj, err := o.dynamic.Resource(gvr).Namespace("").Get(context.TODO(), unstructuredObj.GetName(), metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
if _, err = o.dynamic.Resource(gvr).Namespace("").Create(context.TODO(), unstructuredObj, metav1.CreateOptions{}); err != nil {
return err
}
return nil
}
return err
}
annotations := targetObj.GetAnnotations()
annotations[constant.CRDAPIVersionAnnotationKey] = kbappsv1.GroupVersion.String()
annotations["meta.helm.sh/release-name"] = "kb-addon-" + o.addon.Name
annotations["meta.helm.sh/release-namespace"] = newKBNamespace
targetObj.SetAnnotations(annotations)
targetObj.Object["spec"] = unstructuredObj.Object["spec"]
if _, err = o.dynamic.Resource(gvr).Namespace("").Update(context.TODO(), targetObj, metav1.UpdateOptions{}); err != nil {
return err
}
return nil
}
manifests := releaseutil.SplitManifests(release.Manifest)
for _, manifest := range manifests {

// convert yaml to json
jsonData, err := yaml.YAMLToJSON([]byte(manifest))
if err != nil {
return err
}
// check if jsonData is empty or null
if len(jsonData) == 0 || string(jsonData) == "null" {
continue
}
// get resource gvk
obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(jsonData, nil, nil)
if err != nil {
return err
}
switch gvk.Kind {
case types.KindClusterDef:
if err = updateObject(obj, types.ClusterDefGVR()); err != nil {
return err
}
case types.KindComponentVersion:
if err = updateObject(obj, types.ComponentVersionsGVR()); err != nil {
return err
}
}
}
return nil
}
120 changes: 120 additions & 0 deletions pkg/cmd/addon/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,30 @@ import (
"context"
"encoding/json"
"fmt"
"strings"

"github.com/Masterminds/semver/v3"
kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1"
"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/spf13/cobra"
helmaction "helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/releaseutil"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
ktypes "k8s.io/apimachinery/pkg/types"
"k8s.io/cli-runtime/pkg/genericiooptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/templates"
"sigs.k8s.io/yaml"

"github.com/apecloud/kbcli/pkg/cluster"
"github.com/apecloud/kbcli/pkg/printer"
"github.com/apecloud/kbcli/pkg/util/helm"

"github.com/apecloud/kbcli/pkg/types"
"github.com/apecloud/kbcli/pkg/util"
Expand Down Expand Up @@ -97,6 +110,7 @@ func newUpgradeCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra
o.name = args[0]
util.CheckErr(o.Complete())
util.CheckErr(o.Validate())
util.CheckErr(o.process09ClusterDefAndComponentVersions())
util.CheckErr(o.Run(f, streams))
},
}
Expand Down Expand Up @@ -171,3 +185,109 @@ func (o *upgradeOption) Run(f cmdutil.Factory, streams genericiooptions.IOStream
}
return err
}

func (o *upgradeOption) process09ClusterDefAndComponentVersions() error {
kbDeploys, err := util.GetKBDeploys(o.Client, util.KubeblocksAppComponent, metav1.NamespaceAll)
if err != nil || len(kbDeploys) < 2 {
return err
}
if !strings.HasPrefix(o.currentVersion, "0.9") {
return nil
}
var newKBNamespace string
for _, v := range kbDeploys {
if strings.HasPrefix(v.Labels[constant.AppVersionLabelKey], "1.0") {
newKBNamespace = v.Namespace
break
}
}
// 1. get manifests from the helm repo
chartsDownloader, err := helm.NewDownloader(helm.NewConfig(newKBNamespace, "", "", false))
if err != nil {
return err
}
// DownloadTo can't specify the saved name, so download it to TempDir and rename it when copy
chartPath, _, err := chartsDownloader.DownloadTo(o.addon.Spec.Helm.ChartLocationURL, "", cluster.CliChartsCacheDir)
if err != nil {
return err
}
// 2. overwrite the spec of ClusterDefinition and ComponentVersion with the new version
actionCfg, err := helm.NewActionConfig(helm.NewConfig(newKBNamespace, "", "", false))
if err != nil {
return err
}
chart, err := loader.Load(chartPath)
if err != nil {
return err
}
renderer := helmaction.NewInstall(actionCfg)
renderer.ReleaseName = o.addon.Name + "for-upgrade"
renderer.Namespace = newKBNamespace
renderer.DryRun = true
renderer.Replace = true
renderer.ClientOnly = true
valuesMap := map[string]interface{}{}
if o.addon.Spec.Helm != nil {
for _, v := range o.addon.Spec.Helm.InstallValues.SetValues {
keyValues := strings.Split(v, "=")
if len(keyValues) != 2 {
return fmt.Errorf("invalid install value: %s", v)
}
valuesMap[keyValues[0]] = keyValues[1]
}
}
release, err := renderer.Run(chart, valuesMap)
if err != nil {
return err
}

updateObject := func(obj runtime.Object, gvr schema.GroupVersionResource) error {
unstructuredObj := obj.(*unstructured.Unstructured)
targetObj, err := o.Dynamic.Resource(gvr).Namespace("").Get(context.TODO(), unstructuredObj.GetName(), metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
return nil
}
return err
}
annotations := targetObj.GetAnnotations()
annotations[constant.CRDAPIVersionAnnotationKey] = kbappsv1.GroupVersion.String()
annotations["meta.helm.sh/release-name"] = "kb-addon-" + o.addon.Name
annotations["meta.helm.sh/release-namespace"] = newKBNamespace
targetObj.SetAnnotations(annotations)
targetObj.Object["spec"] = unstructuredObj.Object["spec"]
if _, err = o.Dynamic.Resource(gvr).Namespace("").Update(context.TODO(), targetObj, metav1.UpdateOptions{}); err != nil {
return err
}
return nil
}
manifests := releaseutil.SplitManifests(release.Manifest)
for _, manifest := range manifests {

// convert yaml to json
jsonData, err := yaml.YAMLToJSON([]byte(manifest))
if err != nil {
return err
}
// check if jsonData is empty or null
if len(jsonData) == 0 || string(jsonData) == "null" {
continue
}
// get resource gvk
obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(jsonData, nil, nil)
if err != nil {
return err
}
switch gvk.Kind {
case types.KindClusterDef:
if err = updateObject(obj, types.ClusterDefGVR()); err != nil {
return err
}
case types.KindComponentVersion:
if err = updateObject(obj, types.ComponentVersionsGVR()); err != nil {
return err
}
}
}
return nil
}
Loading
Loading