pkg/filematches/filematches.go (101 lines of code) (raw):

package filematches import ( "errors" "log" "os" "path/filepath" "github.com/yannh/kubeconform/pkg/validator" ) type FileMatches struct { dest string patterns []string deploymentFiles []string } func (f *FileMatches) findDeploymentFiles(dest string) error { err := filepath.Walk(dest, f.walkFunc) if err != nil { return err } return nil } func (f *FileMatches) walkFunc(path string, info os.FileInfo, err error) error { if err != nil { log.Fatal(err) return err } if info.IsDir() { return nil } for _, pattern := range f.patterns { if matched, err := filepath.Match(pattern, filepath.Base(path)); err != nil { return err } else if matched && isValidK8sFile(path) { f.deploymentFiles = append(f.deploymentFiles, path) } } return nil } // TODO: maybe generalize this function in the future func isValidK8sFile(filePath string) bool { f, err := os.Open(filePath) if err != nil { log.Fatal(err) } v, err := validator.New(nil, validator.Opts{Strict: true}) if err != nil { log.Fatalf("failed initializing validator: %s", err) } for i, res := range v.Validate(filePath, f) { // A file might contain multiple resources // File starts with ---, the parser assumes a first empty resource if res.Status == validator.Invalid { log.Printf("resource %d in file %s is not valid: %s", i, filePath, res.Err) return false } if res.Status == validator.Error { log.Printf("error while processing resource %d in file %s: %s", i, filePath, res.Err) return false } } return true } func (f *FileMatches) hasDeploymentFiles() bool { return len(f.deploymentFiles) > 0 } func createK8sFileMatches(dest string) *FileMatches { l := &FileMatches{ dest: dest, patterns: []string{"*.yaml", "*.yml"}, deploymentFiles: []string{}, } err := l.findDeploymentFiles(dest) if err != nil { log.Fatal(err) } return l } func SearchDirectory(dest string) (bool, bool, error) { // check if Dockerfile exists var hasDockerFile bool dockerfilePath := dest + "/Dockerfile" _, err := os.Stat(dockerfilePath) if err == nil { hasDockerFile = true } else if errors.Is(err, os.ErrNotExist) { hasDockerFile = false } else { return false, false, err } // recursive directory search for valid yaml files fileMatches := createK8sFileMatches(dest) _, err = FindDraftDeploymentFiles(dest) hasDeploymentFiles := fileMatches.hasDeploymentFiles() || err == nil return hasDockerFile, hasDeploymentFiles, nil } func FindDraftDeploymentFiles(dest string) (deploymentType string, err error) { if _, err := os.Stat(dest + "/charts"); !os.IsNotExist(err) { return "helm", nil } if _, err := os.Stat(dest + "/overlays"); !os.IsNotExist(err) { return "kustomize", nil } if _, err := os.Stat(dest + "/manifests"); !os.IsNotExist(err) { return "manifests", nil } return "", errors.New("no supported deployment files found") }