github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/builder/template/util.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 template 21 22 import ( 23 "reflect" 24 "strings" 25 26 "github.com/sethvargo/go-password/password" 27 "helm.sh/helm/v3/pkg/cli/values" 28 corev1 "k8s.io/api/core/v1" 29 "k8s.io/apimachinery/pkg/api/resource" 30 31 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 32 "github.com/1aal/kubeblocks/pkg/cli/testing" 33 "github.com/1aal/kubeblocks/pkg/cli/util/helm" 34 testapps "github.com/1aal/kubeblocks/pkg/testutil/apps" 35 "github.com/1aal/kubeblocks/version" 36 ) 37 38 type RenderedOptions struct { 39 ConfigSpec string 40 41 // mock cluster object 42 Name string 43 Namespace string 44 45 Replicas int32 46 DataVolumeName string 47 ComponentName string 48 49 CPU string 50 Memory string 51 } 52 53 func mockClusterObject(clusterDefObj *appsv1alpha1.ClusterDefinition, renderedOpts RenderedOptions, clusterVersion *appsv1alpha1.ClusterVersion) *appsv1alpha1.Cluster { 54 cvReference := "" 55 if clusterVersion != nil { 56 cvReference = clusterVersion.Name 57 } 58 factory := testapps.NewClusterFactory(renderedOpts.Namespace, renderedOpts.Name, clusterDefObj.Name, cvReference) 59 for _, component := range clusterDefObj.Spec.ComponentDefs { 60 factory.AddComponent(component.CharacterType+"-"+RandomString(3), component.Name) 61 factory.SetReplicas(renderedOpts.Replicas) 62 if renderedOpts.DataVolumeName != "" { 63 fields := strings.SplitN(renderedOpts.DataVolumeName, ":", 2) 64 if len(fields) == 1 { 65 fields = append(fields, "10Gi") 66 } 67 pvcSpec := testapps.NewPVCSpec(fields[1]) 68 factory.AddVolumeClaimTemplate(fields[0], pvcSpec) 69 } 70 if renderedOpts.CPU != "" || renderedOpts.Memory != "" { 71 factory.SetResources(fromResource(renderedOpts)) 72 } 73 } 74 return factory.GetObject() 75 } 76 77 func fromResource(opts RenderedOptions) corev1.ResourceRequirements { 78 cpu := opts.CPU 79 memory := opts.Memory 80 if cpu == "" { 81 cpu = "1" 82 } 83 if memory == "" { 84 memory = "1Gi" 85 } 86 return corev1.ResourceRequirements{ 87 Limits: corev1.ResourceList{ 88 "cpu": resource.MustParse(cpu), 89 "memory": resource.MustParse(memory), 90 }, 91 } 92 } 93 94 func kindFromResource[T any](resource T) string { 95 t := reflect.TypeOf(resource) 96 if t.Kind() == reflect.Ptr { 97 t = t.Elem() 98 } 99 return t.Name() 100 } 101 102 func RandomString(n int) string { 103 s, _ := password.Generate(n, 0, 0, false, false) 104 return s 105 } 106 107 func HelmTemplate(helmPath string, helmOutput string) error { 108 o := helm.InstallOpts{ 109 Name: testing.KubeBlocksChartName, 110 Chart: helmPath, 111 Namespace: "default", 112 Version: version.DefaultKubeBlocksVersion, 113 114 DryRun: func() *bool { r := true; return &r }(), 115 OutputDir: helmOutput, 116 ValueOpts: &values.Options{Values: []string{}}, 117 } 118 _, err := o.Install(helm.NewFakeConfig("default")) 119 return err 120 } 121 122 func checkAndFillPortProtocol(clusterDefComponents []appsv1alpha1.ClusterComponentDefinition) { 123 // set a default protocol with 'TCP' to avoid failure in BuildHeadlessSvc 124 for i := range clusterDefComponents { 125 for j := range clusterDefComponents[i].PodSpec.Containers { 126 container := &clusterDefComponents[i].PodSpec.Containers[j] 127 for k := range container.Ports { 128 port := &container.Ports[k] 129 if port.Protocol == "" { 130 port.Protocol = corev1.ProtocolTCP 131 } 132 } 133 } 134 } 135 }