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  }