github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow@v0.28.1-0.20240311201729-34c6856b157f/pkg/common/operator.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 common 21 22 import ( 23 "bufio" 24 "bytes" 25 "fmt" 26 "github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/metadata" 27 "gopkg.in/yaml.v2" 28 "io" 29 "os" 30 "os/exec" 31 "path/filepath" 32 "strings" 33 ) 34 35 type Document struct { 36 Kind string `yaml:"kind"` 37 } 38 39 func ExecuteKubectlApply(crd, namespace string) error { 40 41 cmd := exec.Command("kubectl", 42 "apply", 43 "-f", crd, 44 "-n", namespace, 45 "--validate=false") 46 47 var stderror bytes.Buffer 48 49 cmd.Stdout = os.Stdout 50 cmd.Stderr = &stderror //os.Stderr 51 52 err := cmd.Run() 53 scanner := bufio.NewScanner(&stderror) 54 for scanner.Scan() { 55 line := scanner.Text() 56 //Temporarily removing the following warning: 57 //In this context, using apply or create are interchangeable, but generates a warning. 58 //Warning: resource configmaps/service-props is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically. 59 //This is tracked here: https://issues.redhat.com/browse/KOGITO-9391 and it will be fixed by 60 //https://issues.redhat.com/browse/KOGITO-9381 61 if !strings.Contains(line, "kubectl.kubernetes.io/last-applied-configuration") { 62 fmt.Fprintln(os.Stderr, line) 63 } 64 } 65 if err != nil { 66 fmt.Printf("has a error") 67 return fmt.Errorf("❌ ERROR: failed to execute kubectl apply command for %s: %s", crd, err) 68 } 69 70 return nil 71 } 72 73 func ExecuteKubectlDelete(crd, namespace string) error { 74 75 cmd := exec.Command("kubectl", 76 "delete", 77 "-f", crd, 78 "-n", namespace) 79 cmd.Stdout = os.Stdout 80 cmd.Stderr = os.Stderr 81 82 err := cmd.Run() 83 if err != nil { 84 return fmt.Errorf("❌ ERROR: failed to execute kubectl delete command for %s: %s", crd, err) 85 } 86 87 return nil 88 } 89 90 func CheckOperatorInstalled() error { 91 cmd := exec.Command("kubectl", "get", "pods", "-n", metadata.OperatorName) 92 93 output, err := cmd.Output() 94 if err != nil { 95 return fmt.Errorf("❌ ERROR: SonataFlow Operator not found %w", err) 96 } 97 98 // Check if the pod is running 99 operatorRunning := checkOperatorRunning(string(output)) 100 if !operatorRunning { 101 return fmt.Errorf("❌ ERROR: SonataFlow Operator not found") 102 } 103 104 fmt.Println(" - ✅ SonataFlow Operator is available") 105 return nil 106 } 107 108 func checkOperatorRunning(getPodsOutPut string) bool { 109 pods := strings.Split(getPodsOutPut, "\n") 110 for _, pod := range pods { 111 // Split each line into fields (NAME, READY, STATUS, RESTARTS, AGE) 112 fields := strings.Fields(pod) 113 114 // Check if this line contains information about the desired operator manager pod 115 if len(fields) > 2 && strings.HasPrefix(fields[0], metadata.OperatorManagerPod) && fields[2] == "Running" { 116 return true 117 } 118 } 119 return false 120 } 121 122 func FindServiceFiles(directory string) ([]string, error) { 123 var serviceFiles []string 124 125 err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error { 126 if err != nil { 127 return fmt.Errorf("❌ ERROR: failure accessing a path %q: %v\n", path, err) 128 } 129 130 if info.IsDir() || filepath.Ext(path) != ".yaml" { 131 return nil 132 } 133 134 file, err := os.Open(path) 135 if err != nil { 136 return fmt.Errorf("❌ ERROR: failure opening file %q: %v\n", path, err) 137 } 138 defer file.Close() 139 140 byteValue, err := io.ReadAll(file) 141 if err != nil { 142 return fmt.Errorf("❌ ERROR: failure reading file %q: %v\n", path, err) 143 } 144 145 var doc Document 146 if err := yaml.Unmarshal(byteValue, &doc); err != nil { 147 return fmt.Errorf("❌ ERROR: failure unmarshalling YAML from file %q: %v\n", path, err) 148 } 149 150 if doc.Kind == metadata.ManifestServiceFilesKind { 151 serviceFiles = append(serviceFiles, path) 152 } 153 154 return nil 155 }) 156 157 if err != nil { 158 return nil, err 159 } 160 161 return serviceFiles, nil 162 }