github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow@v0.28.1-0.20240311201729-34c6856b157f/pkg/command/deploy_undeploy_common.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-kogito-serverless-operator/workflowproj"
    28  	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/common"
    29  	"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/metadata"
    30  )
    31  
    32  type DeployUndeployCmdConfig struct {
    33  	EmptyNameSpace             bool
    34  	NameSpace                  string
    35  	KubectlContext             string
    36  	SonataFlowFile             string
    37  	CustomGeneratedManifestDir string
    38  	TempDir                    string
    39  	ApplicationPropertiesPath  string
    40  	SubflowsDir                string
    41  	SpecsDir                   string
    42  	SchemasDir                 string
    43  	CustomManifestsFileDir     string
    44  	DefaultDashboardsFolder    string
    45  	SchemasFilesPath           []string
    46  	SpecsFilesPath             []string
    47  	SubFlowsFilesPath          []string
    48  	DashboardsPath             []string
    49  }
    50  
    51  func checkEnvironment(cfg *DeployUndeployCmdConfig) error {
    52  	fmt.Println("\nšŸ”Ž Checking your environment...")
    53  
    54  	if err := common.CheckKubectl(); err != nil {
    55  		return err
    56  	}
    57  
    58  	if ctx, err := common.CheckKubectlContext(); err != nil {
    59  		return err
    60  	} else {
    61  		cfg.KubectlContext = ctx
    62  	}
    63  
    64  	//setup namespace
    65  	if len(cfg.NameSpace) == 0 {
    66  		if defaultNamespace, err := common.GetKubectlNamespace(); err == nil {
    67  			cfg.NameSpace = defaultNamespace
    68  		} else {
    69  			return err
    70  		}
    71  	}
    72  
    73  	// Temporarily disabled due to lack of clarity of operator 'final name'
    74  	// and also how to verify if operator is correctly installed.
    75  	// For more info, please refer to:	KOGITO-9562 and KOGITO-9563
    76  	//fmt.Println("šŸ”Ž Checking if the SonataFlow Operator is correctly installed...")
    77  	//if err := common.CheckOperatorInstalled(); err != nil {
    78  	//	return err
    79  	//}
    80  
    81  	return nil
    82  }
    83  
    84  func generateManifests(cfg *DeployUndeployCmdConfig) error {
    85  
    86  	workflowExtensionsType := []string{metadata.YAMLSWExtension, metadata.YMLSWExtension, metadata.JSONSWExtension}
    87  
    88  	fmt.Println("\nšŸ› ļø  Generating your manifests...")
    89  
    90  	fmt.Println("šŸ” Looking for your SonataFlow files...")
    91  	if file, err := findSonataFlowFile(workflowExtensionsType); err != nil {
    92  		return err
    93  	} else {
    94  		cfg.SonataFlowFile = file
    95  	}
    96  	fmt.Printf(" - āœ… SonataFlow file found: %s\n", cfg.SonataFlowFile)
    97  
    98  	fmt.Println("šŸ” Looking for your SonataFlow sub flows...")
    99  	files, err := common.FindFilesWithExtensions(cfg.SubflowsDir, workflowExtensionsType)
   100  	if err != nil {
   101  		return fmt.Errorf("āŒ ERROR: failed to get subflows directory: %w", err)
   102  	}
   103  	cfg.SubFlowsFilesPath = files
   104  	for _, file := range cfg.SubFlowsFilesPath {
   105  		fmt.Printf(" - āœ… SonataFlow subflows found: %s\n", file)
   106  	}
   107  
   108  	fmt.Println("šŸ” Looking for your workflow support files...")
   109  
   110  	dir, err := os.Getwd()
   111  	if err != nil {
   112  		return fmt.Errorf("āŒ ERROR: failed to get current directory: %w", err)
   113  	}
   114  
   115  	fmt.Println("šŸ” Looking for properties files...")
   116  
   117  	applicationPropertiesPath := findApplicationPropertiesPath(dir)
   118  	if applicationPropertiesPath != "" {
   119  		cfg.ApplicationPropertiesPath = applicationPropertiesPath
   120  		fmt.Printf(" - āœ… Properties file found: %s\n", cfg.ApplicationPropertiesPath)
   121  	}
   122  
   123  	supportFileExtensions := []string{metadata.JSONExtension, metadata.YAMLExtension, metadata.YMLExtension}
   124  
   125  	fmt.Println("šŸ” Looking for specs files...")
   126  	files, err = common.FindFilesWithExtensions(cfg.SpecsDir, supportFileExtensions)
   127  	if err != nil {
   128  		return fmt.Errorf("āŒ ERROR: failed to get supportFiles directory: %w", err)
   129  	}
   130  	cfg.SpecsFilesPath = files
   131  	for _, file := range cfg.SpecsFilesPath {
   132  		fmt.Printf(" - āœ… Specs file found: %s\n", file)
   133  	}
   134  
   135  	fmt.Println("šŸ” Looking for schema files...")
   136  	files, err = common.FindFilesWithExtensions(cfg.SchemasDir, supportFileExtensions)
   137  	if err != nil {
   138  		return fmt.Errorf("āŒ ERROR: failed to get supportFiles directory: %w", err)
   139  	}
   140  	cfg.SchemasFilesPath = files
   141  	for _, file := range cfg.SchemasFilesPath {
   142  		fmt.Printf(" - āœ… Schemas file found: %s\n", file)
   143  	}
   144  
   145  	fmt.Println("šŸ” Looking for your dashboard files...")
   146  
   147  	dashboardExtensions := []string{metadata.YAMLExtension, metadata.YMLExtension}
   148  
   149  	files, err = common.FindFilesWithExtensions(cfg.DefaultDashboardsFolder, dashboardExtensions)
   150  	if err != nil {
   151  		return fmt.Errorf("āŒ ERROR: failed to get dashboards directory: %w", err)
   152  	}
   153  	cfg.DashboardsPath = files
   154  	for _, file := range cfg.DashboardsPath {
   155  		fmt.Printf(" - āœ… Dashboard found: %s\n", file)
   156  	}
   157  
   158  	fmt.Println("šŸššļø Generating your Kubernetes manifest files...")
   159  
   160  	swfFile, err := common.MustGetFile(cfg.SonataFlowFile)
   161  	if err != nil {
   162  		return err
   163  	}
   164  
   165  	handler := workflowproj.New(cfg.NameSpace).WithWorkflow(swfFile)
   166  	if cfg.ApplicationPropertiesPath != "" {
   167  		appIO, err := common.MustGetFile(cfg.ApplicationPropertiesPath)
   168  		if err != nil {
   169  			return err
   170  		}
   171  		handler.WithAppProperties(appIO)
   172  	}
   173  
   174  	for _, subflow := range cfg.SubFlowsFilesPath {
   175  		specIO, err := common.MustGetFile(subflow)
   176  		if err != nil {
   177  			return err
   178  		}
   179  		handler.AddResourceAt(filepath.Base(subflow), filepath.Base(cfg.SubflowsDir), specIO)
   180  	}
   181  
   182  	for _, supportFile := range cfg.SchemasFilesPath {
   183  		specIO, err := common.MustGetFile(supportFile)
   184  		if err != nil {
   185  			return err
   186  		}
   187  		handler.AddResourceAt(filepath.Base(supportFile), filepath.Base(cfg.SchemasDir), specIO)
   188  	}
   189  
   190  	for _, supportFile := range cfg.SpecsFilesPath {
   191  		specIO, err := common.MustGetFile(supportFile)
   192  		if err != nil {
   193  			return err
   194  		}
   195  		handler.AddResourceAt(filepath.Base(supportFile), filepath.Base(cfg.SpecsDir), specIO)
   196  	}
   197  
   198  	for _, dashboardFile := range cfg.DashboardsPath {
   199  		specIO, err := common.MustGetFile(dashboardFile)
   200  		if err != nil {
   201  			return err
   202  		}
   203  		handler.AddResourceAt(filepath.Base(dashboardFile), metadata.DashboardsDefaultDirName, specIO)
   204  	}
   205  
   206  	_, err = handler.AsObjects()
   207  	if err != nil {
   208  		return err
   209  	}
   210  
   211  	err = handler.SaveAsKubernetesManifests(cfg.CustomGeneratedManifestDir)
   212  	if err != nil {
   213  		return err
   214  	}
   215  
   216  	return nil
   217  }
   218  
   219  func findApplicationPropertiesPath(directoryPath string) string {
   220  	filePath := filepath.Join(directoryPath, metadata.ApplicationProperties)
   221  
   222  	fileInfo, err := os.Stat(filePath)
   223  	if err != nil || fileInfo.IsDir() {
   224  		return ""
   225  	}
   226  
   227  	return filePath
   228  }
   229  
   230  func findSonataFlowFile(extensions []string) (string, error) {
   231  
   232  	dir, err := os.Getwd()
   233  	if err != nil {
   234  		return "", fmt.Errorf("āŒ ERROR: failed to get current directory: %w", err)
   235  	}
   236  
   237  	var matchingFiles []string
   238  	for _, ext := range extensions {
   239  		files, _ := filepath.Glob(filepath.Join(dir, "*."+ext))
   240  		matchingFiles = append(matchingFiles, files...)
   241  	}
   242  
   243  	switch len(matchingFiles) {
   244  	case 0:
   245  		return "", fmt.Errorf("āŒ ERROR: no matching files found")
   246  	case 1:
   247  		return matchingFiles[0], nil
   248  	default:
   249  		return "", fmt.Errorf("āŒ ERROR: multiple SonataFlow definition files found")
   250  	}
   251  }
   252  
   253  func setupConfigManifestPath(cfg *DeployUndeployCmdConfig) error {
   254  
   255  	if len(cfg.CustomGeneratedManifestDir) == 0 {
   256  		tempDir, err := os.MkdirTemp("", "manifests")
   257  		if err != nil {
   258  			return fmt.Errorf("āŒ ERROR: failed to create temporary directory: %w", err)
   259  		}
   260  		cfg.CustomGeneratedManifestDir = tempDir
   261  		cfg.TempDir = tempDir
   262  	} else {
   263  		_, err := os.Stat(cfg.CustomGeneratedManifestDir)
   264  		if err != nil {
   265  			return fmt.Errorf("āŒ ERROR: cannot find or open directory %s : %w", cfg.CustomGeneratedManifestDir, err)
   266  		}
   267  	}
   268  	return nil
   269  }