github.com/khulnasoft-lab/kube-bench@v0.2.1-0.20240330183753-9df52345ae58/cmd/run.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/golang/glog" 10 "github.com/khulnasoft-lab/kube-bench/check" 11 "github.com/spf13/cobra" 12 "github.com/spf13/viper" 13 ) 14 15 func init() { 16 RootCmd.AddCommand(runCmd) 17 runCmd.Flags().StringSliceP("targets", "s", []string{}, 18 `Specify targets of the benchmark to run. These names need to match the filenames in the cfg/<version> directory. 19 For example, to run the tests specified in master.yaml and etcd.yaml, specify --targets=master,etcd 20 If no targets are specified, run tests from all files in the cfg/<version> directory. 21 `) 22 } 23 24 // runCmd represents the run command 25 var runCmd = &cobra.Command{ 26 Use: "run", 27 Short: "Run tests", 28 Long: `Run tests. If no arguments are specified, runs tests from all files`, 29 Run: func(cmd *cobra.Command, args []string) { 30 targets, err := cmd.Flags().GetStringSlice("targets") 31 if err != nil { 32 exitWithError(fmt.Errorf("unable to get `targets` from command line :%v", err)) 33 } 34 35 bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformInfo(), viper.GetViper()) 36 if err != nil { 37 exitWithError(fmt.Errorf("unable to get benchmark version. error: %v", err)) 38 } 39 40 glog.V(2).Infof("Checking targets %v for %v", targets, bv) 41 benchmarkVersionToTargetsMap, err := loadTargetMapping(viper.GetViper()) 42 if err != nil { 43 exitWithError(fmt.Errorf("error loading targets: %v", err)) 44 } 45 valid, err := validTargets(bv, targets, viper.GetViper()) 46 if err != nil { 47 exitWithError(fmt.Errorf("error validating targets: %v", err)) 48 } 49 if len(targets) > 0 && !valid { 50 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]))) 51 } 52 53 // Merge version-specific config if any. 54 path := filepath.Join(cfgDir, bv) 55 err = mergeConfig(path) 56 if err != nil { 57 exitWithError(fmt.Errorf("Error in mergeConfig: %v\n", err)) 58 } 59 60 err = run(targets, bv) 61 if err != nil { 62 exitWithError(fmt.Errorf("Error in run: %v\n", err)) 63 } 64 65 os.Exit(exitCodeSelection(controlsCollection)) 66 }, 67 } 68 69 func run(targets []string, benchmarkVersion string) (err error) { 70 yamlFiles, err := getTestYamlFiles(targets, benchmarkVersion) 71 if err != nil { 72 return err 73 } 74 75 glog.V(3).Infof("Running tests from files %v\n", yamlFiles) 76 77 for _, yamlFile := range yamlFiles { 78 _, name := filepath.Split(yamlFile) 79 testType := check.NodeType(strings.Split(name, ".")[0]) 80 runChecks(testType, yamlFile, detecetedKubeVersion) 81 } 82 83 writeOutput(controlsCollection) 84 return nil 85 } 86 87 func getTestYamlFiles(targets []string, benchmarkVersion string) (yamlFiles []string, err error) { 88 // Check that the specified targets have corresponding YAML files in the config directory 89 configFileDirectory := filepath.Join(cfgDir, benchmarkVersion) 90 for _, target := range targets { 91 filename := translate(target) + ".yaml" 92 file := filepath.Join(configFileDirectory, filename) 93 if _, err := os.Stat(file); err != nil { 94 return nil, fmt.Errorf("file %s not found for version %s", filename, benchmarkVersion) 95 } 96 yamlFiles = append(yamlFiles, file) 97 } 98 99 // If no targets were specified, we will run tests from all the files in the directory 100 if len(yamlFiles) == 0 { 101 yamlFiles, err = getYamlFilesFromDir(configFileDirectory) 102 if err != nil { 103 return nil, err 104 } 105 } 106 107 return yamlFiles, err 108 } 109 110 func translate(target string) string { 111 return strings.Replace(strings.ToLower(target), "worker", "node", -1) 112 }