mirror of
https://github.com/kubescape/kubescape.git
synced 2026-02-14 18:09:55 +00:00
Support glob file loading (#41)
* recursive glob * adding helm support to readme * update glob function
This commit is contained in:
14
README.md
14
README.md
@@ -1,7 +1,7 @@
|
||||
<img src="docs/kubescape.png" width="300" alt="logo" align="center">
|
||||
|
||||
[](https://github.com/armosec/kubescape/actions/workflows/build.yaml)
|
||||
[]()
|
||||
[](https://github.com/armosec/kubescape)
|
||||
[](https://goreportcard.com/report/github.com/armosec/kubescape)
|
||||
|
||||
Kubescape is the first tool for testing if Kubernetes is deployed securely as defined in [Kubernetes Hardening Guidance by NSA and CISA](https://www.nsa.gov/News-Features/Feature-Stories/Article-View/Article/2716980/nsa-cisa-release-kubernetes-hardening-guidance/)
|
||||
@@ -77,6 +77,18 @@ kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --sile
|
||||
kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --silence -o junit > results.xml
|
||||
```
|
||||
|
||||
### Helm Support
|
||||
|
||||
1. Render the helm template to an output yaml
|
||||
```
|
||||
helm template [CHART] [flags] --generate-name --dry-run --output-dir helm-output
|
||||
```
|
||||
|
||||
2. Run `kubescape` with rended yaml files
|
||||
```
|
||||
kubescape scan framework nsa helm-output/*
|
||||
```
|
||||
|
||||
# How to build
|
||||
|
||||
Note: development (and the release process) is done with Go `1.16`
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"kubescape/cautils"
|
||||
"kubescape/cautils/k8sinterface"
|
||||
"kubescape/cautils/opapolicy"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -38,7 +39,7 @@ func (policyHandler *PolicyHandler) loadResources(frameworks []opapolicy.Framewo
|
||||
workloads = append(workloads, w...)
|
||||
}
|
||||
|
||||
// load resource from url
|
||||
// load resources from url
|
||||
w, err = loadResourcesFromUrl(scanInfo.InputPatterns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -47,11 +48,15 @@ func (policyHandler *PolicyHandler) loadResources(frameworks []opapolicy.Framewo
|
||||
workloads = append(workloads, w...)
|
||||
}
|
||||
|
||||
if len(workloads) == 0 {
|
||||
return nil, fmt.Errorf("empty list of workloads - no workloads found")
|
||||
}
|
||||
|
||||
// map all resources: map["/group/version/kind"][]<k8s workloads>
|
||||
allResources := mapResources(workloads)
|
||||
|
||||
// build resources map
|
||||
// map resources based on framework requrid resources: map["/group/version/kind"][]<k8s workloads>
|
||||
// map resources based on framework required resources: map["/group/version/kind"][]<k8s workloads>
|
||||
k8sResources := setResourceMap(frameworks)
|
||||
|
||||
// save only relevant resources
|
||||
@@ -78,9 +83,6 @@ func loadResourcesFromFiles(inputPatterns []string) ([]k8sinterface.IWorkload, e
|
||||
if len(errs) > 0 {
|
||||
cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error
|
||||
}
|
||||
if len(workloads) == 0 {
|
||||
return workloads, fmt.Errorf("empty list of workloads - no workloads found")
|
||||
}
|
||||
return workloads, nil
|
||||
}
|
||||
|
||||
@@ -138,10 +140,11 @@ func readFile(fileContent []byte, fileFromat FileFormat) ([]k8sinterface.IWorklo
|
||||
case JSON_FILE_FORMAT:
|
||||
return readJsonFile(fileContent)
|
||||
default:
|
||||
return nil, []error{fmt.Errorf("file extension %s not supported", fileFromat)}
|
||||
return nil, nil // []error{fmt.Errorf("file extension %s not supported", fileFromat)}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func listFiles(patterns []string) ([]string, []error) {
|
||||
files := []string{}
|
||||
errs := []error{}
|
||||
@@ -149,7 +152,11 @@ func listFiles(patterns []string) ([]string, []error) {
|
||||
if strings.HasPrefix(patterns[i], "http") {
|
||||
continue
|
||||
}
|
||||
f, err := filepath.Glob(patterns[i])
|
||||
if !filepath.IsAbs(patterns[i]) {
|
||||
o, _ := os.Getwd()
|
||||
patterns[i] = filepath.Join(o, patterns[i])
|
||||
}
|
||||
f, err := glob(filepath.Split(patterns[i])) //filepath.Glob(patterns[i])
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
} else {
|
||||
@@ -209,7 +216,9 @@ func convertYamlToJson(i interface{}) interface{} {
|
||||
case map[interface{}]interface{}:
|
||||
m2 := map[string]interface{}{}
|
||||
for k, v := range x {
|
||||
m2[k.(string)] = convertYamlToJson(v)
|
||||
if s, ok := k.(string); ok {
|
||||
m2[s] = convertYamlToJson(v)
|
||||
}
|
||||
}
|
||||
return m2
|
||||
case []interface{}:
|
||||
@@ -220,6 +229,27 @@ func convertYamlToJson(i interface{}) interface{} {
|
||||
return i
|
||||
}
|
||||
|
||||
func glob(root, pattern string) ([]string, error) {
|
||||
var matches []string
|
||||
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if matched, err := filepath.Match(pattern, filepath.Base(path)); err != nil {
|
||||
return err
|
||||
} else if matched {
|
||||
matches = append(matches, path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return matches, nil
|
||||
}
|
||||
func isYaml(filePath string) bool {
|
||||
return cautils.StringInSlice(YAML_PREFIX, filepath.Ext(filePath)) != cautils.ValueNotFound
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func TestListFiles(t *testing.T) {
|
||||
if len(errs) > 0 {
|
||||
t.Error(errs)
|
||||
}
|
||||
expected := 14
|
||||
expected := 12
|
||||
if len(files) != expected {
|
||||
t.Errorf("wrong number of files, expected: %d, found: %d", expected, len(files))
|
||||
}
|
||||
|
||||
@@ -20,9 +20,6 @@ func loadResourcesFromUrl(inputPatterns []string) ([]k8sinterface.IWorkload, err
|
||||
if len(errs) > 0 {
|
||||
cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error
|
||||
}
|
||||
if len(workloads) == 0 {
|
||||
return workloads, fmt.Errorf("empty list of workloads - no workloads valid workloads found")
|
||||
}
|
||||
return workloads, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user