github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/cluster/create_util_test.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package cluster
    21  
    22  import (
    23  	. "github.com/onsi/ginkgo/v2"
    24  	. "github.com/onsi/gomega"
    25  
    26  	"github.com/spf13/cobra"
    27  	flag "github.com/spf13/pflag"
    28  	"k8s.io/apimachinery/pkg/runtime/schema"
    29  	cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
    30  
    31  	"github.com/1aal/kubeblocks/pkg/cli/cluster"
    32  	"github.com/1aal/kubeblocks/pkg/cli/testing"
    33  	"github.com/1aal/kubeblocks/pkg/cli/types"
    34  	cmdflags "github.com/1aal/kubeblocks/pkg/cli/util/flags"
    35  )
    36  
    37  var _ = Describe("cluster create util", func() {
    38  	const (
    39  		namespace   = "test-ns"
    40  		clusterType = "mysql"
    41  	)
    42  
    43  	Context("add create flags", func() {
    44  		var cmd *cobra.Command
    45  		var tf *cmdtesting.TestFactory
    46  
    47  		BeforeEach(func() {
    48  			cmd = &cobra.Command{
    49  				Use: "test-cmd",
    50  			}
    51  			tf = testing.NewTestFactory(namespace)
    52  		})
    53  
    54  		It("add create flags for a nil schema", func() {
    55  			Expect(addCreateFlags(cmd, tf, nil)).Should(Succeed())
    56  		})
    57  
    58  		It("add create flags for a not-nil schema", func() {
    59  			c, err := cluster.BuildChartInfo(clusterType)
    60  			Expect(err).Should(Succeed())
    61  
    62  			Expect(err).Should(Succeed())
    63  			Expect(c.Schema).ShouldNot(BeNil())
    64  			Expect(addCreateFlags(cmd, tf, c)).Should(Succeed())
    65  			Expect(cmd.Flags().Lookup("version")).ShouldNot(BeNil())
    66  		})
    67  
    68  		It("get kubernetes object info from manifests", func() {
    69  			testCases := []struct {
    70  				gvr      schema.GroupVersionResource
    71  				manifest string
    72  			}{
    73  				{
    74  					gvr: types.ServiceAccountGVR(),
    75  					manifest: `apiVersion: v1
    76  kind: ServiceAccount
    77  metadata:
    78    name: kb-sa-test-cluster
    79    namespace: default`},
    80  				{
    81  					gvr: types.RoleGVR(),
    82  					manifest: `apiVersion: rbac.authorization.k8s.io/v1
    83  kind: Role
    84  metadata:
    85    name: kb-role-test-cluster
    86    namespace: default`},
    87  				{
    88  					gvr: types.ClusterGVR(),
    89  					manifest: `apiVersion: apps.kubeblocks.io/v1alpha1
    90  kind: Cluster
    91  metadata:
    92    name: test-cluster
    93    namespace: default`},
    94  			}
    95  
    96  			for _, tc := range testCases {
    97  				By(tc.gvr.String())
    98  				infos, err := getObjectsInfo(tf, map[string]string{
    99  					"manifest": tc.manifest,
   100  				})
   101  				Expect(err).Should(Succeed())
   102  				Expect(infos).ShouldNot(BeNil())
   103  				Expect(infos[0].gvr).Should(Equal(tc.gvr))
   104  			}
   105  		})
   106  	})
   107  
   108  	It("get values from command flags", func() {
   109  		fs := &flag.FlagSet{}
   110  		flags := []struct {
   111  			tpe   string
   112  			name  string
   113  			value interface{}
   114  		}{
   115  			{
   116  				tpe:   cmdflags.CobraInt,
   117  				name:  "int",
   118  				value: 1,
   119  			},
   120  			{
   121  				tpe:   cmdflags.CobraBool,
   122  				name:  "bool",
   123  				value: true,
   124  			},
   125  			{
   126  				tpe:   cmdflags.CobraFloat64,
   127  				name:  "float64",
   128  				value: 1.1,
   129  			},
   130  			{
   131  				tpe:   cmdflags.CobraSting,
   132  				name:  "hello",
   133  				value: "Hello, KubeBlocks",
   134  			}, {
   135  				tpe:   cmdflags.CobraStringArray,
   136  				name:  "clusters",
   137  				value: []string{"mysql", "etcd"},
   138  			},
   139  			{
   140  				tpe:   cmdflags.CobraIntSlice,
   141  				name:  "ports",
   142  				value: []int{3303, 2379},
   143  			},
   144  			{
   145  				tpe:   cmdflags.CobraFloat64Slice,
   146  				name:  "resource",
   147  				value: []float64{0.5, 1.8},
   148  			},
   149  			{
   150  				tpe:   cmdflags.CobraBoolSlice,
   151  				name:  "enable",
   152  				value: []bool{false, true},
   153  			},
   154  		}
   155  
   156  		for _, f := range flags {
   157  			switch f.tpe {
   158  			case cmdflags.CobraInt:
   159  				fs.Int(f.name, f.value.(int), f.name)
   160  			case cmdflags.CobraBool:
   161  				fs.Bool(f.name, f.value.(bool), f.name)
   162  			case cmdflags.CobraFloat64:
   163  				fs.Float64(f.name, f.value.(float64), f.name)
   164  			case cmdflags.CobraStringArray:
   165  				fs.StringArray(f.name, f.value.([]string), f.name)
   166  			case cmdflags.CobraIntSlice:
   167  				fs.IntSlice(f.name, f.value.([]int), f.name)
   168  			case cmdflags.CobraFloat64Slice:
   169  				fs.Float64Slice(f.name, f.value.([]float64), f.name)
   170  			case cmdflags.CobraBoolSlice:
   171  				fs.BoolSlice(f.name, f.value.([]bool), f.name)
   172  			default:
   173  				fs.String(f.name, f.value.(string), f.name)
   174  			}
   175  		}
   176  
   177  		values := getValuesFromFlags(fs)
   178  		for _, f := range flags {
   179  			Expect(values[f.name]).Should(Equal(f.value))
   180  		}
   181  	})
   182  
   183  	It("build helm values", func() {
   184  		By("get cluster schema")
   185  		c, err := cluster.BuildChartInfo(clusterType)
   186  		Expect(err).Should(Succeed())
   187  		Expect(c).ShouldNot(BeNil())
   188  
   189  		By("build helm values")
   190  		values := map[string]interface{}{
   191  			"version":           "1.0.0",
   192  			"cpu":               1,
   193  			"memory":            1,
   194  			"terminationPolicy": "Halt",
   195  		}
   196  		helmValues := buildHelmValues(c, values)
   197  		Expect(helmValues).ShouldNot(BeNil())
   198  		Expect(helmValues["version"]).Should(Equal("1.0.0"))
   199  		Expect(helmValues[c.SubChartName]).ShouldNot(BeNil())
   200  		Expect(helmValues[c.SubChartName].(map[string]interface{})["terminationPolicy"]).Should(Equal("Halt"))
   201  
   202  		By("build object helm values")
   203  		values = map[string]interface{}{
   204  			"etcd.cluster":   "etcd",
   205  			"etcd.namespace": "default",
   206  		}
   207  		helmValues = buildHelmValues(c, values)
   208  		Expect(helmValues).ShouldNot(BeNil())
   209  		Expect(helmValues["etcd"]).ShouldNot(BeNil())
   210  		Expect(helmValues["etcd"].(map[string]interface{})).Should(Equal(map[string]interface{}{
   211  			"cluster":   "etcd",
   212  			"namespace": "default",
   213  		}))
   214  
   215  		By("build array helm values")
   216  		values = map[string]interface{}{
   217  			"servers.name": []string{"mysql", "etcd"},
   218  			"servers.port": []int{3306, 2379},
   219  		}
   220  		helmValues = buildHelmValues(c, values)
   221  		Expect(helmValues).ShouldNot(BeNil())
   222  		Expect(helmValues["servers"]).ShouldNot(BeNil())
   223  		Expect(helmValues["servers"].(map[string]interface{})).Should(Equal(map[string]interface{}{
   224  			"name": []string{"mysql", "etcd"},
   225  			"port": []int{3306, 2379},
   226  		}))
   227  	})
   228  })