1
0
mirror of https://github.com/aquasecurity/kube-bench.git synced 2025-01-19 04:01:07 +00:00

Merge branch 'master' into config-improvements

This commit is contained in:
Liz Rice 2019-05-27 13:10:40 +02:00 committed by GitHub
commit a8c69b57e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 3 deletions

View File

@ -62,7 +62,7 @@ func handleError(err error, context string) (errmsg string) {
type Check struct { type Check struct {
ID string `yaml:"id" json:"test_number"` ID string `yaml:"id" json:"test_number"`
Text string `json:"test_desc"` Text string `json:"test_desc"`
Audit string `json:"omit"` Audit string `json:"audit"`
Type string `json:"type"` Type string `json:"type"`
Commands []*exec.Cmd `json:"omit"` Commands []*exec.Cmd `json:"omit"`
Tests *tests `json:"omit"` Tests *tests `json:"omit"`
@ -72,6 +72,7 @@ type Check struct {
State `json:"status"` State `json:"status"`
ActualValue string `json:"actual_value"` ActualValue string `json:"actual_value"`
Scored bool `json:"scored"` Scored bool `json:"scored"`
ExpectedResult string `json:"expected_result"`
} }
// Runner wraps the basic Run method. // Runner wraps the basic Run method.
@ -188,6 +189,7 @@ func (c *Check) run() State {
finalOutput := c.Tests.execute(out.String()) finalOutput := c.Tests.execute(out.String())
if finalOutput != nil { if finalOutput != nil {
c.ActualValue = finalOutput.actualResult c.ActualValue = finalOutput.actualResult
c.ExpectedResult = finalOutput.ExpectedResult
if finalOutput.testResult { if finalOutput.testResult {
c.State = PASS c.State = PASS
} else { } else {

View File

@ -58,6 +58,7 @@ type compare struct {
type testOutput struct { type testOutput struct {
testResult bool testResult bool
actualResult string actualResult string
ExpectedResult string
} }
func failTestItem(s string) *testOutput { func failTestItem(s string) *testOutput {
@ -135,9 +136,10 @@ func (t *testItem) execute(s string) *testOutput {
} }
} }
result.actualResult = strings.ToLower(flagVal) expectedResultPattern := ""
switch t.Compare.Op { switch t.Compare.Op {
case "eq": case "eq":
expectedResultPattern = "'%s' is equal to '%s'"
value := strings.ToLower(flagVal) value := strings.ToLower(flagVal)
// Do case insensitive comparaison for booleans ... // Do case insensitive comparaison for booleans ...
if value == "false" || value == "true" { if value == "false" || value == "true" {
@ -147,6 +149,7 @@ func (t *testItem) execute(s string) *testOutput {
} }
case "noteq": case "noteq":
expectedResultPattern = "'%s' is not equal to '%s'"
value := strings.ToLower(flagVal) value := strings.ToLower(flagVal)
// Do case insensitive comparaison for booleans ... // Do case insensitive comparaison for booleans ...
if value == "false" || value == "true" { if value == "false" || value == "true" {
@ -156,32 +159,41 @@ func (t *testItem) execute(s string) *testOutput {
} }
case "gt": case "gt":
expectedResultPattern = "%s is greater then %s"
a, b := toNumeric(flagVal, t.Compare.Value) a, b := toNumeric(flagVal, t.Compare.Value)
result.testResult = a > b result.testResult = a > b
case "gte": case "gte":
expectedResultPattern = "%s is greater or equal to %s"
a, b := toNumeric(flagVal, t.Compare.Value) a, b := toNumeric(flagVal, t.Compare.Value)
result.testResult = a >= b result.testResult = a >= b
case "lt": case "lt":
expectedResultPattern = "%s is lower then %s"
a, b := toNumeric(flagVal, t.Compare.Value) a, b := toNumeric(flagVal, t.Compare.Value)
result.testResult = a < b result.testResult = a < b
case "lte": case "lte":
expectedResultPattern = "%s is lower or equal to %s"
a, b := toNumeric(flagVal, t.Compare.Value) a, b := toNumeric(flagVal, t.Compare.Value)
result.testResult = a <= b result.testResult = a <= b
case "has": case "has":
expectedResultPattern = "'%s' has '%s'"
result.testResult = strings.Contains(flagVal, t.Compare.Value) result.testResult = strings.Contains(flagVal, t.Compare.Value)
case "nothave": case "nothave":
expectedResultPattern = " '%s' not have '%s'"
result.testResult = !strings.Contains(flagVal, t.Compare.Value) result.testResult = !strings.Contains(flagVal, t.Compare.Value)
} }
result.ExpectedResult = fmt.Sprintf(expectedResultPattern, t.Flag, t.Compare.Value)
} else { } else {
result.ExpectedResult = fmt.Sprintf("'%s' is present", t.Flag)
result.testResult = isset result.testResult = isset
} }
} else { } else {
result.ExpectedResult = fmt.Sprintf("'%s' is not present", t.Flag)
notset := !match notset := !match
result.testResult = notset result.testResult = notset
} }
@ -207,8 +219,11 @@ func (ts *tests) execute(s string) *testOutput {
return finalOutput return finalOutput
} }
expectedResultArr := make([]string, len(res))
for i, t := range ts.TestItems { for i, t := range ts.TestItems {
res[i] = *(t.execute(s)) res[i] = *(t.execute(s))
expectedResultArr[i] = res[i].ExpectedResult
} }
var result bool var result bool
@ -222,16 +237,25 @@ func (ts *tests) execute(s string) *testOutput {
for i := range res { for i := range res {
result = result && res[i].testResult result = result && res[i].testResult
} }
// Generate an AND expected result
finalOutput.ExpectedResult = strings.Join(expectedResultArr, " AND ")
case or: case or:
result = false result = false
for i := range res { for i := range res {
result = result || res[i].testResult result = result || res[i].testResult
} }
// Generate an OR expected result
finalOutput.ExpectedResult = strings.Join(expectedResultArr, " OR ")
} }
finalOutput.testResult = result finalOutput.testResult = result
finalOutput.actualResult = res[0].actualResult finalOutput.actualResult = res[0].actualResult
if finalOutput.actualResult == "" {
finalOutput.actualResult = s
}
return finalOutput return finalOutput
} }

View File

@ -19,6 +19,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"github.com/aquasecurity/kube-bench/check" "github.com/aquasecurity/kube-bench/check"
"github.com/golang/glog" "github.com/golang/glog"
@ -142,6 +143,10 @@ func prettyPrint(r *check.Controls, summary check.Summary) {
colorPrint(check.INFO, fmt.Sprintf("%s %s\n", g.ID, g.Text)) colorPrint(check.INFO, fmt.Sprintf("%s %s\n", g.ID, g.Text))
for _, c := range g.Checks { for _, c := range g.Checks {
colorPrint(c.State, fmt.Sprintf("%s %s\n", c.ID, c.Text)) colorPrint(c.State, fmt.Sprintf("%s %s\n", c.ID, c.Text))
if includeTestOutput && c.State == check.FAIL && len(c.ActualValue) > 0 {
printRawOutput(c.ActualValue)
}
} }
} }
@ -240,3 +245,9 @@ func isMaster() bool {
} }
return true return true
} }
func printRawOutput(output string) {
for _, row := range strings.Split(output, "\n") {
fmt.Println(fmt.Sprintf("\t %s", row))
}
}

View File

@ -47,6 +47,7 @@ var (
noSummary bool noSummary bool
noRemediations bool noRemediations bool
filterOpts FilterOpts filterOpts FilterOpts
includeTestOutput bool
) )
// RootCmd represents the base command when called without any subcommands // RootCmd represents the base command when called without any subcommands
@ -87,6 +88,7 @@ func init() {
RootCmd.PersistentFlags().BoolVar(&pgSQL, "pgsql", false, "Save the results to PostgreSQL") RootCmd.PersistentFlags().BoolVar(&pgSQL, "pgsql", false, "Save the results to PostgreSQL")
RootCmd.PersistentFlags().BoolVar(&filterOpts.Scored, "scored", true, "Run the scored CIS checks") RootCmd.PersistentFlags().BoolVar(&filterOpts.Scored, "scored", true, "Run the scored CIS checks")
RootCmd.PersistentFlags().BoolVar(&filterOpts.Unscored, "unscored", true, "Run the unscored CIS checks") RootCmd.PersistentFlags().BoolVar(&filterOpts.Unscored, "unscored", true, "Run the unscored CIS checks")
RootCmd.PersistentFlags().BoolVar(&includeTestOutput, "include-test-output", false, "Prints the actual result when test fails")
RootCmd.PersistentFlags().StringVarP( RootCmd.PersistentFlags().StringVarP(
&filterOpts.CheckList, &filterOpts.CheckList,