github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow@v0.28.1-0.20240311201729-34c6856b157f/pkg/command/gen_manifest.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 package command 21 22 import ( 23 "fmt" 24 "os" 25 "path/filepath" 26 27 "github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/common" 28 "github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/metadata" 29 "github.com/ory/viper" 30 "github.com/spf13/cobra" 31 ) 32 33 func NewGenManifest() *cobra.Command { 34 cmd := &cobra.Command{ 35 Use: "gen-manifest", 36 Short: "GenerateOperator manifests", 37 Long: ` 38 Generate a list of Operator manifests for a SonataFlow project. 39 By default, the manifests are generated in the ./manifests directory, 40 but they can be configured by --custom-generated-manifest-dir flag. 41 `, 42 Example: ` 43 # Persist the generated Operator manifests on a default path (default ./manifests) 44 {{.Name}} gen-manifest 45 46 # Specify a custom target namespace. (default: kubeclt current namespace; --namespace "" to don't set namespace on your manifest) 47 {{.Name}} deploy --namespace <your_namespace> 48 49 # Persist the generated Operator manifests on a specific custom path 50 {{.Name}} gen-manifest --custom-generated-manifest-dir=<full_directory_path> 51 52 # Specify a custom subflows files directory. (default: ./subflows) 53 {{.Name}} gen-manifest --subflows-dir=<full_directory_path> 54 55 # Specify a custom support specs directory. (default: ./specs) 56 {{.Name}} gen-manifest --specs-dir=<full_directory_path> 57 58 # Specify a custom support schemas directory. (default: ./schemas) 59 {{.Name}} gen-manifest --schemas-dir=<full_directory_path> 60 61 `, 62 PreRunE: common.BindEnv("namespace", "custom-generated-manifests-dir", "specs-dir", "schemas-dir", "subflows-dir"), 63 SuggestFor: []string{"gen-manifests", "generate-manifest"}, //nolint:misspell 64 } 65 66 cmd.RunE = func(cmd *cobra.Command, args []string) error { 67 return generateManifestsCmd(cmd, args) 68 } 69 70 cmd.Flags().StringP("namespace", "n", "", "Target namespace of your deployment. (default: kubeclt current namespace; \"\" to don't set namespace on your manifest)") 71 cmd.Flags().StringP("custom-generated-manifests-dir", "c", "", "Target directory of your generated Operator manifests.") 72 cmd.Flags().StringP("specs-dir", "p", "", "Specify a custom specs files directory") 73 cmd.Flags().StringP("subflows-dir", "s", "", "Specify a custom subflows files directory") 74 cmd.Flags().StringP("schemas-dir", "t", "", "Specify a custom schemas files directory") 75 76 cmd.SetHelpFunc(common.DefaultTemplatedHelp) 77 78 return cmd 79 } 80 81 func generateManifestsCmd(cmd *cobra.Command, args []string) error { 82 cfg, err := runGenManifestCmdConfig(cmd) 83 84 if err != nil { 85 return fmt.Errorf("ā ERROR: initializing deploy config: %w", err) 86 } 87 88 fmt.Println("š ļøļø Generating a list of Operator manifests for a SonataFlow project...") 89 fmt.Printf("š Manifests will be generated in %s\n", cfg.CustomGeneratedManifestDir) 90 91 if err := setupEnvironment(&cfg); err != nil { 92 return fmt.Errorf("ā ERROR: setup environment: %w", err) 93 } 94 95 if err := generateManifests(&cfg); err != nil { 96 return fmt.Errorf("ā ERROR: generating manifests: %w", err) 97 } 98 99 fmt.Printf("\nš SonataFlow Operator manifests successfully generated.\n") 100 101 return nil 102 } 103 104 func runGenManifestCmdConfig(cmd *cobra.Command) (cfg DeployUndeployCmdConfig, err error) { 105 106 cfg = DeployUndeployCmdConfig{ 107 NameSpace: viper.GetString("namespace"), 108 SpecsDir: viper.GetString("specs-dir"), 109 SchemasDir: viper.GetString("schemas-dir"), 110 SubflowsDir: viper.GetString("subflows-dir"), 111 CustomGeneratedManifestDir: viper.GetString("custom-generated-manifests-dir"), 112 } 113 114 if cmd.Flags().Changed("namespace") && len(cfg.NameSpace) == 0 { 115 // distinguish between a user intentionally setting an empty value 116 // and not providing the flag at all 117 cfg.EmptyNameSpace = true 118 } 119 120 if len(cfg.SubflowsDir) == 0 { 121 dir, err := os.Getwd() 122 cfg.SubflowsDir = dir + "/subflows" 123 if err != nil { 124 return cfg, fmt.Errorf("ā ERROR: failed to get default subflows workflow files folder: %w", err) 125 } 126 } 127 128 if len(cfg.SpecsDir) == 0 { 129 dir, err := os.Getwd() 130 cfg.SpecsDir = dir + "/specs" 131 if err != nil { 132 return cfg, fmt.Errorf("ā ERROR: failed to get default support specs files folder: %w", err) 133 } 134 } 135 136 if len(cfg.SchemasDir) == 0 { 137 dir, err := os.Getwd() 138 cfg.SchemasDir = dir + "/schemas" 139 if err != nil { 140 return cfg, fmt.Errorf("ā ERROR: failed to get default support schemas files folder: %w", err) 141 } 142 } 143 144 dir, err := os.Getwd() 145 cfg.DefaultDashboardsFolder = dir + "/" + metadata.DashboardsDefaultDirName 146 if err != nil { 147 return cfg, fmt.Errorf("ā ERROR: failed to get default dashboards files folder: %w", err) 148 } 149 150 //setup manifest path 151 manifestDir, err := resolveManifestDir(cfg.CustomGeneratedManifestDir) 152 if err != nil { 153 return cfg, fmt.Errorf("ā ERROR: failed to get manifest directory: %w", err) 154 } 155 cfg.CustomGeneratedManifestDir = manifestDir 156 157 return cfg, nil 158 } 159 160 func setupEnvironment(cfg *DeployUndeployCmdConfig) error { 161 fmt.Println("\nš Checking your environment...") 162 163 //setup namespace 164 if len(cfg.NameSpace) == 0 && !cfg.EmptyNameSpace { 165 if defaultNamespace, err := common.GetKubectlNamespace(); err == nil { 166 cfg.NameSpace = defaultNamespace 167 fmt.Printf(" - ā resolved namespace: %s\n", cfg.NameSpace) 168 } else { 169 cfg.NameSpace = "default" 170 fmt.Printf(" - ā resolved namespace (default): %s\n", cfg.NameSpace) 171 } 172 } else if cfg.EmptyNameSpace { 173 fmt.Printf(" - ā empty namespace manifest (you will have to setup one later) \n") 174 } else { 175 fmt.Printf(" - ā resolved namespace: %s\n", cfg.NameSpace) 176 } 177 178 return nil 179 } 180 181 func resolveManifestDir(folderName string) (string, error) { 182 if folderName == "" { 183 folderName = "manifests" 184 } 185 186 if _, err := os.Stat(folderName); os.IsNotExist(err) { 187 err = os.Mkdir(folderName, 0755) 188 if err != nil { 189 return "", err 190 } 191 } 192 193 absPath, err := filepath.Abs(folderName) 194 if err != nil { 195 return "", err 196 } 197 198 return absPath, nil 199 }