1
0
mirror of https://github.com/aquasecurity/kube-bench.git synced 2024-11-15 20:39:08 +00:00
kube-bench/cmd/run.go

113 lines
3.5 KiB
Go
Raw Normal View History

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)
}