mirror of
https://github.com/aquasecurity/kube-bench.git
synced 2024-12-22 14:48:07 +00:00
113 lines
3.5 KiB
Go
113 lines
3.5 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/aquasecurity/kube-bench/check"
|
|
"github.com/golang/glog"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
func init() {
|
|
RootCmd.AddCommand(runCmd)
|
|
runCmd.Flags().StringSliceP("targets", "s", []string{},
|
|
`Specify targets of the benchmark to run. These names need to match the filenames in the cfg/<version> directory.
|
|
For example, to run the tests specified in master.yaml and etcd.yaml, specify --targets=master,etcd
|
|
If no targets are specified, run tests from all files in the cfg/<version> directory.
|
|
`)
|
|
}
|
|
|
|
// runCmd represents the run command
|
|
var runCmd = &cobra.Command{
|
|
Use: "run",
|
|
Short: "Run tests",
|
|
Long: `Run tests. If no arguments are specified, runs tests from all files`,
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
targets, err := cmd.Flags().GetStringSlice("targets")
|
|
if err != nil {
|
|
exitWithError(fmt.Errorf("unable to get `targets` from command line :%v", err))
|
|
}
|
|
|
|
bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformInfo(), viper.GetViper())
|
|
if err != nil {
|
|
exitWithError(fmt.Errorf("unable to get benchmark version. error: %v", err))
|
|
}
|
|
|
|
glog.V(2).Infof("Checking targets %v for %v", targets, bv)
|
|
benchmarkVersionToTargetsMap, err := loadTargetMapping(viper.GetViper())
|
|
if err != nil {
|
|
exitWithError(fmt.Errorf("error loading targets: %v", err))
|
|
}
|
|
valid, err := validTargets(bv, targets, viper.GetViper())
|
|
if err != nil {
|
|
exitWithError(fmt.Errorf("error validating targets: %v", err))
|
|
}
|
|
if len(targets) > 0 && !valid {
|
|
exitWithError(fmt.Errorf(fmt.Sprintf(`The specified --targets "%s" are not configured for the CIS Benchmark %s\n Valid targets %v`, strings.Join(targets, ","), bv, benchmarkVersionToTargetsMap[bv])))
|
|
}
|
|
|
|
// Merge version-specific config if any.
|
|
path := filepath.Join(cfgDir, bv)
|
|
err = mergeConfig(path)
|
|
if err != nil {
|
|
exitWithError(fmt.Errorf("Error in mergeConfig: %v\n", err))
|
|
}
|
|
|
|
err = run(targets, bv)
|
|
if err != nil {
|
|
exitWithError(fmt.Errorf("Error in run: %v\n", err))
|
|
}
|
|
|
|
os.Exit(exitCodeSelection(controlsCollection))
|
|
},
|
|
}
|
|
|
|
func run(targets []string, benchmarkVersion string) (err error) {
|
|
yamlFiles, err := getTestYamlFiles(targets, benchmarkVersion)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
glog.V(3).Infof("Running tests from files %v\n", yamlFiles)
|
|
|
|
for _, yamlFile := range yamlFiles {
|
|
_, name := filepath.Split(yamlFile)
|
|
testType := check.NodeType(strings.Split(name, ".")[0])
|
|
runChecks(testType, yamlFile, detecetedKubeVersion)
|
|
}
|
|
|
|
writeOutput(controlsCollection)
|
|
return nil
|
|
}
|
|
|
|
func getTestYamlFiles(targets []string, benchmarkVersion string) (yamlFiles []string, err error) {
|
|
// Check that the specified targets have corresponding YAML files in the config directory
|
|
configFileDirectory := filepath.Join(cfgDir, benchmarkVersion)
|
|
for _, target := range targets {
|
|
filename := translate(target) + ".yaml"
|
|
file := filepath.Join(configFileDirectory, filename)
|
|
if _, err := os.Stat(file); err != nil {
|
|
return nil, fmt.Errorf("file %s not found for version %s", filename, benchmarkVersion)
|
|
}
|
|
yamlFiles = append(yamlFiles, file)
|
|
}
|
|
|
|
// If no targets were specified, we will run tests from all the files in the directory
|
|
if len(yamlFiles) == 0 {
|
|
yamlFiles, err = getYamlFilesFromDir(configFileDirectory)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return yamlFiles, err
|
|
}
|
|
|
|
func translate(target string) string {
|
|
return strings.Replace(strings.ToLower(target), "worker", "node", -1)
|
|
}
|