github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/builder/template/template.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 "os" 24 "path/filepath" 25 26 "github.com/spf13/cobra" 27 "k8s.io/cli-runtime/pkg/genericiooptions" 28 cmdutil "k8s.io/kubectl/pkg/cmd/util" 29 "k8s.io/kubectl/pkg/util/templates" 30 31 "github.com/1aal/kubeblocks/pkg/cli/util" 32 cfgcore "github.com/1aal/kubeblocks/pkg/configuration/core" 33 "github.com/1aal/kubeblocks/pkg/constant" 34 viper "github.com/1aal/kubeblocks/pkg/viperx" 35 ) 36 37 type renderTPLCmdOpts struct { 38 genericiooptions.IOStreams 39 40 Factory cmdutil.Factory 41 // dynamic dynamic.Interface 42 43 clusterYaml string 44 clusterDef string 45 clusterVersion string 46 47 outputDir string 48 clearOutputDir bool 49 helmOutputDir string 50 helmTemplateDir string 51 52 opts RenderedOptions 53 } 54 55 func (o *renderTPLCmdOpts) complete() error { 56 if err := o.checkAndHelmTemplate(); err != nil { 57 return err 58 } 59 60 if o.helmOutputDir == "" { 61 return cfgcore.MakeError("helm template dir is empty") 62 } 63 64 if o.clearOutputDir && o.outputDir != "" { 65 _ = os.RemoveAll(o.outputDir) 66 } 67 if o.outputDir == "" { 68 o.outputDir = filepath.Join("./output", RandomString(6)) 69 } 70 return nil 71 } 72 73 func (o *renderTPLCmdOpts) run() error { 74 viper.SetDefault(constant.KubernetesClusterDomainEnv, constant.DefaultDNSDomain) 75 workflow, err := NewWorkflowTemplateRender(o.helmOutputDir, o.opts, o.clusterDef, o.clusterVersion) 76 if err != nil { 77 return err 78 } 79 return workflow.Do(o.outputDir) 80 } 81 82 var templateExamples = templates.Examples(` 83 # builder template: Provides a mechanism to rendered template for ComponentConfigSpec and ComponentScriptSpec in the ClusterComponentDefinition. 84 # builder template --helm deploy/redis --memory=64Gi --cpu=16 --replicas=3 --component-name=redis --config-spec=redis-replication-config 85 86 # build all configspec 87 kbcli builder template --helm deploy/redis -a 88 `) 89 90 // buildReconfigureCommonFlags build common flags for reconfigure command 91 func (o *renderTPLCmdOpts) buildTemplateFlags(cmd *cobra.Command) { 92 cmd.Flags().StringVar(&o.clusterYaml, "cluster", "", "the cluster yaml file") 93 cmd.Flags().StringVar(&o.clusterVersion, "cluster-version", "", "specify the cluster version name") 94 cmd.Flags().StringVar(&o.clusterDef, "cluster-definition", "", "specify the cluster definition name") 95 cmd.Flags().StringVarP(&o.outputDir, "output-dir", "o", "", "specify the output directory") 96 97 cmd.Flags().StringVar(&o.opts.ConfigSpec, "config-spec", "", "specify the config spec to be rendered") 98 99 // mock cluster object 100 cmd.Flags().Int32VarP(&o.opts.Replicas, "replicas", "r", 1, "specify the replicas of the component") 101 cmd.Flags().StringVar(&o.opts.DataVolumeName, "volume-name", "", "specify the data volume name of the component") 102 cmd.Flags().StringVar(&o.opts.ComponentName, "component-name", "", "specify the component name of the clusterdefinition") 103 cmd.Flags().StringVar(&o.helmTemplateDir, "helm", "", "specify the helm template dir") 104 cmd.Flags().StringVar(&o.helmOutputDir, "helm-output", "", "specify the helm template output dir") 105 cmd.Flags().StringVar(&o.opts.CPU, "cpu", "", "specify the cpu of the component") 106 cmd.Flags().StringVar(&o.opts.Memory, "memory", "", "specify the memory of the component") 107 cmd.Flags().BoolVar(&o.clearOutputDir, "clean", false, "specify whether to clear the output dir") 108 } 109 110 func (o *renderTPLCmdOpts) checkAndHelmTemplate() error { 111 if o.helmTemplateDir == "" || o.helmOutputDir != "" { 112 return nil 113 } 114 115 if o.helmTemplateDir != "" && o.helmOutputDir == "" { 116 o.helmOutputDir = filepath.Join("./helm-output", RandomString(6)) 117 } 118 119 return HelmTemplate(o.helmTemplateDir, o.helmOutputDir) 120 } 121 122 func NewComponentTemplateRenderCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 123 o := &renderTPLCmdOpts{ 124 Factory: f, 125 IOStreams: streams, 126 opts: RenderedOptions{ 127 // for mock cluster object 128 Namespace: "default", 129 Name: "cluster-" + RandomString(6), 130 }, 131 } 132 cmd := &cobra.Command{ 133 Use: "template", 134 Aliases: []string{"tpl"}, 135 Short: "tpl - a developer tool integrated with KubeBlocks that can help developers quickly generate rendered configurations or scripts based on Helm templates, and discover errors in the template before creating the database cluster.", 136 Example: templateExamples, 137 Run: func(cmd *cobra.Command, args []string) { 138 util.CheckErr(o.complete()) 139 util.CheckErr(o.run()) 140 }, 141 } 142 o.buildTemplateFlags(cmd) 143 return cmd 144 }