diff --git a/cautils/getter/loadpolicy.go b/cautils/getter/loadpolicy.go index 9cde9a0f..7ae8c8f5 100644 --- a/cautils/getter/loadpolicy.go +++ b/cautils/getter/loadpolicy.go @@ -85,8 +85,19 @@ func (lp *LoadPolicy) GetFrameworks() ([]reporthandling.Framework, error) { } func (lp *LoadPolicy) ListFrameworks() ([]string, error) { - // TODO - Support - return []string{}, fmt.Errorf("loading frameworks list from file is not supported") + fwNames := []string{} + framework := &reporthandling.Framework{} + for _, f := range lp.filePaths { + file, err := os.ReadFile(f) + if err == nil { + if err := json.Unmarshal(file, framework); err == nil { + if !contains(fwNames, framework.Name) { + fwNames = append(fwNames, framework.Name) + } + } + } + } + return fwNames, nil } func (lp *LoadPolicy) ListControls(listType ListType) ([]string, error) { @@ -114,7 +125,7 @@ func (lp *LoadPolicy) GetControlsInputs(clusterName string) (map[string][]string return nil, err } - if err = json.Unmarshal(f, &accountConfig); err == nil { + if err = json.Unmarshal(f, &accountConfig.Settings.PostureControlInputs); err == nil { return accountConfig.Settings.PostureControlInputs, nil } return nil, err diff --git a/cautils/scaninfo.go b/cautils/scaninfo.go index 3175f1d9..a2c83ca9 100644 --- a/cautils/scaninfo.go +++ b/cautils/scaninfo.go @@ -1,7 +1,11 @@ package cautils import ( + "encoding/json" "fmt" + "io/ioutil" + "log" + "os" "path/filepath" "github.com/armosec/kubescape/cautils/getter" @@ -9,8 +13,10 @@ import ( ) const ( - ScanCluster string = "cluster" - ScanLocalFiles string = "yaml" + ScanCluster string = "cluster" + ScanLocalFiles string = "yaml" + localControlInputsFilename string = "controls-inputs.json" + localExceptionsFilename string = "exceptions.json" ) type BoolPtrFlag struct { @@ -52,6 +58,7 @@ type ScanInfo struct { ControlsInputs string // Load file with inputs for controls UseFrom []string // Load framework from local file (instead of download). Use when running offline UseDefault bool // Load framework from cached file (instead of download). Use when running offline + UseArtifactsFrom string // Load artifacts from local path. Use when running offline VerboseMode bool // Display all of the input resources and not only failed resources Format string // Format results (table, json, junit ...) Output string // Store results in an output file, Output file name @@ -78,7 +85,36 @@ type Getters struct { func (scanInfo *ScanInfo) Init() { scanInfo.setUseFrom() scanInfo.setOutputFile() + scanInfo.setUseArtifactsFrom() +} +func (scanInfo *ScanInfo) setUseArtifactsFrom() { + // UseArtifactsFrom must be a path without a filename + dir, file := filepath.Split(scanInfo.UseArtifactsFrom) + if dir == "" { + scanInfo.UseArtifactsFrom = file + } else { + scanInfo.UseArtifactsFrom = dir + } + // set frameworks files + files, err := ioutil.ReadDir(scanInfo.UseArtifactsFrom) + if err != nil { + log.Fatal(err) + } + framework := &reporthandling.Framework{} + for _, f := range files { + filePath := filepath.Join(scanInfo.UseArtifactsFrom, f.Name()) + file, err := os.ReadFile(filePath) + if err == nil { + if err := json.Unmarshal(file, framework); err == nil { + scanInfo.UseFrom = append(scanInfo.UseFrom, filepath.Join(scanInfo.UseArtifactsFrom, f.Name())) + } + } + } + // set config-inputs file + scanInfo.ControlsInputs = filepath.Join(scanInfo.UseArtifactsFrom, localControlInputsFilename) + // set exceptions + scanInfo.UseExceptions = filepath.Join(scanInfo.UseArtifactsFrom, localExceptionsFilename) } func (scanInfo *ScanInfo) setUseFrom() { diff --git a/clihandler/cmd/scan.go b/clihandler/cmd/scan.go index 00440d62..80f0e538 100644 --- a/clihandler/cmd/scan.go +++ b/clihandler/cmd/scan.go @@ -45,6 +45,7 @@ func init() { rootCmd.PersistentFlags().StringVarP(&scanInfo.ClusterName, "cluster", "", "", "Cluster name. Default will use the current-context") scanCmd.PersistentFlags().StringVar(&scanInfo.ControlsInputs, "controls-config", "", "Path to an controls-config obj. If not set will download controls-config from ARMO management portal") scanCmd.PersistentFlags().StringVar(&scanInfo.UseExceptions, "exceptions", "", "Path to an exceptions obj. If not set will download exceptions from ARMO management portal") + scanCmd.PersistentFlags().StringVar(&scanInfo.UseArtifactsFrom, "use-artifacts-from", "", "Load artifacts from local directory. If not used will download them") scanCmd.PersistentFlags().StringVarP(&scanInfo.ExcludedNamespaces, "exclude-namespaces", "e", "", "Namespaces to exclude from scanning. Recommended: kube-system,kube-public") scanCmd.PersistentFlags().Uint16VarP(&scanInfo.FailThreshold, "fail-threshold", "t", 100, "Failure threshold is the percent above which the command fails and returns exit code 1") scanCmd.PersistentFlags().StringVarP(&scanInfo.Format, "format", "f", "pretty-printer", `Output format. Supported formats: "pretty-printer"/"json"/"junit"/"prometheus"`)