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  }