Merge pull request #53 from armosec/dev

Supporting failure threshold
This commit is contained in:
Benyamin Hirschberg
2021-09-02 00:00:17 +03:00
committed by GitHub
4 changed files with 45 additions and 4 deletions

View File

@@ -34,6 +34,7 @@ If you wish to scan all namespaces in your cluster, remove the `--exclude-namesp
| --- | --- | --- | --- |
| `-e`/`--exclude-namespaces` | Scan all namespaces | Namespaces to exclude from scanning. Recommended to exclude `kube-system` and `kube-public` namespaces |
| `-s`/`--silent` | Display progress messages | Silent progress messages |
| `-t`/`--fail-threshold` | `0` (do not fail) | fail command (return exit code 1) if result bellow threshold| `0` -> `100` |
| `-f`/`--format` | `pretty-printer` | Output format | `pretty-printer`/`json`/`junit` |
| `-o`/`--output` | print to stdout | Save scan result in file |

View File

@@ -17,6 +17,7 @@ type ScanInfo struct {
ExcludedNamespaces string
InputPatterns []string
Silent bool
FailThreshold uint16
}
func (scanInfo *ScanInfo) Init() {

View File

@@ -67,8 +67,11 @@ var frameworkCmd = &cobra.Command{
}
scanInfo.Init()
cautils.SetSilentMode(scanInfo.Silent)
CliSetup()
err := CliSetup()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
return nil
},
}
@@ -86,11 +89,18 @@ func init() {
frameworkCmd.Flags().StringVarP(&scanInfo.Format, "format", "f", "pretty-printer", `Output format. supported formats: "pretty-printer"/"json"/"junit"`)
frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "", "Output file. print output to file and not stdout")
frameworkCmd.Flags().BoolVarP(&scanInfo.Silent, "silent", "s", false, "Silent progress messages")
frameworkCmd.Flags().Uint16VarP(&scanInfo.FailThreshold, "fail-threshold", "t", 0, "Failure threshold is the percent bellow which the command fails and returns exit code -1")
}
func CliSetup() error {
flag.Parse()
if 100 < scanInfo.FailThreshold {
fmt.Println("bad argument: out of range threshold")
os.Exit(1)
}
var k8s *k8sinterface.KubernetesApi
if scanInfo.ScanRunningCluster() {
k8s = k8sinterface.NewKubernetesApi()
@@ -114,7 +124,12 @@ func CliSetup() error {
reporterObj.ProcessRulesListenner()
}()
p := printer.NewPrinter(&reportResults, scanInfo.Format, scanInfo.Output)
p.ActionPrint()
score := p.ActionPrint()
adjustedFailThreshold := float32(scanInfo.FailThreshold) / 100
if score < adjustedFailThreshold {
return fmt.Errorf("Scan score is bellow threshold")
}
return nil
}

View File

@@ -43,8 +43,28 @@ func NewPrinter(opaSessionObj *chan *cautils.OPASessionObj, printerType, outputF
}
}
func (printer *Printer) ActionPrint() {
func calculatePostureScore(postureReport *opapolicy.PostureReport) float32 {
totalResources := 0
totalFailed := 0
for _, frameworkReport := range postureReport.FrameworkReports {
for _, controlReport := range frameworkReport.ControlReports {
for _, ruleReport := range controlReport.RuleReports {
for _, ruleResponses := range ruleReport.RuleResponses {
totalFailed += len(ruleResponses.AlertObject.K8SApiObjects)
totalFailed += len(ruleResponses.AlertObject.ExternalObjects)
}
}
totalResources += controlReport.GetNumberOfResources()
}
}
if totalResources == 0 {
return float32(0)
}
return (float32(totalResources) - float32(totalFailed)) / float32(totalResources)
}
func (printer *Printer) ActionPrint() float32 {
var score float32
for {
opaSessionObj := <-*printer.opaSessionObj
if printer.printerType == PrettyPrinter {
@@ -75,10 +95,14 @@ func (printer *Printer) ActionPrint() {
os.Exit(1)
}
score = calculatePostureScore(opaSessionObj.PostureReport)
if !k8sinterface.RunningIncluster {
break
}
}
return score
}
func (printer *Printer) SummarySetup(postureReport *opapolicy.PostureReport) {