From ea39abb9a03e788fd63af010e8d48944d38a1fbf Mon Sep 17 00:00:00 2001 From: Bella Khizgiyaev Date: Wed, 6 Sep 2023 12:59:08 +0300 Subject: [PATCH] OVA: Change the scanning for ova and ovf files inside the NFS directory Signed-off-by: Bella Khizgiyaev --- cmd/ova-provider-server/BUILD.bazel | 9 +- cmd/ova-provider-server/nfs_test.go | 113 ++++++++++++++++++ .../ova-provider-server.go | 63 ++++++---- 3 files changed, 162 insertions(+), 23 deletions(-) create mode 100644 cmd/ova-provider-server/nfs_test.go diff --git a/cmd/ova-provider-server/BUILD.bazel b/cmd/ova-provider-server/BUILD.bazel index 6db2597ee..0452abde8 100644 --- a/cmd/ova-provider-server/BUILD.bazel +++ b/cmd/ova-provider-server/BUILD.bazel @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") go_library( name = "ova-provider-server_lib", @@ -24,3 +24,10 @@ container_image( base = "@ova-provider-server-image-dockerfile//image:dockerfile_image.tar", visibility = ["//visibility:public"], ) + +go_test( + name = "ova-provider-server_test", + srcs = ["nfs_test.go"], + embed = [":ova-provider-server_lib"], + deps = ["//vendor/github.com/onsi/gomega"], +) diff --git a/cmd/ova-provider-server/nfs_test.go b/cmd/ova-provider-server/nfs_test.go new file mode 100644 index 000000000..f7792475d --- /dev/null +++ b/cmd/ova-provider-server/nfs_test.go @@ -0,0 +1,113 @@ +package main + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + . "github.com/onsi/gomega" +) + +func TestFindOVAFiles(t *testing.T) { + g := NewGomegaWithT(t) + + tests := []struct { + name string + setup func(directory string) + expectedOVAs []string + expectedOVFs []string + expectError bool + }{ + { + name: "basic structure", + setup: func(directory string) { + os.MkdirAll(filepath.Join(directory, "subdir1", "subdir2"), 0755) + ioutil.WriteFile(filepath.Join(directory, "test.ova"), []byte{}, 0644) + ioutil.WriteFile(filepath.Join(directory, "test.ovf"), []byte{}, 0644) + ioutil.WriteFile(filepath.Join(directory, "subdir1", "test1.ova"), []byte{}, 0644) + ioutil.WriteFile(filepath.Join(directory, "subdir1", "test1.ovf"), []byte{}, 0644) + ioutil.WriteFile(filepath.Join(directory, "subdir1", "subdir2", "test2.ovf"), []byte{}, 0644) + }, + expectedOVAs: []string{"test.ova", "subdir1/test1.ova"}, + expectedOVFs: []string{"test.ovf", "subdir1/test1.ovf", "subdir1/subdir2/test2.ovf"}, + expectError: false, + }, + { + name: "non-existent directory", + setup: func(directory string) { + os.RemoveAll(directory) + }, + expectedOVAs: nil, + expectedOVFs: nil, + expectError: true, + }, + { + name: "non-ova/ovf files", + setup: func(directory string) { + ioutil.WriteFile(filepath.Join(directory, "test.txt"), []byte{}, 0644) + }, + expectedOVAs: nil, + expectedOVFs: nil, + expectError: false, + }, + { + name: "incorrect depth", + setup: func(directory string) { + os.MkdirAll(filepath.Join(directory, "subdir1", "subdir2"), 0755) + ioutil.WriteFile(filepath.Join(directory, "subdir1", "subdir2", "test3.ova"), []byte{}, 0644) + }, + expectedOVAs: nil, + expectedOVFs: nil, + expectError: false, + }, + { + name: "folder with extension", + setup: func(directory string) { + os.MkdirAll(filepath.Join(directory, "subdir1.ova"), 0755) + os.MkdirAll(filepath.Join(directory, "subdir2.ovf"), 0755) + }, + expectedOVAs: nil, + expectedOVFs: nil, + expectError: false, + }, + { + name: "files inside folders with extension", + setup: func(directory string) { + os.MkdirAll(filepath.Join(directory, "subdir1.ova"), 0755) + os.MkdirAll(filepath.Join(directory, "subdir2.ovf"), 0755) + ioutil.WriteFile(filepath.Join(directory, "subdir1.ova", "test.ova"), []byte{}, 0644) + ioutil.WriteFile(filepath.Join(directory, "subdir2.ovf", "test.ovf"), []byte{}, 0644) + }, + expectedOVAs: []string{"subdir1.ova/test.ova"}, + expectedOVFs: []string{"subdir2.ovf/test.ovf"}, + expectError: false, + }, + } + + for _, testCase := range tests { + t.Run(testCase.name, func(t *testing.T) { + testDir, err := ioutil.TempDir("", "ova_test") + g.Expect(err).NotTo(HaveOccurred()) + + testCase.setup(testDir) + + for i, relPath := range testCase.expectedOVAs { + testCase.expectedOVAs[i] = filepath.Join(testDir, relPath) + } + for i, relPath := range testCase.expectedOVFs { + testCase.expectedOVFs[i] = filepath.Join(testDir, relPath) + } + + ovaFiles, ovfFiles, err := findOVAFiles(testDir) + if testCase.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(ovaFiles).To(ConsistOf(testCase.expectedOVAs)) + g.Expect(ovfFiles).To(ConsistOf(testCase.expectedOVFs)) + } + os.RemoveAll(testDir) + }) + } +} diff --git a/cmd/ova-provider-server/ova-provider-server.go b/cmd/ova-provider-server/ova-provider-server.go index 1d5fab08d..ea1d9ddbb 100644 --- a/cmd/ova-provider-server/ova-provider-server.go +++ b/cmd/ova-provider-server/ova-provider-server.go @@ -23,6 +23,8 @@ import ( const ( invalidRequestMethodMsg = "Invalid request method" errorProcessingOvfMsg = "Error processing OVF file" + OvaExt = ".ova" + OvfExt = ".ovf" ) // xml struct @@ -292,33 +294,50 @@ func scanOVAsOnNFS() (envelopes []Envelope, ovaPaths []string) { return envelopes, filesPath } -func findOVAFiles(directory string) ([]string, []string, error) { - childs, err := os.ReadDir(directory) - if err != nil { - return nil, nil, err - } +func findOVAFiles(directory string) (ovaFiles []string, ovfFiles []string, err error) { + var ovaMaxDepth = 2 - var ovaFiles, ovfFiles []string - for _, child := range childs { - if !child.IsDir() { - continue - } - newDir := directory + "/" + child.Name() - files, err := os.ReadDir(newDir) + err = filepath.WalkDir(directory, func(path string, info os.DirEntry, err error) error { if err != nil { - return nil, nil, err + return err } - for _, file := range files { - path := filepath.Join(directory, child.Name(), file.Name()) - switch { - case strings.HasSuffix(strings.ToLower(file.Name()), ".ova"): - ovaFiles = append(ovaFiles, path) - case strings.HasSuffix(strings.ToLower(file.Name()), ".ovf"): - ovfFiles = append(ovfFiles, path) - } + + if info.IsDir() { + return nil + } + + relativePath, _ := filepath.Rel(directory, path) + depth := len(strings.Split(relativePath, string(filepath.Separator))) + + switch { + case (depth <= ovaMaxDepth) && isOva(info.Name()): + ovaFiles = append(ovaFiles, path) + + case (depth <= ovaMaxDepth+1) && isOvf(info.Name()): + ovfFiles = append(ovfFiles, path) } + + return nil + }) + + if err != nil { + fmt.Println("Error scanning OVA and OVF files: ", err) + return nil, nil, err } - return ovaFiles, ovfFiles, nil + return +} + +func isOva(filename string) bool { + return hasSuffixIgnoreCase(filename, OvaExt) +} + +func isOvf(filename string) bool { + return hasSuffixIgnoreCase(filename, OvfExt) +} + +// Checks if the given file has the desired extension +func hasSuffixIgnoreCase(fileName, suffix string) bool { + return strings.HasSuffix(strings.ToLower(fileName), strings.ToLower(suffix)) } func readOVFFromOVA(ovaFile string) (*Envelope, error) {