1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-09 17:37:12 +00:00
kyverno/cmd/cli/kubectl-kyverno/test/load.go
Charles-Edouard Brétéché 7ffb049b7f
refactor: restructure cli test command (#6942)
* refactor: restructure cli test command

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
2023-04-18 12:08:17 +00:00

145 lines
4.5 KiB
Go

package test
import (
"fmt"
"io"
"net/url"
"os"
"path"
"path/filepath"
"sort"
"strings"
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/memfs"
sanitizederror "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/sanitizedError"
gitutils "github.com/kyverno/kyverno/pkg/utils/git"
"k8s.io/apimachinery/pkg/util/yaml"
"sigs.k8s.io/controller-runtime/pkg/log"
)
type policy struct {
bytes []byte
resourcePath string
}
func loadTests(
dirPath []string,
fileName string,
gitBranch string,
) (billy.Filesystem, []policy, []error) {
var policies []policy
var errors []error
if strings.Contains(dirPath[0], "https://") {
fs := memfs.New()
if gitURL, err := url.Parse(dirPath[0]); err != nil {
errors = append(errors, sanitizederror.NewWithError("failed to parse URL", err))
} else {
pathElems := strings.Split(gitURL.Path[1:], "/")
if len(pathElems) <= 1 {
err := fmt.Errorf("invalid URL path %s - expected https://github.com/:owner/:repository/:branch (without --git-branch flag) OR https://github.com/:owner/:repository/:directory (with --git-branch flag)", gitURL.Path)
fmt.Printf("Error: failed to parse URL \nCause: %s\n", err)
os.Exit(1)
}
gitURL.Path = strings.Join([]string{pathElems[0], pathElems[1]}, "/")
repoURL := gitURL.String()
var gitPathToYamls string
if gitBranch == "" {
gitPathToYamls = "/"
if string(dirPath[0][len(dirPath[0])-1]) == "/" {
gitBranch = strings.ReplaceAll(dirPath[0], repoURL+"/", "")
} else {
gitBranch = strings.ReplaceAll(dirPath[0], repoURL, "")
}
if gitBranch == "" {
gitBranch = "main"
} else if string(gitBranch[0]) == "/" {
gitBranch = gitBranch[1:]
}
} else {
if string(dirPath[0][len(dirPath[0])-1]) == "/" {
gitPathToYamls = strings.ReplaceAll(dirPath[0], repoURL+"/", "/")
} else {
gitPathToYamls = strings.ReplaceAll(dirPath[0], repoURL, "/")
}
}
_, cloneErr := gitutils.Clone(repoURL, fs, gitBranch)
if cloneErr != nil {
fmt.Printf("Error: failed to clone repository \nCause: %s\n", cloneErr)
log.Log.V(3).Info(fmt.Sprintf("failed to clone repository %v as it is not valid", repoURL), "error", cloneErr)
os.Exit(1)
}
if policyYamls, err := gitutils.ListYamls(fs, gitPathToYamls); err != nil {
errors = append(errors, sanitizederror.NewWithError("failed to list YAMLs in repository", err))
} else {
sort.Strings(policyYamls)
for _, yamlFilePath := range policyYamls {
file, err := fs.Open(yamlFilePath)
if err != nil {
errors = append(errors, sanitizederror.NewWithError("Error: failed to open file", err))
continue
}
if path.Base(file.Name()) == fileName {
policyresoucePath := strings.Trim(yamlFilePath, fileName)
bytes, err := io.ReadAll(file)
if err != nil {
errors = append(errors, sanitizederror.NewWithError("Error: failed to read file", err))
continue
}
policyBytes, err := yaml.ToJSON(bytes)
if err != nil {
errors = append(errors, sanitizederror.NewWithError("failed to convert to JSON", err))
continue
}
policies = append(policies, policy{
bytes: policyBytes,
resourcePath: policyresoucePath,
})
}
}
}
}
return fs, policies, errors
} else {
path := filepath.Clean(dirPath[0])
policies, errors = loadLocalTest(path, fileName)
return nil, policies, errors
}
}
func loadLocalTest(
path string,
fileName string,
) ([]policy, []error) {
var policies []policy
var errors []error
files, err := os.ReadDir(path)
if err != nil {
errors = append(errors, fmt.Errorf("failed to read %v: %v", path, err.Error()))
} else {
for _, file := range files {
if file.IsDir() {
ps, errs := loadLocalTest(filepath.Join(path, file.Name()), fileName)
policies = append(policies, ps...)
errors = append(errors, errs...)
} else if file.Name() == fileName {
// We accept the risk of including files here as we read the test dir only.
yamlFile, err := os.ReadFile(filepath.Join(path, file.Name())) // #nosec G304
if err != nil {
errors = append(errors, sanitizederror.NewWithError("unable to read yaml", err))
continue
}
valuesBytes, err := yaml.ToJSON(yamlFile)
if err != nil {
errors = append(errors, sanitizederror.NewWithError("failed to convert json", err))
continue
}
policies = append(policies, policy{
bytes: valuesBytes,
resourcePath: path,
})
}
}
}
return policies, errors
}