github.com/verrazzano/verrazzano@v1.7.1/tools/oam-converter/pkg/app/confdata.go (about) 1 // Copyright (c) 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package app 5 6 import ( 7 "encoding/json" 8 "errors" 9 "fmt" 10 consts "github.com/verrazzano/verrazzano/tools/oam-converter/pkg/constants" 11 "github.com/verrazzano/verrazzano/tools/oam-converter/pkg/resources" 12 "github.com/verrazzano/verrazzano/tools/oam-converter/pkg/traits" 13 "github.com/verrazzano/verrazzano/tools/oam-converter/pkg/types" 14 workload "github.com/verrazzano/verrazzano/tools/oam-converter/pkg/workloads" 15 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 16 "os" 17 "path/filepath" 18 "sigs.k8s.io/controller-runtime/pkg/client" 19 "sigs.k8s.io/controller-runtime/pkg/client/config" 20 "sigs.k8s.io/yaml" 21 "strings" 22 ) 23 24 func ConfData() error { 25 26 var inputDirectory string 27 var outputDirectory string 28 29 //Check the length of args 30 if len(os.Args) != 3 { 31 32 return errors.New("not enough args to run tool. Add input directory path and output directory path as args") 33 34 } 35 inputDirectory = os.Args[1] 36 outputDirectory = os.Args[2] 37 38 //used to store app file data 39 var appData []map[string]interface{} 40 41 //used to store comp file data 42 var components []map[string]interface{} 43 44 //used to store non-oam file data 45 // var k8sResources unstructured.Unstructured 46 47 //iterate through user inputted directory 48 files, err := iterateDirectory(inputDirectory) 49 if err != nil { 50 51 return fmt.Errorf("error in iterating over directory %w", err) 52 } 53 54 //Read each file from the input directory 55 for _, input := range files { 56 data, err := os.ReadFile(input) 57 if err != nil { 58 return fmt.Errorf("error in reading file %w", err) 59 } 60 61 datastr := string(data) 62 63 //Split the objects using "---" delimiter 64 objects := strings.Split(datastr, "---") 65 66 //Iterate over each object to segregate into applicationConfiguration kind or Component kind 67 for _, obj := range objects { 68 var component map[string]interface{} 69 err := yaml.Unmarshal([]byte(obj), &component) 70 if err != nil { 71 return errors.New("error in unmarshalling the components") 72 } 73 compKind, found, err := unstructured.NestedString(component, "kind") 74 if !found || err != nil { 75 return errors.New("component kind doesn't exist or not found in the specified type") 76 } 77 compVersion, found, err := unstructured.NestedString(component, "apiVersion") 78 if !found || err != nil { 79 return errors.New("component api version doesn't exist or not found in the specified type") 80 } 81 82 //Check the kind of each component and apiVersion 83 if compKind == "Component" && compVersion == consts.CompAPIVersion { 84 components = append(components, component) 85 } else if compKind == "ApplicationConfiguration" && compVersion == consts.CompAPIVersion { 86 appData = append(appData, component) 87 } 88 89 } 90 } 91 92 //Extract traits from app file 93 conversionComponents, err := traits.ExtractTrait(appData) 94 95 if err != nil { 96 return errors.New("failed extracting traits from app") 97 } 98 //Extract workloads from app file 99 100 conversionComponents, err = workload.ExtractWorkload(components, conversionComponents) 101 102 if err != nil { 103 return errors.New("error in extracting workload") 104 } 105 106 cfg, _ := config.GetConfig() 107 cli, _ := client.New(cfg, client.Options{}) 108 //Create child resources 109 outputResources, err := resources.CreateResources(cli, conversionComponents) 110 111 if err != nil { 112 return err 113 } 114 //Write the K8s child resources to the file 115 err = writeKubeResources(outputDirectory, outputResources) 116 if err != nil { 117 return err 118 119 } 120 return nil 121 } 122 123 // writeKubeResources Write the kube resources to the files in output directory 124 func writeKubeResources(outputDirectory string, outputResources *types.KubeResources) (err error) { 125 126 //Write virtual services to files 127 if outputResources.VirtualServices != nil { 128 for _, virtualService := range outputResources.VirtualServices { 129 130 fileName := "" + virtualService.Name + ".yaml" 131 filePath := filepath.Join(outputDirectory, fileName) 132 133 f, err := os.Create(filePath) 134 if err != nil { 135 return err 136 } 137 138 defer f.Close() 139 140 r, err := json.Marshal(virtualService) 141 if err != nil { 142 return err 143 } 144 output, err := yaml.JSONToYAML(r) 145 if err != nil { 146 return err 147 } 148 149 _, err = f.WriteString(string(output)) 150 if err != nil { 151 return err 152 } 153 154 } 155 } 156 157 //Write down gateway to files 158 if outputResources.Gateway != nil { 159 160 fileName := "gateway.yaml" 161 filePath := filepath.Join(outputDirectory, fileName) 162 163 f, err := os.Create(filePath) 164 if err != nil { 165 return err 166 } 167 defer f.Close() 168 gatewayYaml, err := yaml.Marshal(outputResources.Gateway) 169 if err != nil { 170 return fmt.Errorf("failed to marshal YAML: %w", err) 171 } 172 173 _, err = f.WriteString(string(gatewayYaml)) 174 if err != nil { 175 return fmt.Errorf("failed to write YAML to file: %w", err) 176 } 177 178 } 179 180 //Write down destination rules to files 181 if outputResources.DestinationRules != nil { 182 for _, destinationRule := range outputResources.DestinationRules { 183 184 if destinationRule != nil { 185 fileName := "" + destinationRule.Name 186 filePath := filepath.Join(outputDirectory, fileName) 187 188 f, err := os.Create(filePath) 189 if err != nil { 190 return err 191 } 192 193 defer f.Close() 194 195 r, err := json.Marshal(destinationRule) 196 if err != nil { 197 return err 198 } 199 output, err := yaml.JSONToYAML(r) 200 if err != nil { 201 return err 202 } 203 _, err2 := f.WriteString(string(output)) 204 if err2 != nil { 205 return err2 206 } 207 } 208 } 209 } 210 211 //Write down Authorization Policies to files 212 if outputResources.AuthPolicies != nil { 213 for _, authPolicy := range outputResources.AuthPolicies { 214 215 if authPolicy != nil { 216 fileName := "authzpolicy.yaml" 217 filePath := filepath.Join(outputDirectory, fileName) 218 219 f, err := os.Create(filePath) 220 if err != nil { 221 return err 222 } 223 224 defer f.Close() 225 r, err := json.Marshal(authPolicy) 226 if err != nil { 227 return err 228 } 229 output, err := yaml.JSONToYAML(r) 230 if err != nil { 231 return err 232 } 233 234 _, err2 := f.WriteString(string(output)) 235 if err2 != nil { 236 return err2 237 } 238 } 239 } 240 } 241 242 //Write down Service Monitors to files 243 if outputResources.ServiceMonitors != nil { 244 var output string 245 fileName := "output.yaml" 246 filePath := filepath.Join(outputDirectory, fileName) 247 f, err := os.Create(filePath) 248 if err != nil { 249 return err 250 } 251 252 defer f.Close() 253 254 for _, servicemonitor := range outputResources.ServiceMonitors { 255 r, err := json.Marshal(servicemonitor) 256 if err != nil { 257 return err 258 259 } 260 out, err := yaml.JSONToYAML(r) 261 if err != nil { 262 return err 263 } 264 output = output + "---\n" + string(out) 265 } 266 267 _, err2 := f.WriteString(string(output)) 268 if err2 != nil { 269 return err2 270 } 271 272 } 273 return nil 274 275 } 276 277 // iterateDirectory Iterate over input directory 278 func iterateDirectory(path string) ([]string, error) { 279 var files []string 280 281 filepath.Walk(path, func(path string, info os.FileInfo, err error) error { 282 if err != nil { 283 return err 284 } 285 if strings.Contains(info.Name(), "yaml") || strings.Contains(info.Name(), "yml") { 286 files = append(files, path) 287 } 288 return nil 289 }) 290 return files, nil 291 }