Files
kubescape/core/cautils/kustomizedirectory.go
majiayu000andClaude Opus 4.5 0f2125817b fix: enable kustomize overlays to load base configurations
Fixes #1617. The kustomize build was failing for overlays that reference
base configurations in parent directories (e.g., ../../base). This was
because krusty.MakeDefaultOptions() defaults to LoadRestrictionsRootOnly,
which prevents loading resources from outside the kustomize directory.

Changed LoadRestrictions to LoadRestrictionsNone to allow overlays to
properly resolve and merge base configurations during scanning.

Added tests to verify:
- Overlay directories can successfully load resources from base directories
- Base directories continue to work as before
- The merged configuration includes resources from both base and overlay

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: majiayu000 <1835304752@qq.com>
2025-12-31 06:14:10 +08:00

117 lines
2.9 KiB
Go

package cautils
import (
"os"
"path/filepath"
"github.com/kubescape/go-logger"
"github.com/kubescape/go-logger/helpers"
"github.com/kubescape/k8s-interface/workloadinterface"
"github.com/kubescape/opa-utils/objectsenvelopes/localworkload"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
type KustomizeDirectory struct {
path string
}
// Used for checking if there is "Kustomization" file in the given Directory
var kustomizationFileMatchers = [3]string{"kustomization.yml", "kustomization.yaml", "Kustomization"}
func isKustomizeDirectory(path string) bool {
if ok := isDir(path); !ok {
return false
}
matches := 0
for _, kustomizationFileMatcher := range kustomizationFileMatchers {
checkPath := filepath.Join(path, kustomizationFileMatcher)
if _, err := os.Stat(checkPath); err == nil {
matches++
}
}
switch matches {
case 0:
return false
case 1:
return true
default:
logger.L().Info("Multiple kustomize files found while checking the Kustomize Directory")
return false
}
}
// Used for checking if the path is Kustomization file.
func IsKustomizeFile(path string) bool {
fileName := filepath.Base(path)
for _, kustomizationFileMatcher := range kustomizationFileMatchers {
if fileName == kustomizationFileMatcher {
return true
}
}
return false
}
func NewKustomizeDirectory(path string) *KustomizeDirectory {
return &KustomizeDirectory{
path: path,
}
}
func getKustomizeDirectoryName(path string) string {
if ok := isKustomizeDirectory(path); !ok {
return ""
}
return path
}
// Get Workloads, creates the yaml files(K8s resources) using Kustomize and
// renders the workloads from the yaml files (k8s resources)
func (kd *KustomizeDirectory) GetWorkloads(kustomizeDirectoryPath string) (map[string][]workloadinterface.IMetadata, []error) {
fSys := filesys.MakeFsOnDisk()
// Use LoadRestrictionsNone to allow loading resources from outside the kustomize directory.
// This is necessary for overlays that reference base configurations in parent directories.
opts := krusty.MakeDefaultOptions()
opts.LoadRestrictions = types.LoadRestrictionsNone
kustomizer := krusty.MakeKustomizer(opts)
resmap, err := kustomizer.Run(fSys, kustomizeDirectoryPath)
if err != nil {
return nil, []error{err}
}
yml, err := resmap.AsYaml()
if err != nil {
return nil, []error{err}
}
workloads := make(map[string][]workloadinterface.IMetadata, 0)
errs := []error{}
wls, e := ReadFile(yml, YAML_FILE_FORMAT)
if e != nil {
logger.L().Debug("failed to read rendered yaml file", helpers.String("file", kustomizeDirectoryPath), helpers.Error(e))
}
if len(wls) != 0 {
workloads[kustomizeDirectoryPath] = []workloadinterface.IMetadata{}
for i := range wls {
lw := localworkload.NewLocalWorkload(wls[i].GetObject())
lw.SetPath(kustomizeDirectoryPath)
workloads[kustomizeDirectoryPath] = append(workloads[kustomizeDirectoryPath], lw)
}
}
return workloads, errs
}