From e56f15c72b8b7d299706a4224d014a62307ffc41 Mon Sep 17 00:00:00 2001 From: "L.Dongming" Date: Mon, 8 Apr 2024 08:49:35 +0800 Subject: [PATCH 1/4] chore: remove deprecated class command --- addons | 2 +- pkg/cluster/charts/kafka-cluster.tgz | Bin 6102 -> 6107 bytes pkg/cluster/charts/llm-cluster.tgz | Bin 4559 -> 4569 bytes pkg/cluster/charts/redis-cluster.tgz | Bin 5756 -> 5753 bytes pkg/cmd/class/class.go | 40 ---- pkg/cmd/class/class_test.go | 47 ---- pkg/cmd/class/create.go | 309 --------------------------- pkg/cmd/class/create_test.go | 157 -------------- pkg/cmd/class/list.go | 121 ----------- pkg/cmd/class/list_test.go | 106 --------- pkg/cmd/class/suite_test.go | 86 -------- pkg/cmd/class/template.go | 77 ------- pkg/cmd/class/template_test.go | 48 ----- pkg/cmd/class/utils.go | 130 ----------- pkg/cmd/cli.go | 2 - pkg/cmd/cluster/cluster_test.go | 75 ------- pkg/cmd/cluster/create.go | 52 +---- pkg/cmd/cluster/create_test.go | 25 +-- pkg/cmd/cluster/operations.go | 69 ++---- pkg/cmd/cluster/operations_test.go | 26 --- pkg/scheme/install.go | 2 +- 21 files changed, 35 insertions(+), 1339 deletions(-) delete mode 100644 pkg/cmd/class/class.go delete mode 100644 pkg/cmd/class/class_test.go delete mode 100644 pkg/cmd/class/create.go delete mode 100644 pkg/cmd/class/create_test.go delete mode 100644 pkg/cmd/class/list.go delete mode 100644 pkg/cmd/class/list_test.go delete mode 100644 pkg/cmd/class/suite_test.go delete mode 100644 pkg/cmd/class/template.go delete mode 100644 pkg/cmd/class/template_test.go delete mode 100644 pkg/cmd/class/utils.go diff --git a/addons b/addons index a33d64047..2f7d6e970 160000 --- a/addons +++ b/addons @@ -1 +1 @@ -Subproject commit a33d64047247388fa8671b83e67aa2fecf4e8978 +Subproject commit 2f7d6e9708467422f18bc7fe07043f50a6c86089 diff --git a/pkg/cluster/charts/kafka-cluster.tgz b/pkg/cluster/charts/kafka-cluster.tgz index f303d970d2f5f78bdd1f7e6b748668d2253ddecc..91e53c2785e30a9b5f13ca947c768f4289826e71 100644 GIT binary patch delta 5960 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 z z{dNiPk|mE3!Nv@3bt{B*dGLSov^6AZ+c;_6njCLymq+Ui{D%5pZ@GV^^?z?vIsZB8 z@8W;9Qu33*jB?{FNbVh)1Dh5U^4S$a?e!A3dH{3)>SjZF(@}5A<^9y+CCHtt`jyLO z^FPqr^j~NG_eR}OW&RI#`QNruO8b8%y=9X6YON~B5@dY&V&xNNm2Q6$X?;*14WqWb zlH1r_ITP?9zfq6%A-Iw!H1vxt6DeusVe*c_9d6&D?YahzWFM{qI8tuIJKrN$MM?yGq)$q490E+g8nxl$EKy z0=7=%R>4OVz?<0eZ|x=heanXae;RUmn?=C7^WXlU9RJhp4R`zhTPgMXf9ZH1nt3dp z!(9HCwflm()P%{gqDcUGa`yB395Dv=?Z&BM3Ms5~qRHGV5_pw=*Rn&EG^NsX9^xR6 zcLhI5%hURnYfpA-@i0kXR-=-TTjWd=!)kCcy)6-7qc$FG}Ka=aUjd zx1G!1SsWytxwBBGm<%-OBG1-!U6d#;cd?7_1>7d zXa#9X-=wM19<7A3D*M3eTUXb*vet`@&KVcx`!$7~-SkR$O~|*tyOmQ=?QiVeZaDvS z&aYd34S3!B9}bSn^S|rt_J6lh8qR;sc<0@}y6oiZ&xcKGLuwK=zd3^@+n%w1eS<9>W%A3A!@Ev#|E9U>bC4*Z# q|10_5M#J6xukDmw{>17~t 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 diff --git a/pkg/cluster/charts/llm-cluster.tgz b/pkg/cluster/charts/llm-cluster.tgz index 2fc5d32eae6f3cb4ccc957d80922e6522b0253ab..9fb18281b55f87cc233ee5701e731a194b518ff8 100644 GIT binary patch delta 3908 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 S{9gb70RR6A;km~Ega81Xq|DL) delta 3956 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 O0RR7nwO}{^ga80HN!lO) diff --git a/pkg/cluster/charts/redis-cluster.tgz b/pkg/cluster/charts/redis-cluster.tgz index 25c480d13eab0c03adf767e370e48c332ba31804..7e96981be5d371629d65aa48d69f0a9916ddb952 100644 GIT binary patch delta 5230 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 diff --git a/pkg/cmd/class/class.go b/pkg/cmd/class/class.go deleted file mode 100644 index 916de829b..000000000 --- a/pkg/cmd/class/class.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - "github.com/spf13/cobra" - "k8s.io/cli-runtime/pkg/genericiooptions" - cmdutil "k8s.io/kubectl/pkg/cmd/util" -) - -func NewClassCommand(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { - cmd := &cobra.Command{ - Use: "class", - Short: "Manage classes", - Deprecated: "This command is deprecated.", - } - - cmd.AddCommand(NewCreateCommand(f, streams)) - cmd.AddCommand(NewListCommand(f, streams)) - cmd.AddCommand(NewTemplateCmd(streams)) - - return cmd -} diff --git a/pkg/cmd/class/class_test.go b/pkg/cmd/class/class_test.go deleted file mode 100644 index 3a4afd918..000000000 --- a/pkg/cmd/class/class_test.go +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "k8s.io/cli-runtime/pkg/genericiooptions" - cmdtesting "k8s.io/kubectl/pkg/cmd/testing" -) - -var _ = Describe("class", func() { - var streams genericiooptions.IOStreams - var tf *cmdtesting.TestFactory - - BeforeEach(func() { - streams, _, _, _ = genericiooptions.NewTestIOStreams() - tf = cmdtesting.NewTestFactory() - }) - - AfterEach(func() { - tf.Cleanup() - }) - - It("command should succeed", func() { - cmd := NewClassCommand(tf, streams) - Expect(cmd).ShouldNot(BeNil()) - }) -}) diff --git a/pkg/cmd/class/create.go b/pkg/cmd/class/create.go deleted file mode 100644 index 3ef4c1332..000000000 --- a/pkg/cmd/class/create.go +++ /dev/null @@ -1,309 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - "context" - "fmt" - "os" - "strings" - - "github.com/ghodss/yaml" - "github.com/spf13/cobra" - corev1 "k8s.io/api/core/v1" - "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/cli-runtime/pkg/genericiooptions" - "k8s.io/client-go/dynamic" - cmdutil "k8s.io/kubectl/pkg/cmd/util" - utilcomp "k8s.io/kubectl/pkg/util/completion" - "k8s.io/kubectl/pkg/util/templates" - - "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - "github.com/apecloud/kubeblocks/pkg/constant" - "github.com/apecloud/kubeblocks/pkg/controller/component" - - "github.com/apecloud/kbcli/pkg/types" - "github.com/apecloud/kbcli/pkg/util" -) - -type CreateOptions struct { - genericiooptions.IOStreams - - // REVIEW: make this field a parameter which can be set by user - objectName string - - Factory cmdutil.Factory - dynamic dynamic.Interface - ClusterDefRef string - ComponentType string - ClassName string - CPU string - Memory string - File string -} - -var classCreateExamples = templates.Examples(` - # Create a class for component mysql in cluster definition apecloud-mysql, which has 1 CPU core and 1Gi memory - kbcli class create custom-1c1g --cluster-definition apecloud-mysql --type mysql --cpu 1 --memory 1Gi - - # Create classes for component mysql in cluster definition apecloud-mysql, with classes defined in file - kbcli class create --cluster-definition apecloud-mysql --type mysql --file ./classes.yaml -`) - -func NewCreateCommand(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { - o := CreateOptions{IOStreams: streams} - cmd := &cobra.Command{ - Use: "create [NAME]", - Short: "Create a class", - Example: classCreateExamples, - Run: func(cmd *cobra.Command, args []string) { - util.CheckErr(o.complete(f)) - util.CheckErr(o.validate(args)) - util.CheckErr(o.run()) - }, - } - cmd.Flags().StringVar(&o.ClusterDefRef, "cluster-definition", "", "Specify cluster definition, run \"kbcli clusterdefinition list\" to show all available cluster definitions") - util.CheckErr(cmd.MarkFlagRequired("cluster-definition")) - cmd.Flags().StringVar(&o.ComponentType, "type", "", "Specify component type") - util.CheckErr(cmd.MarkFlagRequired("type")) - - cmd.Flags().StringVar(&o.CPU, corev1.ResourceCPU.String(), "", "Specify component CPU cores") - cmd.Flags().StringVar(&o.Memory, corev1.ResourceMemory.String(), "", "Specify component memory size") - - cmd.Flags().StringVar(&o.File, "file", "", "Specify file path of class definition YAML") - - // register flag completion func - registerFlagCompletionFunc(cmd, f) - - return cmd -} - -func (o *CreateOptions) validate(args []string) error { - // validate creating by resource arguments - if o.File != "" { - return nil - } - - // validate cpu and memory - if _, err := resource.ParseQuantity(o.CPU); err != nil { - return err - } - if _, err := resource.ParseQuantity(o.Memory); err != nil { - return err - } - - // validate class name - if len(args) == 0 { - return fmt.Errorf("missing class name") - } - o.ClassName = args[0] - - return nil -} - -func (o *CreateOptions) complete(f cmdutil.Factory) error { - var err error - o.dynamic, err = f.DynamicClient() - return err -} - -func (o *CreateOptions) run() error { - clsMgr, _, err := GetManager(o.dynamic, o.ClusterDefRef) - if err != nil { - return err - } - - constraints, err := GetResourceConstraints(o.dynamic) - if err != nil { - return err - } - - var ( - classInstances []*v1alpha1.ComponentClass - componentClassGroups []v1alpha1.ComponentClassGroup - ) - - if o.File != "" { - data, err := os.ReadFile(o.File) - if err != nil { - return err - } - if err := yaml.Unmarshal(data, &componentClassGroups); err != nil { - return err - } - classDefinition := v1alpha1.ComponentClassDefinition{ - Spec: v1alpha1.ComponentClassDefinitionSpec{Groups: componentClassGroups}, - } - newClasses, err := component.ParseComponentClasses(classDefinition) - if err != nil { - return err - } - for _, cls := range newClasses { - classInstances = append(classInstances, cls) - } - } else { - cls := v1alpha1.ComponentClass{Name: o.ClassName, CPU: resource.MustParse(o.CPU), Memory: resource.MustParse(o.Memory)} - if err != nil { - return err - } - componentClassGroups = []v1alpha1.ComponentClassGroup{ - { - Series: []v1alpha1.ComponentClassSeries{ - { - Classes: []v1alpha1.ComponentClass{cls}, - }, - }, - }, - } - classInstances = append(classInstances, &cls) - } - - var ( - classNames []string - objName = o.objectName - ) - if objName == "" { - objName = GetCustomClassObjectName(o.ClusterDefRef, o.ComponentType) - } - - var rules []v1alpha1.ResourceConstraintRule - for _, constraint := range constraints { - rules = append(rules, constraint.FindRules(o.ClusterDefRef, o.ComponentType)...) - } - - for _, item := range classInstances { - clsDefRef := v1alpha1.ClassDefRef{Name: objName, Class: item.Name} - if clsMgr.HasClass(o.ComponentType, clsDefRef) { - return fmt.Errorf("class name conflicted %s", item.Name) - } - classNames = append(classNames, item.Name) - - if len(rules) == 0 { - continue - } - - match := false - for _, rule := range rules { - if rule.ValidateResources(item.ToResourceRequirements().Requests) { - match = true - break - } - } - if !match { - return fmt.Errorf("class %s does not conform to its constraints", item.Name) - } - } - - obj, err := o.dynamic.Resource(types.ComponentClassDefinitionGVR()).Get(context.TODO(), objName, metav1.GetOptions{}) - if err != nil && !errors.IsNotFound(err) { - return err - } - - var classDefinition v1alpha1.ComponentClassDefinition - if err == nil { - if err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &classDefinition); err != nil { - return err - } - classDefinition.Spec.Groups = append(classDefinition.Spec.Groups, componentClassGroups...) - unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&classDefinition) - if err != nil { - return err - } - if _, err = o.dynamic.Resource(types.ComponentClassDefinitionGVR()).Update( - context.Background(), &unstructured.Unstructured{Object: unstructuredMap}, metav1.UpdateOptions{}); err != nil { - return err - } - } else { - gvr := types.ComponentClassDefinitionGVR() - classDefinition = v1alpha1.ComponentClassDefinition{ - TypeMeta: metav1.TypeMeta{ - Kind: types.KindComponentClassDefinition, - APIVersion: gvr.Group + "/" + gvr.Version, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: GetCustomClassObjectName(o.ClusterDefRef, o.ComponentType), - Labels: map[string]string{ - constant.ClusterDefLabelKey: o.ClusterDefRef, - types.ClassProviderLabelKey: "user", - constant.KBAppComponentDefRefLabelKey: o.ComponentType, - }, - }, - Spec: v1alpha1.ComponentClassDefinitionSpec{ - Groups: componentClassGroups, - }, - } - unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&classDefinition) - if err != nil { - return err - } - if _, err = o.dynamic.Resource(types.ComponentClassDefinitionGVR()).Create( - context.Background(), &unstructured.Unstructured{Object: unstructuredMap}, metav1.CreateOptions{}); err != nil { - return err - } - } - _, _ = fmt.Fprintf(o.Out, "Successfully create class [%s].\n", strings.Join(classNames, ",")) - return nil -} - -func registerFlagCompletionFunc(cmd *cobra.Command, f cmdutil.Factory) { - util.CheckErr(cmd.RegisterFlagCompletionFunc( - "cluster-definition", - func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return utilcomp.CompGetResource(f, util.GVRToString(types.ClusterDefGVR()), toComplete), cobra.ShellCompDirectiveNoFileComp - })) - util.CheckErr(cmd.RegisterFlagCompletionFunc( - "type", - func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - var ( - componentTypes []string - selector string - compTypeLabel = "apps.kubeblocks.io/component-def-ref" - ) - - client, err := f.DynamicClient() - if err != nil { - return componentTypes, cobra.ShellCompDirectiveNoFileComp - } - - clusterDefinition, err := cmd.Flags().GetString("cluster-definition") - if err == nil && clusterDefinition != "" { - selector = fmt.Sprintf("%s=%s,%s", constant.ClusterDefLabelKey, clusterDefinition, types.ClassProviderLabelKey) - } - objs, err := client.Resource(types.ComponentClassDefinitionGVR()).List(context.Background(), metav1.ListOptions{LabelSelector: selector}) - if err != nil { - return componentTypes, cobra.ShellCompDirectiveNoFileComp - } - var classDefinitionList v1alpha1.ComponentClassDefinitionList - if err = runtime.DefaultUnstructuredConverter.FromUnstructured(objs.UnstructuredContent(), &classDefinitionList); err != nil { - return componentTypes, cobra.ShellCompDirectiveNoFileComp - } - for _, item := range classDefinitionList.Items { - componentType := item.Labels[compTypeLabel] - if componentType != "" { - componentTypes = append(componentTypes, componentType) - } - } - return componentTypes, cobra.ShellCompDirectiveNoFileComp - })) -} diff --git a/pkg/cmd/class/create_test.go b/pkg/cmd/class/create_test.go deleted file mode 100644 index d95e66724..000000000 --- a/pkg/cmd/class/create_test.go +++ /dev/null @@ -1,157 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - "bytes" - "fmt" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/cli-runtime/pkg/genericiooptions" - - "k8s.io/client-go/kubernetes/scheme" - cmdtesting "k8s.io/kubectl/pkg/cmd/testing" - - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - - "github.com/apecloud/kbcli/pkg/testing" -) - -var _ = Describe("create", func() { - var ( - createOptions *CreateOptions - out *bytes.Buffer - tf *cmdtesting.TestFactory - streams genericiooptions.IOStreams - ) - - fillResources := func(o *CreateOptions, cpu string, memory string) { - o.CPU = cpu - o.Memory = memory - o.ClassName = fmt.Sprintf("custom-%s-%s", cpu, memory) - } - - BeforeEach(func() { - streams, _, out, _ = genericiooptions.NewTestIOStreams() - tf = testing.NewTestFactory(namespace) - _ = appsv1alpha1.AddToScheme(scheme.Scheme) - createOptions = &CreateOptions{ - IOStreams: streams, - ClusterDefRef: "apecloud-mysql", - ComponentType: "mysql", - } - }) - - AfterEach(func() { - tf.Cleanup() - }) - - It("should succeed to new command", func() { - cmd := NewCreateCommand(tf, streams) - Expect(cmd).ShouldNot(BeNil()) - }) - - Context("with resource arguments", func() { - - Context("without constraints", func() { - BeforeEach(func() { - tf.FakeDynamicClient = testing.FakeDynamicClient(&classDef, &generalResourceConstraintWithoutSelector) - createOptions.Factory = tf - Expect(createOptions.complete(tf)).ShouldNot(HaveOccurred()) - }) - - It("should succeed if component don't have any constraints", func() { - fillResources(createOptions, "1", "100Gi") - Expect(createOptions.run()).ShouldNot(HaveOccurred()) - }) - - }) - - Context("with constraints", func() { - BeforeEach(func() { - tf.FakeDynamicClient = testing.FakeDynamicClient(&classDef, &generalResourceConstraint, &memoryOptimizedResourceConstraint) - createOptions.Factory = tf - Expect(createOptions.complete(tf)).ShouldNot(HaveOccurred()) - }) - - It("should fail if required arguments is missing", func() { - fillResources(createOptions, "", "48Gi") - Expect(createOptions.validate([]string{"general-12c48g"})).Should(HaveOccurred()) - fillResources(createOptions, "12", "") - Expect(createOptions.validate([]string{"general-12c48g"})).Should(HaveOccurred()) - fillResources(createOptions, "12", "48g") - Expect(createOptions.validate([]string{})).Should(HaveOccurred()) - }) - - It("should succeed with required arguments", func() { - fillResources(createOptions, "96", "384Gi") - Expect(createOptions.validate([]string{"general-96c384g"})).ShouldNot(HaveOccurred()) - Expect(createOptions.run()).ShouldNot(HaveOccurred()) - Expect(out.String()).Should(ContainSubstring(createOptions.ClassName)) - }) - - It("should fail if not conformed to constraint", func() { - By("memory not conformed to constraint") - fillResources(createOptions, "2", "9Gi") - Expect(createOptions.run()).Should(HaveOccurred()) - - By("CPU with invalid step") - fillResources(createOptions, "0.6", "0.6Gi") - Expect(createOptions.run()).Should(HaveOccurred()) - }) - - It("should fail if class name is conflicted", func() { - // class may be conflict only within the same object, so we set the objectName to be consistent with the name of the object classDef - createOptions.objectName = "kb.classes.default.apecloud-mysql.mysql" - - fillResources(createOptions, "1", "1Gi") - createOptions.ClassName = "general-1c1g" - Expect(createOptions.run()).Should(HaveOccurred()) - - fillResources(createOptions, "0.5", "0.5Gi") - Expect(createOptions.run()).ShouldNot(HaveOccurred()) - - fillResources(createOptions, "0.5", "0.5Gi") - Expect(createOptions.run()).Should(HaveOccurred()) - }) - }) - }) - - Context("with class definitions file", func() { - BeforeEach(func() { - tf.FakeDynamicClient = testing.FakeDynamicClient(&classDef, &generalResourceConstraint, &memoryOptimizedResourceConstraint) - createOptions.Factory = tf - Expect(createOptions.complete(tf)).ShouldNot(HaveOccurred()) - }) - - It("should succeed", func() { - createOptions.File = testCustomClassDefsPath - Expect(createOptions.run()).ShouldNot(HaveOccurred()) - Expect(out.String()).Should(ContainSubstring("custom-1c1g")) - Expect(out.String()).Should(ContainSubstring("custom-4c16g")) - // memory optimized classes - Expect(out.String()).Should(ContainSubstring("custom-2c16g")) - Expect(out.String()).Should(ContainSubstring("custom-4c64g")) - }) - - }) - -}) diff --git a/pkg/cmd/class/list.go b/pkg/cmd/class/list.go deleted file mode 100644 index afdbc185c..000000000 --- a/pkg/cmd/class/list.go +++ /dev/null @@ -1,121 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - "fmt" - "sort" - "strings" - - "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/cli-runtime/pkg/genericiooptions" - "k8s.io/client-go/dynamic" - cmdutil "k8s.io/kubectl/pkg/cmd/util" - "k8s.io/kubectl/pkg/util/templates" - - "github.com/apecloud/kubeblocks/pkg/controller/component" - - "github.com/apecloud/kbcli/pkg/printer" - "github.com/apecloud/kbcli/pkg/util" - "github.com/apecloud/kbcli/pkg/util/flags" -) - -type ListOptions struct { - ClusterDefRef string - Factory cmdutil.Factory - dynamic dynamic.Interface - genericiooptions.IOStreams -} - -var listClassExamples = templates.Examples(` - # List all components classes in cluster definition apecloud-mysql - kbcli class list --cluster-definition apecloud-mysql -`) - -func NewListCommand(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { - o := &ListOptions{IOStreams: streams} - cmd := &cobra.Command{ - Use: "list", - Short: "List classes", - Example: listClassExamples, - Run: func(cmd *cobra.Command, args []string) { - util.CheckErr(o.complete(f)) - util.CheckErr(o.run()) - }, - } - flags.AddClusterDefinitionFlag(f, cmd, &o.ClusterDefRef) - util.CheckErr(cmd.MarkFlagRequired("cluster-definition")) - return cmd -} - -func (o *ListOptions) complete(f cmdutil.Factory) error { - var err error - o.dynamic, err = f.DynamicClient() - return err -} - -func (o *ListOptions) run() error { - clsMgr, _, err := GetManager(o.dynamic, o.ClusterDefRef) - if err != nil { - return err - } - for compName, classes := range clsMgr.GetClasses() { - o.printClass(compName, classes) - } - return nil -} - -func (o *ListOptions) printClass(compName string, classes []*component.ComponentClassWithRef) { - tbl := printer.NewTablePrinter(o.Out) - tbl.SetHeader("COMPONENT", "CLASS", "CPU", "MEMORY") - sort.Sort(component.ByClassResource(classes)) - for _, cls := range classes { - tbl.AddRow(compName, cls.Name, cls.CPU.String(), normalizeMemory(cls.Memory)) - } - tbl.Print() -} - -func normalizeMemory(mem resource.Quantity) string { - if !strings.HasSuffix(mem.String(), "m") { - return mem.String() - } - - var ( - value float64 - suffix string - bytes = float64(mem.MilliValue()) / 1000 - ) - switch { - case bytes < 1024: - value = bytes / 1024 - suffix = "Ki" - case bytes < 1024*1024: - value = bytes / 1024 / 1024 - suffix = "Mi" - case bytes < 1024*1024*1024: - value = bytes / 1024 / 1024 / 1024 - suffix = "Gi" - default: - value = bytes / 1024 / 1024 / 1024 / 1024 - suffix = "Ti" - } - return strings.TrimRight(fmt.Sprintf("%.3f", value), "0") + suffix -} diff --git a/pkg/cmd/class/list_test.go b/pkg/cmd/class/list_test.go deleted file mode 100644 index f549d8705..000000000 --- a/pkg/cmd/class/list_test.go +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - "bytes" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/cli-runtime/pkg/genericiooptions" - "k8s.io/client-go/kubernetes/scheme" - cmdtesting "k8s.io/kubectl/pkg/cmd/testing" - - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - - "github.com/apecloud/kbcli/pkg/testing" -) - -var _ = Describe("list", func() { - var ( - out *bytes.Buffer - tf *cmdtesting.TestFactory - streams genericiooptions.IOStreams - ) - - BeforeEach(func() { - streams, _, out, _ = genericiooptions.NewTestIOStreams() - tf = testing.NewTestFactory(namespace) - _ = appsv1alpha1.AddToScheme(scheme.Scheme) - tf.FakeDynamicClient = testing.FakeDynamicClient(&classDef) - }) - - AfterEach(func() { - tf.Cleanup() - }) - - It("should succeed", func() { - cmd := NewListCommand(tf, streams) - Expect(cmd).ShouldNot(BeNil()) - _ = cmd.Flags().Set("cluster-definition", "apecloud-mysql") - cmd.Run(cmd, []string{}) - Expect(out.String()).To(ContainSubstring("general-1c1g")) - Expect(out.String()).To(ContainSubstring("mysql")) - }) - - It("memory should be normalized", func() { - cases := []struct { - memory string - normalized string - }{ - { - memory: "0.2Gi", - normalized: "0.2Gi", - }, - { - memory: "0.2Mi", - normalized: "0.2Mi", - }, - { - memory: "0.2Ki", - normalized: "0.2Ki", - }, - { - memory: "1024Mi", - normalized: "1Gi", - }, - { - memory: "1025Mi", - normalized: "1025Mi", - }, - { - memory: "1023Mi", - normalized: "1023Mi", - }, - { - memory: "1Gi", - normalized: "1Gi", - }, - { - memory: "512Mi", - normalized: "512Mi", - }, - } - for _, item := range cases { - Expect(normalizeMemory(resource.MustParse(item.memory))).Should(Equal(item.normalized)) - } - }) -}) diff --git a/pkg/cmd/class/suite_test.go b/pkg/cmd/class/suite_test.go deleted file mode 100644 index d80ed5c58..000000000 --- a/pkg/cmd/class/suite_test.go +++ /dev/null @@ -1,86 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - "os" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/yaml" - "k8s.io/client-go/kubernetes/scheme" - - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" -) - -const ( - namespace = "test" - testDefaultClassDefsPath = "../../testing/testdata/class.yaml" - testCustomClassDefsPath = "../../testing/testdata/custom_class.yaml" - testGeneralResourceConstraintPath = "../../testing/testdata/resource-constraint-general.yaml" - testMemoryOptimizedResourceConstraintPath = "../../testing/testdata/resource-constraint-memory-optimized.yaml" - testGeneralResourceConstraintWithoutSelectorPath = "../../testing/testdata/resource-constraint-general-without-selector.yaml" -) - -var ( - classDef appsv1alpha1.ComponentClassDefinition - generalResourceConstraint appsv1alpha1.ComponentResourceConstraint - generalResourceConstraintWithoutSelector appsv1alpha1.ComponentResourceConstraint - memoryOptimizedResourceConstraint appsv1alpha1.ComponentResourceConstraint -) - -var _ = BeforeSuite(func() { - var err error - - classDefBytes, err := os.ReadFile(testDefaultClassDefsPath) - Expect(err).ShouldNot(HaveOccurred()) - err = yaml.Unmarshal(classDefBytes, &classDef) - Expect(err).ShouldNot(HaveOccurred()) - - generalResourceConstraintBytes, err := os.ReadFile(testGeneralResourceConstraintPath) - Expect(err).ShouldNot(HaveOccurred()) - err = yaml.Unmarshal(generalResourceConstraintBytes, &generalResourceConstraint) - Expect(err).ShouldNot(HaveOccurred()) - - generalResourceConstraintWithoutSelectorBytes, err := os.ReadFile(testGeneralResourceConstraintWithoutSelectorPath) - Expect(err).ShouldNot(HaveOccurred()) - err = yaml.Unmarshal(generalResourceConstraintWithoutSelectorBytes, &generalResourceConstraintWithoutSelector) - Expect(err).ShouldNot(HaveOccurred()) - - memoryOptimizedResourceConstraintBytes, err := os.ReadFile(testMemoryOptimizedResourceConstraintPath) - Expect(err).ShouldNot(HaveOccurred()) - err = yaml.Unmarshal(memoryOptimizedResourceConstraintBytes, &memoryOptimizedResourceConstraint) - Expect(err).ShouldNot(HaveOccurred()) - - err = appsv1alpha1.AddToScheme(scheme.Scheme) - Expect(err).ShouldNot(HaveOccurred()) - - err = corev1.AddToScheme(scheme.Scheme) - Expect(err).ShouldNot(HaveOccurred()) - -}) - -func TestClass(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Class Suite") -} diff --git a/pkg/cmd/class/template.go b/pkg/cmd/class/template.go deleted file mode 100644 index b380fd17d..000000000 --- a/pkg/cmd/class/template.go +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - "fmt" - "os" - - "github.com/spf13/cobra" - "k8s.io/cli-runtime/pkg/genericiooptions" - - "github.com/apecloud/kbcli/pkg/util" -) - -const ComponentClassTemplate = ` -- # class template, you can declare variables and set default values here - template: | - cpu: "{{ or .cpu 1 }}" - memory: "{{ or .memory 4 }}Gi" - # template variables used to define classes - vars: [cpu, memory] - series: - - # class naming template, you can reference variables in class template - # it's also ok to define static class name in the following class definitions - namingTemplate: "custom-{{ .cpu }}c{{ .memory }}g" - - # class definitions, we support two kinds of class definitions: - # 1. dynamically classes rendered with defined values & template variables - # 2. statically defined classes - classes: - - args: [1, 1] -` - -type TemplateOptions struct { - genericiooptions.IOStreams - - outputFile string -} - -func NewTemplateCmd(streams genericiooptions.IOStreams) *cobra.Command { - o := &TemplateOptions{IOStreams: streams} - cmd := &cobra.Command{ - Use: "template", - Short: "Generate class definition template", - Run: func(cmd *cobra.Command, args []string) { - util.CheckErr(o.run()) - }, - } - cmd.Flags().StringVarP(&o.outputFile, "output", "o", "", "Output class definition template to a file") - return cmd -} - -func (o *TemplateOptions) run() error { - if o.outputFile != "" { - return os.WriteFile(o.outputFile, []byte(ComponentClassTemplate), 0644) - } - - _, err := fmt.Fprint(o.Out, ComponentClassTemplate) - return err -} diff --git a/pkg/cmd/class/template_test.go b/pkg/cmd/class/template_test.go deleted file mode 100644 index d138ab7c3..000000000 --- a/pkg/cmd/class/template_test.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - "bytes" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "k8s.io/cli-runtime/pkg/genericiooptions" -) - -var _ = Describe("template", func() { - var ( - out *bytes.Buffer - streams genericiooptions.IOStreams - ) - - BeforeEach(func() { - streams, _, out, _ = genericiooptions.NewTestIOStreams() - }) - - It("command should succeed", func() { - cmd := NewTemplateCmd(streams) - Expect(cmd).ShouldNot(BeNil()) - - cmd.Run(cmd, []string{}) - Expect(out.String()).ShouldNot(BeEmpty()) - }) -}) diff --git a/pkg/cmd/class/utils.go b/pkg/cmd/class/utils.go deleted file mode 100644 index 08e963fa7..000000000 --- a/pkg/cmd/class/utils.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package class - -import ( - "context" - "fmt" - - "github.com/apecloud/kubeblocks/pkg/controller/component" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/dynamic" - - "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - "github.com/apecloud/kubeblocks/pkg/constant" - - "github.com/apecloud/kbcli/pkg/types" -) - -// GetManager gets a class manager which manages default classes and user custom classes -func GetManager(client dynamic.Interface, cdName string) (*component.Manager, *v1alpha1.ComponentResourceConstraintList, error) { - selector := fmt.Sprintf("%s=%s,%s", constant.ClusterDefLabelKey, cdName, types.ClassProviderLabelKey) - classObjs, err := client.Resource(types.ComponentClassDefinitionGVR()).Namespace("").List(context.TODO(), metav1.ListOptions{ - LabelSelector: selector, - }) - if err != nil { - return nil, nil, err - } - var classDefinitionList v1alpha1.ComponentClassDefinitionList - if err = runtime.DefaultUnstructuredConverter.FromUnstructured(classObjs.UnstructuredContent(), &classDefinitionList); err != nil { - return nil, nil, err - } - - constraintObjs, err := client.Resource(types.ComponentResourceConstraintGVR()).Namespace("").List(context.TODO(), metav1.ListOptions{}) - if err != nil { - return nil, nil, err - } - var resourceConstraintList v1alpha1.ComponentResourceConstraintList - if err = runtime.DefaultUnstructuredConverter.FromUnstructured(constraintObjs.UnstructuredContent(), &resourceConstraintList); err != nil { - return nil, nil, err - } - mgr, err := component.NewManager(classDefinitionList, resourceConstraintList) - return mgr, &resourceConstraintList, err -} - -// GetResourceConstraints gets all resource constraints -func GetResourceConstraints(dynamic dynamic.Interface) (map[string]*v1alpha1.ComponentResourceConstraint, error) { - objs, err := dynamic.Resource(types.ComponentResourceConstraintGVR()).List(context.TODO(), metav1.ListOptions{ - // LabelSelector: types.ResourceConstraintProviderLabelKey, - }) - if err != nil { - return nil, err - } - var constraintsList v1alpha1.ComponentResourceConstraintList - if err = runtime.DefaultUnstructuredConverter.FromUnstructured(objs.UnstructuredContent(), &constraintsList); err != nil { - return nil, err - } - - result := make(map[string]*v1alpha1.ComponentResourceConstraint) - for idx := range constraintsList.Items { - cf := constraintsList.Items[idx] - if _, ok := cf.GetLabels()[constant.ResourceConstraintProviderLabelKey]; !ok { - continue - } - result[cf.GetName()] = &cf - } - return result, nil -} - -// GetCustomClassObjectName returns the name of the ComponentClassDefinition object containing the custom classes -func GetCustomClassObjectName(cdName string, componentName string) string { - return fmt.Sprintf("kb.classes.custom.%s.%s", cdName, componentName) -} - -func ValidateResources(clsMGR *component.Manager, - resourceConstraintList *v1alpha1.ComponentResourceConstraintList, - clusterDefRef string, - comp *v1alpha1.ClusterComponentSpec) error { - if comp.ClassDefRef != nil && comp.ClassDefRef.Class != "" { - if clsMGR.HasClass(comp.ComponentDefRef, *comp.ClassDefRef) { - return nil - } - return fmt.Errorf("class not found") - } - - var rules []v1alpha1.ResourceConstraintRule - for _, constraint := range resourceConstraintList.Items { - rules = append(rules, constraint.FindRules(clusterDefRef, comp.ComponentDefRef)...) - } - if len(rules) == 0 { - return nil - } - - for _, rule := range rules { - if !rule.ValidateResources(comp.Resources.Requests) { - continue - } - - // validate volume - match := true - // all volumes should match the rules - for _, volume := range comp.VolumeClaimTemplates { - if !rule.ValidateStorage(volume.Spec.Resources.Requests.Storage()) { - match = false - break - } - } - if match { - return nil - } - } - return fmt.Errorf("resource is not conform to the constraints, please check the ComponentResourceConstraint API") -} diff --git a/pkg/cmd/cli.go b/pkg/cmd/cli.go index 3ae3ff5db..936e48e18 100644 --- a/pkg/cmd/cli.go +++ b/pkg/cmd/cli.go @@ -43,7 +43,6 @@ import ( "github.com/apecloud/kbcli/pkg/cmd/backuprepo" "github.com/apecloud/kbcli/pkg/cmd/bench" "github.com/apecloud/kbcli/pkg/cmd/builder" - "github.com/apecloud/kbcli/pkg/cmd/class" "github.com/apecloud/kbcli/pkg/cmd/cluster" "github.com/apecloud/kbcli/pkg/cmd/clusterdefinition" "github.com/apecloud/kbcli/pkg/cmd/clusterversion" @@ -202,7 +201,6 @@ A Command Line Interface for KubeBlocks`, dashboard.NewDashboardCmd(f, ioStreams), clusterversion.NewClusterVersionCmd(f, ioStreams), clusterdefinition.NewClusterDefinitionCmd(f, ioStreams), - class.NewClassCommand(f, ioStreams), alert.NewAlertCmd(f, ioStreams), addon.NewAddonCmd(f, ioStreams), migration.NewMigrationCmd(f, ioStreams), diff --git a/pkg/cmd/cluster/cluster_test.go b/pkg/cmd/cluster/cluster_test.go index 9c1601023..fe126e1fe 100644 --- a/pkg/cmd/cluster/cluster_test.go +++ b/pkg/cmd/cluster/cluster_test.go @@ -177,69 +177,6 @@ var _ = Describe("Cluster", func() { Expect(o.Validate()).Should(HaveOccurred()) }) - It("should succeed if component with valid class", func() { - o.Values = []string{fmt.Sprintf("type=%s,class=%s", testing.ComponentDefName, testapps.Class1c1gName)} - Expect(o.Complete()).Should(Succeed()) - Expect(o.Validate()).Should(Succeed()) - Run() - }) - - It("should fail if component with invalid class", func() { - o.Values = []string{fmt.Sprintf("type=%s,class=class-not-exists", testing.ComponentDefName)} - Expect(o.Complete()).Should(HaveOccurred()) - }) - - It("should succeed if component with resource meets the resource constraint", func() { - o.Values = []string{fmt.Sprintf("type=%s,cpu=1,memory=1Gi", testing.ComponentDefName)} - Expect(o.Complete()).Should(Succeed()) - Expect(o.Validate()).Should(Succeed()) - Run() - }) - - It("should succeed if component with resource with smaller unit meets the constraint", func() { - o.Values = []string{fmt.Sprintf("type=%s,cpu=1000m,memory=1024Mi", testing.ComponentDefName)} - Expect(o.Complete()).Should(Succeed()) - Expect(o.Validate()).Should(Succeed()) - Run() - }) - - It("should fail if component with resource not meets the constraint", func() { - o.Values = []string{fmt.Sprintf("type=%s,cpu=1,memory=100Gi", testing.ComponentDefName)} - Expect(o.Complete()).Should(HaveOccurred()) - }) - - It("should succeed if component with cpu meets the constraint", func() { - o.Values = []string{fmt.Sprintf("type=%s,cpu=1", testing.ComponentDefName)} - Expect(o.Complete()).Should(Succeed()) - Expect(o.Validate()).Should(Succeed()) - Run() - }) - - It("should fail if component with cpu not meets the constraint", func() { - o.Values = []string{fmt.Sprintf("type=%s,cpu=1024", testing.ComponentDefName)} - Expect(o.Complete()).Should(HaveOccurred()) - }) - - It("should fail if component with memory not meets the constraint", func() { - o.Values = []string{fmt.Sprintf("type=%s,memory=1Ti", testing.ComponentDefName)} - Expect(o.Complete()).Should(HaveOccurred()) - }) - - It("should succeed if component doesn't have class definition", func() { - o.Values = []string{fmt.Sprintf("type=%s,cpu=3,memory=7Gi", testing.ExtraComponentDefName)} - Expect(o.Complete()).Should(Succeed()) - Expect(o.Validate()).Should(Succeed()) - Run() - }) - - It("should fail if component with storage not meets the constraint", func() { - o.Values = []string{fmt.Sprintf("type=%s,storage=500Mi", testing.ComponentDefName)} - Expect(o.Complete()).Should(HaveOccurred()) - - o.Values = []string{fmt.Sprintf("type=%s,storage=1Pi", testing.ComponentDefName)} - Expect(o.Complete()).Should(HaveOccurred()) - }) - It("should fail if create cluster by non-existed file", func() { o.SetFile = "test.yaml" Expect(o.Complete()).Should(HaveOccurred()) @@ -259,13 +196,6 @@ var _ = Describe("Cluster", func() { Run() }) - It("should succeed if create cluster by file with class", func() { - o.SetFile = testComponentWithClassPath - Expect(o.Complete()).Should(Succeed()) - Expect(o.Validate()).Should(Succeed()) - Run() - }) - It("should succeed if create cluster by file with resource", func() { o.SetFile = testComponentWithResourcePath Expect(o.Complete()).Should(Succeed()) @@ -273,11 +203,6 @@ var _ = Describe("Cluster", func() { Run() }) - It("should fail if create cluster by file with non-existed class", func() { - o.SetFile = testComponentWithInvalidClassPath - Expect(o.Complete()).Should(HaveOccurred()) - }) - It("should succeed if create cluster with a complete config file", func() { o.SetFile = testClusterPath Expect(o.Complete()).Should(Succeed()) diff --git a/pkg/cmd/cluster/create.go b/pkg/cmd/cluster/create.go index e2dfeacad..9c84ace77 100755 --- a/pkg/cmd/cluster/create.go +++ b/pkg/cmd/cluster/create.go @@ -31,7 +31,6 @@ import ( "strconv" "strings" - "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/ghodss/yaml" "github.com/robfig/cron/v3" "github.com/spf13/cobra" @@ -63,7 +62,6 @@ import ( "github.com/apecloud/kbcli/pkg/action" "github.com/apecloud/kbcli/pkg/cluster" - classutil "github.com/apecloud/kbcli/pkg/cmd/class" "github.com/apecloud/kbcli/pkg/printer" "github.com/apecloud/kbcli/pkg/types" "github.com/apecloud/kbcli/pkg/util" @@ -166,7 +164,6 @@ type setKey string const ( keyType setKey = "type" keyCPU setKey = "cpu" - keyClass setKey = "class" keyMemory setKey = "memory" keyReplicas setKey = "replicas" keyStorage setKey = "storage" @@ -293,7 +290,7 @@ func NewCreateCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra. cmd.Flags().StringVar(&o.ClusterDefRef, "cluster-definition", "", "Specify cluster definition, run \"kbcli cd list\" to show all available cluster definitions") cmd.Flags().StringVar(&o.ClusterVersionRef, "cluster-version", "", "Specify cluster version, run \"kbcli cv list\" to show all available cluster versions, use the latest version if not specified") cmd.Flags().StringVarP(&o.SetFile, "set-file", "f", "", "Use yaml file, URL, or stdin to set the cluster resource") - cmd.Flags().StringArrayVar(&o.Values, "set", []string{}, "Set the cluster resource including cpu, memory, replicas and storage, each set corresponds to a component.(e.g. --set cpu=1,memory=1Gi,replicas=3,storage=20Gi or --set class=general-1c1g)") + cmd.Flags().StringArrayVar(&o.Values, "set", []string{}, "Set the cluster resource including cpu, memory, replicas and storage, each set corresponds to a component.(e.g. --set cpu=1,memory=1Gi,replicas=3,storage=20Gi)") cmd.Flags().BoolVar(&o.CreateOnlySet, "create-only-set", false, "Create components exclusively configured in 'set'") cmd.Flags().StringArrayVar(&o.Storages, "pvc", []string{}, "Set the cluster detail persistent volume claim, each '--pvc' corresponds to a component, and will override the simple configurations about storage by --set (e.g. --pvc type=mysql,name=data,mode=ReadWriteOnce,size=20Gi --pvc type=mysql,name=log,mode=ReadWriteOnce,size=1Gi)") cmd.Flags().StringArrayVar(&o.ServiceRef, "service-reference", []string{}, "Set the other KubeBlocks cluster dependencies, each '--service-reference' corresponds to a cluster service. (e.g --service-reference name=pulsarZookeeper,cluster=zookeeper,namespace=default)") @@ -589,10 +586,6 @@ func (o *CreateOptions) buildComponents(clusterCompSpecs []appsv1alpha1.ClusterC if err != nil { return nil, err } - clsMgr, resourceConstraintList, err := classutil.GetManager(o.Dynamic, o.ClusterDefRef) - if err != nil { - return nil, err - } compSets, err := buildCompSetsMap(o.Values, cd) if err != nil { @@ -613,8 +606,6 @@ func (o *CreateOptions) buildComponents(clusterCompSpecs []appsv1alpha1.ClusterC case keyCPU: comp.Resources.Requests[corev1.ResourceCPU] = setComp.Resources.Requests[corev1.ResourceCPU] comp.Resources.Limits[corev1.ResourceCPU] = setComp.Resources.Limits[corev1.ResourceCPU] - case keyClass: - comp.ClassDefRef = setComp.ClassDefRef case keyMemory: comp.Resources.Requests[corev1.ResourceMemory] = setComp.Resources.Requests[corev1.ResourceMemory] comp.Resources.Limits[corev1.ResourceMemory] = setComp.Resources.Limits[corev1.ResourceMemory] @@ -633,7 +624,7 @@ func (o *CreateOptions) buildComponents(clusterCompSpecs []appsv1alpha1.ClusterC } if clusterCompSpecs != nil { - setsCompSpecs, err := buildClusterComp(cd, compSets, clsMgr, o.MonitoringInterval, o.CreateOnlySet) + setsCompSpecs, err := buildClusterComp(cd, compSets, o.MonitoringInterval, o.CreateOnlySet) if err != nil { return nil, err } @@ -647,7 +638,7 @@ func (o *CreateOptions) buildComponents(clusterCompSpecs []appsv1alpha1.ClusterC compSpecs = append(compSpecs, &comp) } } else { - compSpecs, err = buildClusterComp(cd, compSets, clsMgr, o.MonitoringInterval, o.CreateOnlySet) + compSpecs, err = buildClusterComp(cd, compSets, o.MonitoringInterval, o.CreateOnlySet) if err != nil { return nil, err } @@ -667,11 +658,6 @@ func (o *CreateOptions) buildComponents(clusterCompSpecs []appsv1alpha1.ClusterC var comps []map[string]interface{} for _, compSpec := range compSpecs { - // validate component classes - if err = classutil.ValidateResources(clsMgr, resourceConstraintList, o.ClusterDefRef, compSpec); err != nil { - return nil, err - } - // cpu oversell if o.CPUOversellRatio > 1 { cpuRequest := compSpec.Resources.Requests[corev1.ResourceCPU] @@ -1006,7 +992,6 @@ func setEnableAllLogs(c *appsv1alpha1.Cluster, cd *appsv1alpha1.ClusterDefinitio func buildClusterComp(cd *appsv1alpha1.ClusterDefinition, setsMap map[string]map[setKey]string, - clsMgr *component.Manager, monitoringInterval uint8, createOnlySet bool) ([]*appsv1alpha1.ClusterComponentSpec, error) { // get value from set values and environment variables, the second return value is @@ -1106,33 +1091,9 @@ func buildClusterComp(cd *appsv1alpha1.ClusterDefinition, Replicas: int32(setReplicas), } - // class has higher priority than other resource related parameters - resourceList := make(corev1.ResourceList) - if clsMgr.HasClass(compObj.ComponentDefRef, component.Any) { - if className := getVal(&c, keyClass, sets); className != "" { - clsDefRef := appsv1alpha1.ClassDefRef{} - parts := strings.SplitN(className, ":", 2) - if len(parts) == 1 { - clsDefRef.Class = parts[0] - } else { - clsDefRef.Name = parts[0] - clsDefRef.Class = parts[1] - } - compObj.ClassDefRef = &clsDefRef - } else { - resourceList = corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse(getVal(&c, keyCPU, sets)), - corev1.ResourceMemory: resource.MustParse(getVal(&c, keyMemory, sets)), - } - } - } else { - if className := getVal(&c, keyClass, sets); className != "" { - return nil, fmt.Errorf("can not find class %s for component type %s", className, c.Name) - } - resourceList = corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse(getVal(&c, keyCPU, sets)), - corev1.ResourceMemory: resource.MustParse(getVal(&c, keyMemory, sets)), - } + resourceList := corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse(getVal(&c, keyCPU, sets)), + corev1.ResourceMemory: resource.MustParse(getVal(&c, keyMemory, sets)), } compObj.Resources = corev1.ResourceRequirements{ // deepcopy to make requests and limits point to different resources @@ -1621,7 +1582,6 @@ func setKeys() []string { string(keyStorage), string(keyMemory), string(keyReplicas), - string(keyClass), string(keyStorageClass), string(keySwitchPolicy), string(keyMonitor), diff --git a/pkg/cmd/cluster/create_test.go b/pkg/cmd/cluster/create_test.go index 284eec4ea..d4419afd0 100644 --- a/pkg/cmd/cluster/create_test.go +++ b/pkg/cmd/cluster/create_test.go @@ -28,7 +28,6 @@ import ( "strings" "time" - "github.com/apecloud/kubeblocks/pkg/controller/component" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" @@ -65,8 +64,6 @@ func getResource(res corev1.ResourceRequirements, name corev1.ResourceName) inte } var _ = Describe("create", func() { - var clsMgr = &component.Manager{} - Context("setEnableAllLogs Test", func() { var cluster *appsv1alpha1.Cluster var clusterDef *appsv1alpha1.ClusterDefinition @@ -140,13 +137,12 @@ var _ = Describe("create", func() { } else { Expect(*comp.VolumeClaimTemplates[0].Spec.StorageClassName).Should(Equal(storageClassName)) } - } It("build default cluster component without environment", func() { dynamic := testing.FakeDynamicClient(testing.FakeClusterDef()) cd, _ := cluster.GetClusterDefByName(dynamic, testing.ClusterDefName) - comps, err := buildClusterComp(cd, nil, clsMgr, 15, false) + comps, err := buildClusterComp(cd, nil, 15, false) Expect(err).ShouldNot(HaveOccurred()) checkComponent(comps, "20Gi", 1, "1", "1Gi", "", 0) }) @@ -158,7 +154,7 @@ var _ = Describe("create", func() { viper.Set(types.CfgKeyClusterDefaultMemory, "2Gi") dynamic := testing.FakeDynamicClient(testing.FakeClusterDef()) cd, _ := cluster.GetClusterDefByName(dynamic, testing.ClusterDefName) - comps, err := buildClusterComp(cd, nil, clsMgr, 15, false) + comps, err := buildClusterComp(cd, nil, 15, false) Expect(err).ShouldNot(HaveOccurred()) checkComponent(comps, "5Gi", 1, "2", "2Gi", "", 0) }) @@ -175,13 +171,13 @@ var _ = Describe("create", func() { keyStorageClass: "test", }, } - comps, err := buildClusterComp(cd, setsMap, clsMgr, 0, false) + comps, err := buildClusterComp(cd, setsMap, 0, false) Expect(err).Should(Succeed()) checkComponent(comps, "10Gi", 10, "10", "2Gi", "test", 0) setsMap[testing.ComponentDefName][keySwitchPolicy] = "invalid" cd.Spec.ComponentDefs[0].WorkloadType = appsv1alpha1.Replication - _, err = buildClusterComp(cd, setsMap, clsMgr, 0, false) + _, err = buildClusterComp(cd, setsMap, 0, false) Expect(err).Should(HaveOccurred()) }) @@ -203,13 +199,13 @@ var _ = Describe("create", func() { keyStorageClass: "test-other", }, } - comps, err := buildClusterComp(cd, setsMap, clsMgr, 15, false) + comps, err := buildClusterComp(cd, setsMap, 15, false) Expect(err).Should(Succeed()) checkComponent(comps, "10Gi", 10, "10", "2Gi", "test", 0) checkComponent(comps, "5Gi", 5, "5", "1Gi", "test-other", 1) setsMap[testing.ComponentDefName][keySwitchPolicy] = "invalid" cd.Spec.ComponentDefs[0].WorkloadType = appsv1alpha1.Replication - _, err = buildClusterComp(cd, setsMap, clsMgr, 15, false) + _, err = buildClusterComp(cd, setsMap, 15, false) Expect(err).Should(HaveOccurred()) }) @@ -250,14 +246,13 @@ var _ = Describe("create", func() { true, }, { - []string{"cpu=1,memory=2Gi,storage=10Gi,class=general-1c2g"}, + []string{"cpu=1,memory=2Gi,storage=10Gi"}, []string{"my-comp"}, map[string]map[setKey]string{ "my-comp": { keyCPU: "1", keyMemory: "2Gi", keyStorage: "10Gi", - keyClass: "general-1c2g", }, }, true, @@ -316,20 +311,18 @@ var _ = Describe("create", func() { true, }, { - []string{"type=comp1,cpu=1,memory=2Gi,class=general-2c4g", "type=comp2,storage=10Gi,cpu=2,class=mo-1c8g,replicas=3"}, + []string{"type=comp1,cpu=1,memory=2Gi", "type=comp2,storage=10Gi,cpu=2,replicas=3"}, []string{"comp1", "comp2"}, map[string]map[setKey]string{ "comp1": { keyType: "comp1", keyCPU: "1", keyMemory: "2Gi", - keyClass: "general-2c4g", }, "comp2": { keyType: "comp2", keyCPU: "2", keyStorage: "10Gi", - keyClass: "mo-1c8g", keyReplicas: "3", }, }, @@ -650,7 +643,7 @@ var _ = Describe("create", func() { }) It("rebuild clusterComponentSpec VolumeClaimTemplates by --pvc", func() { - comps, err := buildClusterComp(mockCD([]string{"comp1", "comp2"}), nil, clsMgr, 0, false) + comps, err := buildClusterComp(mockCD([]string{"comp1", "comp2"}), nil, 0, false) Expect(err).Should(Succeed()) Expect(comps).ShouldNot(BeNil()) diff --git a/pkg/cmd/cluster/operations.go b/pkg/cmd/cluster/operations.go index d8978bae9..85205a4ac 100755 --- a/pkg/cmd/cluster/operations.go +++ b/pkg/cmd/cluster/operations.go @@ -49,7 +49,6 @@ import ( "github.com/apecloud/kbcli/pkg/action" "github.com/apecloud/kbcli/pkg/cluster" - classutil "github.com/apecloud/kbcli/pkg/cmd/class" "github.com/apecloud/kbcli/pkg/printer" "github.com/apecloud/kbcli/pkg/types" "github.com/apecloud/kbcli/pkg/util" @@ -79,10 +78,8 @@ type OperationsOptions struct { ClusterVersionRef string `json:"clusterVersionRef"` // VerticalScaling options - CPU string `json:"cpu"` - Memory string `json:"memory"` - Class string `json:"class"` - ClassDefRef appsv1alpha1.ClassDefRef `json:"classDefRef,omitempty"` + CPU string `json:"cpu"` + Memory string `json:"memory"` // HorizontalScaling options Replicas int `json:"replicas"` @@ -374,50 +371,28 @@ func (o *OperationsOptions) validateVolumeExpansion() error { } func (o *OperationsOptions) validateVScale(cluster *appsv1alpha1.Cluster) error { - if o.Class != "" && (o.CPU != "" || o.Memory != "") { - return fmt.Errorf("class and cpu/memory cannot be both specified") - } - if o.Class == "" && o.CPU == "" && o.Memory == "" { - return fmt.Errorf("class or cpu/memory must be specified") - } - - clsMgr, resourceConstraintList, err := classutil.GetManager(o.Dynamic, cluster.Spec.ClusterDefRef) - if err != nil { - return err + if o.CPU == "" && o.Memory == "" { + return fmt.Errorf("cpu or memory must be specified") } fillClassParams := func(comp *appsv1alpha1.ClusterComponentSpec) error { - if o.Class != "" { - clsDefRef := appsv1alpha1.ClassDefRef{} - parts := strings.SplitN(o.Class, ":", 2) - if len(parts) == 1 { - clsDefRef.Class = parts[0] - } else { - clsDefRef.Name = parts[0] - clsDefRef.Class = parts[1] - } - comp.ClassDefRef = &clsDefRef - comp.Resources = corev1.ResourceRequirements{} - } else { - comp.ClassDefRef = &appsv1alpha1.ClassDefRef{} - requests := make(corev1.ResourceList) - if o.CPU != "" { - cpu, err := resource.ParseQuantity(o.CPU) - if err != nil { - return fmt.Errorf("cannot parse '%v', %v", o.CPU, err) - } - requests[corev1.ResourceCPU] = cpu + requests := make(corev1.ResourceList) + if o.CPU != "" { + cpu, err := resource.ParseQuantity(o.CPU) + if err != nil { + return fmt.Errorf("cannot parse '%v', %v", o.CPU, err) } - if o.Memory != "" { - memory, err := resource.ParseQuantity(o.Memory) - if err != nil { - return fmt.Errorf("cannot parse '%v', %v", o.Memory, err) - } - requests[corev1.ResourceMemory] = memory + requests[corev1.ResourceCPU] = cpu + } + if o.Memory != "" { + memory, err := resource.ParseQuantity(o.Memory) + if err != nil { + return fmt.Errorf("cannot parse '%v', %v", o.Memory, err) } - requests.DeepCopyInto(&comp.Resources.Requests) - requests.DeepCopyInto(&comp.Resources.Limits) + requests[corev1.ResourceMemory] = memory } + requests.DeepCopyInto(&comp.Resources.Requests) + requests.DeepCopyInto(&comp.Resources.Limits) return nil } @@ -429,10 +404,6 @@ func (o *OperationsOptions) validateVScale(cluster *appsv1alpha1.Cluster) error if err := fillClassParams(&comp); err != nil { return err } - // validate component classes - if err = classutil.ValidateResources(clsMgr, resourceConstraintList, cluster.Spec.ClusterDefRef, &comp); err != nil { - return err - } } } @@ -732,9 +703,6 @@ func NewUpgradeCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra var verticalScalingExample = templates.Examples(` # scale the computing resources of specified components, separate with commas for multiple components kbcli cluster vscale mycluster --components=mysql --cpu=500m --memory=500Mi - - # scale the computing resources of specified components by class, run command 'kbcli class list --cluster-definition cluster-definition-name' to get available classes - kbcli cluster vscale mycluster --components=mysql --class=general-2c4g `) // NewVerticalScalingCmd creates a vertical scaling command @@ -757,7 +725,6 @@ func NewVerticalScalingCmd(f cmdutil.Factory, streams genericiooptions.IOStreams o.addCommonFlags(cmd, f) cmd.Flags().StringVar(&o.CPU, "cpu", "", "Request and limit size of component cpu") cmd.Flags().StringVar(&o.Memory, "memory", "", "Request and limit size of component memory") - cmd.Flags().StringVar(&o.Class, "class", "", "Component class") cmd.Flags().BoolVar(&o.AutoApprove, "auto-approve", false, "Skip interactive approval before vertically scaling the cluster") _ = cmd.MarkFlagRequired("components") return cmd diff --git a/pkg/cmd/cluster/operations_test.go b/pkg/cmd/cluster/operations_test.go index f886b293d..368fbe2b8 100644 --- a/pkg/cmd/cluster/operations_test.go +++ b/pkg/cmd/cluster/operations_test.go @@ -231,43 +231,17 @@ var _ = Describe("operations", func() { Expect(o.CompleteComponentsFlag()).Should(Succeed()) Expect(o.ComponentNames[0]).Should(Equal(testing.ComponentName)) - By("validate invalid class") - o.Class = "class-not-exists" - in.Write([]byte(o.Name + "\n")) - Expect(o.Validate()).Should(HaveOccurred()) - - By("expect to validate success with class") - o.Class = testapps.Class1c1gName - in.Write([]byte(o.Name + "\n")) - Expect(o.Validate()).ShouldNot(HaveOccurred()) - By("validate invalid resource") - o.Class = "" - o.CPU = "100" - o.Memory = "100Gi" - in.Write([]byte(o.Name + "\n")) - Expect(o.Validate()).Should(HaveOccurred()) - - By("validate invalid resource") - o.Class = "" o.CPU = "1g" o.Memory = "100Gi" in.Write([]byte(o.Name + "\n")) Expect(o.Validate()).Should(HaveOccurred()) By("validate invalid resource") - o.Class = "" o.CPU = "1" o.Memory = "100MB" in.Write([]byte(o.Name + "\n")) Expect(o.Validate()).Should(HaveOccurred()) - - By("expect to validate success with resource") - o.Class = "" - o.CPU = "1" - o.Memory = "1Gi" - in.Write([]byte(o.Name + "\n")) - Expect(o.Validate()).ShouldNot(HaveOccurred()) }) It("Hscale Ops", func() { diff --git a/pkg/scheme/install.go b/pkg/scheme/install.go index 67fb8f1b4..31152cd91 100644 --- a/pkg/scheme/install.go +++ b/pkg/scheme/install.go @@ -28,7 +28,7 @@ import ( clientgoscheme "k8s.io/client-go/kubernetes/scheme" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" From 42bfc08884367fb082ba4b501f80dadde7abc74c Mon Sep 17 00:00:00 2001 From: ldming Date: Mon, 8 Apr 2024 01:39:09 +0000 Subject: [PATCH 2/4] chore: auto update cli doc changes --- docs/user_docs/cli/kbcli_cluster_create.md | 2 +- docs/user_docs/cli/kbcli_cluster_create_llm.md | 2 +- docs/user_docs/cli/kbcli_cluster_vscale.md | 4 ---- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/user_docs/cli/kbcli_cluster_create.md b/docs/user_docs/cli/kbcli_cluster_create.md index 0daafdfe2..1b1c5060f 100644 --- a/docs/user_docs/cli/kbcli_cluster_create.md +++ b/docs/user_docs/cli/kbcli_cluster_create.md @@ -125,7 +125,7 @@ kbcli cluster create [NAME] [flags] --rbac-enabled Specify whether rbac resources will be created by kbcli, otherwise KubeBlocks server will try to create rbac resources --restore-to-time string Set a time for point in time recovery --service-reference stringArray Set the other KubeBlocks cluster dependencies, each '--service-reference' corresponds to a cluster service. (e.g --service-reference name=pulsarZookeeper,cluster=zookeeper,namespace=default) - --set stringArray Set the cluster resource including cpu, memory, replicas and storage, each set corresponds to a component.(e.g. --set cpu=1,memory=1Gi,replicas=3,storage=20Gi or --set class=general-1c1g) + --set stringArray Set the cluster resource including cpu, memory, replicas and storage, each set corresponds to a component.(e.g. --set cpu=1,memory=1Gi,replicas=3,storage=20Gi) -f, --set-file string Use yaml file, URL, or stdin to set the cluster resource --tenancy string Tenancy options, one of: (SharedNode, DedicatedNode) (default "SharedNode") --termination-policy string Termination policy, one of: (DoNotTerminate, Halt, Delete, WipeOut) (default "Delete") diff --git a/docs/user_docs/cli/kbcli_cluster_create_llm.md b/docs/user_docs/cli/kbcli_cluster_create_llm.md index 9be93f12d..1b4344156 100644 --- a/docs/user_docs/cli/kbcli_cluster_create_llm.md +++ b/docs/user_docs/cli/kbcli_cluster_create_llm.md @@ -23,7 +23,7 @@ kbcli cluster create llm NAME [flags] ``` --availability-policy string The availability policy of cluster. Legal values [none, node, zone]. (default "node") --cpu float CPU cores. Value range [0, 64]. - --cpu-mode Set to true if no GPU is available + --cpu-mode Set to true if no GPU is available, default true (default true) --extra-args string extra arguments that will be passed to run model (default "--trust-remote-code") --gpu float GPU cores. Value range [0, 64]. (default 1) -h, --help help for llm diff --git a/docs/user_docs/cli/kbcli_cluster_vscale.md b/docs/user_docs/cli/kbcli_cluster_vscale.md index 96cbb0453..c254d9af7 100644 --- a/docs/user_docs/cli/kbcli_cluster_vscale.md +++ b/docs/user_docs/cli/kbcli_cluster_vscale.md @@ -13,16 +13,12 @@ kbcli cluster vscale NAME [flags] ``` # scale the computing resources of specified components, separate with commas for multiple components kbcli cluster vscale mycluster --components=mysql --cpu=500m --memory=500Mi - - # scale the computing resources of specified components by class, run command 'kbcli class list --cluster-definition cluster-definition-name' to get available classes - kbcli cluster vscale mycluster --components=mysql --class=general-2c4g ``` ### Options ``` --auto-approve Skip interactive approval before vertically scaling the cluster - --class string Component class --components strings Component names to this operations --cpu string Request and limit size of component cpu --dry-run string[="unchanged"] Must be "client", or "server". If with client strategy, only print the object that would be sent, and no data is actually sent. If with server strategy, submit the server-side request, but no data is persistent. (default "none") From 207102f4149409ecb149c942009fbfa650c0ea58 Mon Sep 17 00:00:00 2001 From: "L.Dongming" Date: Mon, 8 Apr 2024 09:47:15 +0800 Subject: [PATCH 3/4] remove test file --- pkg/testing/testdata/class.yaml | 57 ------------------- .../testdata/component_with_class_1c1g.yaml | 16 ------ .../component_with_invalid_class.yaml | 16 ------ .../component_with_invalid_resource.yaml | 18 ------ .../component_with_resource_1c1g.yaml | 18 ------ pkg/testing/testdata/custom_class.yaml | 21 ------- ...e-constraint-general-without-selector.yaml | 26 --------- .../testdata/resource-constraint-general.yaml | 34 ----------- .../resource-constraint-memory-optimized.yaml | 27 --------- 9 files changed, 233 deletions(-) delete mode 100644 pkg/testing/testdata/class.yaml delete mode 100644 pkg/testing/testdata/component_with_class_1c1g.yaml delete mode 100644 pkg/testing/testdata/component_with_invalid_class.yaml delete mode 100644 pkg/testing/testdata/component_with_invalid_resource.yaml delete mode 100644 pkg/testing/testdata/component_with_resource_1c1g.yaml delete mode 100644 pkg/testing/testdata/custom_class.yaml delete mode 100644 pkg/testing/testdata/resource-constraint-general-without-selector.yaml delete mode 100644 pkg/testing/testdata/resource-constraint-general.yaml delete mode 100644 pkg/testing/testdata/resource-constraint-memory-optimized.yaml diff --git a/pkg/testing/testdata/class.yaml b/pkg/testing/testdata/class.yaml deleted file mode 100644 index 882b18789..000000000 --- a/pkg/testing/testdata/class.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: apps.kubeblocks.io/v1alpha1 -kind: ComponentClassDefinition -metadata: - name: kb.classes.default.apecloud-mysql.mysql - labels: - class.kubeblocks.io/provider: kubeblocks - apps.kubeblocks.io/component-def-ref: mysql - clusterdefinition.kubeblocks.io/name: apecloud-mysql -spec: - groups: - - # class schema template, you can set default resource values here - template: | - cpu: "{{ .cpu }}" - memory: "{{ .memory }}Gi" - # class schema template variables - vars: [ cpu, memory] - series: - - # class name generator, you can reference variables in class schema template - # it's also ok to define static class name in following class definitions - namingTemplate: "general-{{ .cpu }}c{{ .memory }}g" - - # class definitions, we support two kinds of class definitions: - # 1. define arguments for class schema variables, class schema will be dynamically generated - # 2. statically define complete class schema - classes: - - args: [ "1", "1"] - - args: [ "2", "2"] - - args: [ "2", "4"] - - args: [ "2", "8"] - - args: [ "4", "16"] - - args: [ "8", "32"] - - args: [ "16", "64"] - - args: [ "32", "128"] - - args: [ "64", "256"] - - args: [ "128", "512"] - - - template: | - cpu: "{{ .cpu }}" - memory: "{{ .memory }}Gi" - vars: [ cpu, memory] - series: - - namingTemplate: "mo-{{ .cpu }}c{{ .memory }}g" - classes: - - args: [ "2", "16"] - - args: [ "4", "32"] - - args: [ "8", "64"] - - args: [ "12", "96"] - - args: [ "24", "192"] - - args: [ "48", "384"] - - args: [ "2", "32"] - - args: [ "4", "64"] - - args: [ "8", "128"] - - args: [ "16", "256"] - - args: [ "32", "512"] - - args: [ "48", "768"] - - args: [ "64", "1024"] - - args: [ "128", "2048"] \ No newline at end of file diff --git a/pkg/testing/testdata/component_with_class_1c1g.yaml b/pkg/testing/testdata/component_with_class_1c1g.yaml deleted file mode 100644 index a5adfde07..000000000 --- a/pkg/testing/testdata/component_with_class_1c1g.yaml +++ /dev/null @@ -1,16 +0,0 @@ -- name: test - componentDefRef: mysql - monitor: true - enabledLogs: [error, slow] - replicas: 1 - classDefRef: - class: general-1c1g - volumeClaimTemplates: - - name: data - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - volumeMode: Filesystem \ No newline at end of file diff --git a/pkg/testing/testdata/component_with_invalid_class.yaml b/pkg/testing/testdata/component_with_invalid_class.yaml deleted file mode 100644 index d9f359f45..000000000 --- a/pkg/testing/testdata/component_with_invalid_class.yaml +++ /dev/null @@ -1,16 +0,0 @@ -- name: test - componentDefRef: mysql - monitor: true - enabledLogs: [error, slow] - replicas: 1 - classDefRef: - class: class-not-exists - volumeClaimTemplates: - - name: data - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - volumeMode: Filesystem \ No newline at end of file diff --git a/pkg/testing/testdata/component_with_invalid_resource.yaml b/pkg/testing/testdata/component_with_invalid_resource.yaml deleted file mode 100644 index efdc476b1..000000000 --- a/pkg/testing/testdata/component_with_invalid_resource.yaml +++ /dev/null @@ -1,18 +0,0 @@ -- name: test - componentDefRef: mysql - monitor: true - enabledLogs: [error, slow] - replicas: 1 - resources: - requests: - cpu: 3 - memory: 7Gi - volumeClaimTemplates: - - name: data - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - volumeMode: Filesystem \ No newline at end of file diff --git a/pkg/testing/testdata/component_with_resource_1c1g.yaml b/pkg/testing/testdata/component_with_resource_1c1g.yaml deleted file mode 100644 index cfdf53ae8..000000000 --- a/pkg/testing/testdata/component_with_resource_1c1g.yaml +++ /dev/null @@ -1,18 +0,0 @@ -- name: test - componentDefRef: mysql - monitor: true - enabledLogs: [error, slow] - replicas: 1 - resources: - requests: - cpu: 1 - memory: 1Gi - volumeClaimTemplates: - - name: data - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - volumeMode: Filesystem \ No newline at end of file diff --git a/pkg/testing/testdata/custom_class.yaml b/pkg/testing/testdata/custom_class.yaml deleted file mode 100644 index 3173d4181..000000000 --- a/pkg/testing/testdata/custom_class.yaml +++ /dev/null @@ -1,21 +0,0 @@ - - template: | - cpu: "{{ or .cpu 1 }}" - memory: "{{ or .memory 4 }}Gi" - vars: [cpu, memory] - series: - - namingTemplate: "custom-{{ .cpu }}c{{ .memory }}g" - classes: - - args: ["1", "1"] - - name: custom-4c16g - cpu: 4 - memory: 16Gi - - - template: | - cpu: "{{ or .cpu 1 }}" - memory: "{{ or .memory 4 }}Gi" - vars: [cpu, memory] - series: - - namingTemplate: "custom-{{ .cpu }}c{{ .memory }}g" - classes: - - args: ["2", "16"] - - args: ["4", "64"] diff --git a/pkg/testing/testdata/resource-constraint-general-without-selector.yaml b/pkg/testing/testdata/resource-constraint-general-without-selector.yaml deleted file mode 100644 index e8c0d7dd8..000000000 --- a/pkg/testing/testdata/resource-constraint-general-without-selector.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: apps.kubeblocks.io/v1alpha1 -kind: ComponentResourceConstraint -metadata: - name: kb-resource-constraint-general-without-selector - labels: - resourceconstraint.kubeblocks.io/provider: kubeblocks -spec: - rules: - - name: c1 - cpu: - min: 0.5 - max: 2 - step: 0.5 - memory: - sizePerCPU: 1Gi - - name: c2 - cpu: - min: 2 - max: 2 - memory: - sizePerCPU: 2Gi - - name: c3 - cpu: - slots: [2, 4, 8, 16, 24, 32, 48, 64, 96, 128] - memory: - sizePerCPU: 4Gi diff --git a/pkg/testing/testdata/resource-constraint-general.yaml b/pkg/testing/testdata/resource-constraint-general.yaml deleted file mode 100644 index fadbc67b0..000000000 --- a/pkg/testing/testdata/resource-constraint-general.yaml +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: apps.kubeblocks.io/v1alpha1 -kind: ComponentResourceConstraint -metadata: - name: kb-resource-constraint-general - labels: - resourceconstraint.kubeblocks.io/provider: kubeblocks -spec: - rules: - - name: c1 - cpu: - min: 0.5 - max: 2 - step: 0.5 - memory: - sizePerCPU: 1Gi - - name: c2 - cpu: - min: 2 - max: 2 - memory: - sizePerCPU: 2Gi - - name: c3 - cpu: - slots: [2, 4, 8, 16, 24, 32, 48, 64, 96, 128] - memory: - sizePerCPU: 4Gi - selector: - - clusterDefRef: apecloud-mysql - components: - - componentDefRef: mysql - rules: - - "c1" - - "c2" - - "c3" diff --git a/pkg/testing/testdata/resource-constraint-memory-optimized.yaml b/pkg/testing/testdata/resource-constraint-memory-optimized.yaml deleted file mode 100644 index 89db7f021..000000000 --- a/pkg/testing/testdata/resource-constraint-memory-optimized.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: apps.kubeblocks.io/v1alpha1 -kind: ComponentResourceConstraint -metadata: - name: kb-resource-constraint-memory-optimized - labels: - resourceconstraint.kubeblocks.io/provider: kubeblocks -spec: - rules: - - name: c1 - cpu: - slots: [2, 4, 8, 12, 24, 48] - memory: - sizePerCPU: 8Gi - - name: c2 - cpu: - min: 2 - max: 128 - step: 2 - memory: - sizePerCPU: 16Gi - selector: - - clusterDefRef: apecloud-mysql - components: - - componentDefRef: mysql - rules: - - "c1" - - "c2" From 2a1e99d8981051594ea705559ad48a736f1ddf63 Mon Sep 17 00:00:00 2001 From: "L.Dongming" Date: Mon, 8 Apr 2024 10:01:08 +0800 Subject: [PATCH 4/4] remove class doc --- docs/user_docs/cli/kbcli_class.md | 45 -------------- docs/user_docs/cli/kbcli_class_create.md | 61 ------------------- docs/user_docs/cli/kbcli_class_list.md | 54 ---------------- docs/user_docs/cli/kbcli_class_template.md | 47 -------------- .../template/cluster_operations_template.cue | 5 -- pkg/cmd/cluster/cluster_test.go | 15 +---- pkg/cmd/cluster/describe_ops.go | 15 +---- pkg/cmd/cluster/operations.go | 4 +- pkg/cmd/cluster/operations_test.go | 19 +----- pkg/types/types.go | 2 - 10 files changed, 8 insertions(+), 259 deletions(-) delete mode 100644 docs/user_docs/cli/kbcli_class.md delete mode 100644 docs/user_docs/cli/kbcli_class_create.md delete mode 100644 docs/user_docs/cli/kbcli_class_list.md delete mode 100644 docs/user_docs/cli/kbcli_class_template.md diff --git a/docs/user_docs/cli/kbcli_class.md b/docs/user_docs/cli/kbcli_class.md deleted file mode 100644 index fc5536db4..000000000 --- a/docs/user_docs/cli/kbcli_class.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: kbcli class ---- - -Manage classes - -### Options - -``` - -h, --help help for class -``` - -### Options inherited from parent commands - -``` - --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --as-uid string UID to impersonate for the operation. - --cache-dir string Default cache directory (default "$HOME/.kube/cache") - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --context string The name of the kubeconfig context to use - --disable-compression If true, opt-out of response compression for all requests to the server - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to the kubeconfig file to use for CLI requests. - --match-server-version Require server version to match client version - -n, --namespace string If present, the namespace scope for this CLI request - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - -s, --server string The address and port of the Kubernetes API server - --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use -``` - -### SEE ALSO - - -* [kbcli class create](kbcli_class_create.md) - Create a class -* [kbcli class list](kbcli_class_list.md) - List classes -* [kbcli class template](kbcli_class_template.md) - Generate class definition template - -#### Go Back to [CLI Overview](cli.md) Homepage. - diff --git a/docs/user_docs/cli/kbcli_class_create.md b/docs/user_docs/cli/kbcli_class_create.md deleted file mode 100644 index c45743c2a..000000000 --- a/docs/user_docs/cli/kbcli_class_create.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: kbcli class create ---- - -Create a class - -``` -kbcli class create [NAME] [flags] -``` - -### Examples - -``` - # Create a class for component mysql in cluster definition apecloud-mysql, which has 1 CPU core and 1Gi memory - kbcli class create custom-1c1g --cluster-definition apecloud-mysql --type mysql --cpu 1 --memory 1Gi - - # Create classes for component mysql in cluster definition apecloud-mysql, with classes defined in file - kbcli class create --cluster-definition apecloud-mysql --type mysql --file ./classes.yaml -``` - -### Options - -``` - --cluster-definition string Specify cluster definition, run "kbcli clusterdefinition list" to show all available cluster definitions - --cpu string Specify component CPU cores - --file string Specify file path of class definition YAML - -h, --help help for create - --memory string Specify component memory size - --type string Specify component type -``` - -### Options inherited from parent commands - -``` - --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --as-uid string UID to impersonate for the operation. - --cache-dir string Default cache directory (default "$HOME/.kube/cache") - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --context string The name of the kubeconfig context to use - --disable-compression If true, opt-out of response compression for all requests to the server - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to the kubeconfig file to use for CLI requests. - --match-server-version Require server version to match client version - -n, --namespace string If present, the namespace scope for this CLI request - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - -s, --server string The address and port of the Kubernetes API server - --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use -``` - -### SEE ALSO - -* [kbcli class](kbcli_class.md) - Manage classes - -#### Go Back to [CLI Overview](cli.md) Homepage. - diff --git a/docs/user_docs/cli/kbcli_class_list.md b/docs/user_docs/cli/kbcli_class_list.md deleted file mode 100644 index c44de63f0..000000000 --- a/docs/user_docs/cli/kbcli_class_list.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: kbcli class list ---- - -List classes - -``` -kbcli class list [flags] -``` - -### Examples - -``` - # List all components classes in cluster definition apecloud-mysql - kbcli class list --cluster-definition apecloud-mysql -``` - -### Options - -``` - --cluster-definition string Specify cluster definition, run "kbcli clusterdefinition list" to show all available cluster definition - -h, --help help for list -``` - -### Options inherited from parent commands - -``` - --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --as-uid string UID to impersonate for the operation. - --cache-dir string Default cache directory (default "$HOME/.kube/cache") - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --context string The name of the kubeconfig context to use - --disable-compression If true, opt-out of response compression for all requests to the server - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to the kubeconfig file to use for CLI requests. - --match-server-version Require server version to match client version - -n, --namespace string If present, the namespace scope for this CLI request - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - -s, --server string The address and port of the Kubernetes API server - --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use -``` - -### SEE ALSO - -* [kbcli class](kbcli_class.md) - Manage classes - -#### Go Back to [CLI Overview](cli.md) Homepage. - diff --git a/docs/user_docs/cli/kbcli_class_template.md b/docs/user_docs/cli/kbcli_class_template.md deleted file mode 100644 index 92af595ad..000000000 --- a/docs/user_docs/cli/kbcli_class_template.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: kbcli class template ---- - -Generate class definition template - -``` -kbcli class template [flags] -``` - -### Options - -``` - -h, --help help for template - -o, --output string Output class definition template to a file -``` - -### Options inherited from parent commands - -``` - --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --as-uid string UID to impersonate for the operation. - --cache-dir string Default cache directory (default "$HOME/.kube/cache") - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --context string The name of the kubeconfig context to use - --disable-compression If true, opt-out of response compression for all requests to the server - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to the kubeconfig file to use for CLI requests. - --match-server-version Require server version to match client version - -n, --namespace string If present, the namespace scope for this CLI request - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - -s, --server string The address and port of the Kubernetes API server - --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use -``` - -### SEE ALSO - -* [kbcli class](kbcli_class.md) - Manage classes - -#### Go Back to [CLI Overview](cli.md) Homepage. - diff --git a/pkg/action/template/cluster_operations_template.cue b/pkg/action/template/cluster_operations_template.cue index 295c77df0..453f51785 100644 --- a/pkg/action/template/cluster_operations_template.cue +++ b/pkg/action/template/cluster_operations_template.cue @@ -47,8 +47,6 @@ options: { ] cpu: string memory: string - class: string - classDefRef: {...} replicas: int storage: string vctNames: [...string] @@ -128,9 +126,6 @@ content: { if options.type == "VerticalScaling" { verticalScaling: [ for _, cName in options.componentNames { componentName: cName - if options.class != "" { - classDefRef: options.classDefRef - } requests: { if options.memory != "" { memory: options.memory diff --git a/pkg/cmd/cluster/cluster_test.go b/pkg/cmd/cluster/cluster_test.go index fe126e1fe..41f5e9fcd 100644 --- a/pkg/cmd/cluster/cluster_test.go +++ b/pkg/cmd/cluster/cluster_test.go @@ -43,12 +43,8 @@ import ( var _ = Describe("Cluster", func() { const ( - testComponentPath = "../../testing/testdata/component.yaml" - testComponentWithClassPath = "../../testing/testdata/component_with_class_1c1g.yaml" - testComponentWithInvalidClassPath = "../../testing/testdata/component_with_invalid_class.yaml" - testComponentWithResourcePath = "../../testing/testdata/component_with_resource_1c1g.yaml" - testComponentWithInvalidResourcePath = "../../testing/testdata/component_with_invalid_resource.yaml" - testClusterPath = "../../testing/testdata/cluster.yaml" + testComponentPath = "../../testing/testdata/component.yaml" + testClusterPath = "../../testing/testdata/cluster.yaml" ) const ( @@ -196,13 +192,6 @@ var _ = Describe("Cluster", func() { Run() }) - It("should succeed if create cluster by file with resource", func() { - o.SetFile = testComponentWithResourcePath - Expect(o.Complete()).Should(Succeed()) - Expect(o.Validate()).Should(Succeed()) - Run() - }) - It("should succeed if create cluster with a complete config file", func() { o.SetFile = testClusterPath Expect(o.Complete()).Should(Succeed()) diff --git a/pkg/cmd/cluster/describe_ops.go b/pkg/cmd/cluster/describe_ops.go index 4f9db51f5..f9822f0c8 100644 --- a/pkg/cmd/cluster/describe_ops.go +++ b/pkg/cmd/cluster/describe_ops.go @@ -272,18 +272,9 @@ func (o *describeOpsOptions) getVerticalScalingCommand(spec appsv1alpha1.OpsRequ for i := range componentNameSlice { commands[i] = fmt.Sprintf("kbcli cluster vscale %s --components=%s", spec.ClusterRef, strings.Join(componentNameSlice[i], ",")) - clsRef := spec.VerticalScalingList[i].ClassDefRef - if clsRef != nil { - class := clsRef.Class - if clsRef.Name != "" { - class = fmt.Sprintf("%s:%s", clsRef.Name, class) - } - commands[i] += fmt.Sprintf("--class=%s", class) - } else { - resource := resourceSlice[i].(corev1.ResourceRequirements) - commands[i] += o.addResourceFlag("cpu", resource.Limits.Cpu()) - commands[i] += o.addResourceFlag("memory", resource.Limits.Memory()) - } + resource := resourceSlice[i].(corev1.ResourceRequirements) + commands[i] += o.addResourceFlag("cpu", resource.Limits.Cpu()) + commands[i] += o.addResourceFlag("memory", resource.Limits.Memory()) } return commands } diff --git a/pkg/cmd/cluster/operations.go b/pkg/cmd/cluster/operations.go index 85205a4ac..366a82ef4 100755 --- a/pkg/cmd/cluster/operations.go +++ b/pkg/cmd/cluster/operations.go @@ -375,7 +375,7 @@ func (o *OperationsOptions) validateVScale(cluster *appsv1alpha1.Cluster) error return fmt.Errorf("cpu or memory must be specified") } - fillClassParams := func(comp *appsv1alpha1.ClusterComponentSpec) error { + fillResource := func(comp *appsv1alpha1.ClusterComponentSpec) error { requests := make(corev1.ResourceList) if o.CPU != "" { cpu, err := resource.ParseQuantity(o.CPU) @@ -401,7 +401,7 @@ func (o *OperationsOptions) validateVScale(cluster *appsv1alpha1.Cluster) error if comp.Name != name { continue } - if err := fillClassParams(&comp); err != nil { + if err := fillResource(&comp); err != nil { return err } } diff --git a/pkg/cmd/cluster/operations_test.go b/pkg/cmd/cluster/operations_test.go index 368fbe2b8..39d9065ac 100644 --- a/pkg/cmd/cluster/operations_test.go +++ b/pkg/cmd/cluster/operations_test.go @@ -37,7 +37,6 @@ import ( appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" - testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" "github.com/apecloud/kbcli/pkg/testing" ) @@ -67,22 +66,6 @@ var _ = Describe("operations", func() { clusterWithOneComp.Spec.ComponentSpecs = []appsv1alpha1.ClusterComponentSpec{ clusterWithOneComp.Spec.ComponentSpecs[0], } - clusterWithOneComp.Spec.ComponentSpecs[0].ClassDefRef = &appsv1alpha1.ClassDefRef{Class: testapps.Class1c1gName} - classDef := testapps.NewComponentClassDefinitionFactory("custom", clusterWithOneComp.Spec.ClusterDefRef, testing.ComponentDefName). - AddClasses([]appsv1alpha1.ComponentClass{testapps.Class1c1g}). - GetObject() - resourceConstraint := testapps.NewComponentResourceConstraintFactory(testapps.DefaultResourceConstraintName). - AddConstraints(testapps.ProductionResourceConstraint). - AddSelector(appsv1alpha1.ClusterResourceConstraintSelector{ - ClusterDefRef: testing.ClusterDefName, - Components: []appsv1alpha1.ComponentResourceConstraintSelector{ - { - ComponentDefRef: testing.ComponentDefName, - Rules: []string{"c1"}, - }, - }, - }). - GetObject() // init cluster with one component and componentDefinition clusterWithCompDef := clusterWithOneComp.DeepCopy() @@ -115,7 +98,7 @@ var _ = Describe("operations", func() { tf.Client = &clientfake.RESTClient{} tf.FakeDynamicClient = testing.FakeDynamicClient(testing.FakeClusterDef(), testing.FakeClusterVersion(), testing.FakeCompDef(), clusterWithTwoComps, clusterWithOneComp, clusterWithCompDef, - classDef, &pods.Items[0], &pods.Items[1], &podsWithCompDef.Items[0], &podsWithCompDef.Items[1], resourceConstraint, opsDef) + &pods.Items[0], &pods.Items[1], &podsWithCompDef.Items[0], &podsWithCompDef.Items[1], opsDef) }) AfterEach(func() { diff --git a/pkg/types/types.go b/pkg/types/types.go index f98ac1942..b3386da07 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -155,8 +155,6 @@ const ( // Labels const ( - ClassProviderLabelKey = "class.kubeblocks.io/provider" - AddonProviderLabelKey = "addon.kubeblocks.io/provider" // ProviderLabelKey was used as the label for addon providers before version 0.8.0 ProviderLabelKey = "kubeblocks.io/provider"