diff --git a/check/check.go b/check/check.go index a1b67f8..7ef0e50 100644 --- a/check/check.go +++ b/check/check.go @@ -71,13 +71,20 @@ type Check struct { TestInfo []string `json:"test_info"` State `json:"status"` ActualValue string `json:"actual_value"` + Scored bool `json:"scored"` } // Run executes the audit commands specified in a check and outputs // the results. func (c *Check) Run() { - // If check type is manual, force result to WARN. - if c.Type == "manual" { + + if c.Type == "skip" { + c.State = INFO + return + } + + // If check type is manual or the check is not scored, force result to WARN + if c.Type == "manual" || !c.Scored { c.State = WARN return } diff --git a/check/check_test.go b/check/check_test.go new file mode 100644 index 0000000..ab74656 --- /dev/null +++ b/check/check_test.go @@ -0,0 +1,30 @@ +package check + +import ( + "testing" +) + +func TestCheck_Run(t *testing.T) { + type TestCase struct { + check Check + Expected State + } + + testCases := []TestCase{ + {check: Check{Type: "manual"}, Expected: WARN}, + {check: Check{Type: "skip"}, Expected: INFO}, + {check: Check{Type: "", Scored: false}, Expected: WARN}, // Not scored checks with no type should be marked warn + {check: Check{Type: "", Scored: true}, Expected: WARN}, // If there are no tests in the check, warn + {check: Check{Type: "manual", Scored: false}, Expected: WARN}, + {check: Check{Type: "skip", Scored: false}, Expected: INFO}, + } + + for _, testCase := range testCases { + + testCase.check.Run() + + if testCase.check.State != testCase.Expected { + t.Errorf("test failed, expected %s, actual %s\n", testCase.Expected, testCase.check.State) + } + } +} diff --git a/check/controls.go b/check/controls.go index 640278f..f6d4ab9 100644 --- a/check/controls.go +++ b/check/controls.go @@ -37,6 +37,7 @@ type Group struct { Pass int `json:"pass"` Fail int `json:"fail"` Warn int `json:"warn"` + Info int `json:"info"` Text string `json:"desc"` Checks []*Check `json:"results"` } @@ -46,6 +47,7 @@ type Summary struct { Pass int `json:"total_pass"` Fail int `json:"total_fail"` Warn int `json:"total_warn"` + Info int `json:"total_info"` } // NewControls instantiates a new master Controls object. @@ -74,7 +76,7 @@ func NewControls(t NodeType, in []byte) (*Controls, error) { // RunGroup runs all checks in a group. func (controls *Controls) RunGroup(gids ...string) Summary { g := []*Group{} - controls.Summary.Pass, controls.Summary.Fail, controls.Summary.Warn = 0, 0, 0 + controls.Summary.Pass, controls.Summary.Fail, controls.Summary.Warn, controls.Info = 0, 0, 0, 0 // If no groupid is passed run all group checks. if len(gids) == 0 { @@ -105,7 +107,7 @@ func (controls *Controls) RunGroup(gids ...string) Summary { func (controls *Controls) RunChecks(ids ...string) Summary { g := []*Group{} m := make(map[string]*Group) - controls.Summary.Pass, controls.Summary.Fail, controls.Summary.Warn = 0, 0, 0 + controls.Summary.Pass, controls.Summary.Fail, controls.Summary.Warn, controls.Info = 0, 0, 0, 0 // If no groupid is passed run all group checks. if len(ids) == 0 { @@ -182,6 +184,8 @@ func summarize(controls *Controls, check *Check) { controls.Summary.Fail++ case WARN: controls.Summary.Warn++ + case INFO: + controls.Summary.Info++ } } @@ -193,5 +197,7 @@ func summarizeGroup(group *Group, check *Check) { group.Fail++ case WARN: group.Warn++ + case INFO: + group.Info++ } } diff --git a/cmd/common.go b/cmd/common.go index e038efe..b7e9622 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -108,7 +108,7 @@ func runChecks(nodetype check.NodeType) { } // if we successfully ran some tests and it's json format, ignore the warnings - if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0) && jsonFmt { + if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0 || summary.Info > 0) && jsonFmt { out, err := controls.JSON() if err != nil { exitWithError(fmt.Errorf("failed to output in JSON format: %v", err)) @@ -117,7 +117,7 @@ func runChecks(nodetype check.NodeType) { fmt.Println(string(out)) } else { // if we want to store in PostgreSQL, convert to JSON and save it - if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0) && pgSQL { + if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0 || summary.Info > 0) && pgSQL { out, err := controls.JSON() if err != nil { exitWithError(fmt.Errorf("failed to output in JSON format: %v", err)) @@ -178,8 +178,8 @@ func prettyPrint(r *check.Controls, summary check.Summary) { } colors[res].Printf("== Summary ==\n") - fmt.Printf("%d checks PASS\n%d checks FAIL\n%d checks WARN\n", - summary.Pass, summary.Fail, summary.Warn, + fmt.Printf("%d checks PASS\n%d checks FAIL\n%d checks WARN\n%d checks INFO\n", + summary.Pass, summary.Fail, summary.Warn, summary.Info, ) } }