Fix issue #16 about supporting verbosity.

pull/18/head
Abubakr-Sadik Nii Nai Davis 7 years ago
parent 06466d6573
commit bd53529387

@ -47,6 +47,13 @@ const (
FEDERATED NodeType = "federated" FEDERATED NodeType = "federated"
) )
func handleError(err error, context string) (errmsg string) {
if err != nil {
errmsg = fmt.Sprintf("%s, error: %s\n", context, err)
}
return
}
// Check contains information about a recommendation in the // Check contains information about a recommendation in the
// CIS Kubernetes 1.6+ document. // CIS Kubernetes 1.6+ document.
type Check struct { type Check struct {
@ -62,8 +69,9 @@ type Check struct {
// Run executes the audit commands specified in a check and outputs // Run executes the audit commands specified in a check and outputs
// the results. // the results.
func (c *Check) Run() { func (c *Check) Run(verbose bool) {
var out bytes.Buffer var out bytes.Buffer
var errmsgs string
// Check if command exists or exit with WARN. // Check if command exists or exit with WARN.
for _, cmd := range c.Commands { for _, cmd := range c.Commands {
@ -88,18 +96,24 @@ func (c *Check) Run() {
cs := c.Commands cs := c.Commands
// Initialize command pipeline // Initialize command pipeline
cs[0].Stderr = os.Stderr // cs[0].Stderr = os.Stderr
cs[n-1].Stdout = &out cs[n-1].Stdout = &out
i := 1 i := 1
var err error var err error
errmsgs = ""
for i < n { for i < n {
cs[i-1].Stdout, err = cs[i].StdinPipe() cs[i-1].Stdout, err = cs[i].StdinPipe()
if err != nil { errmsgs += handleError(
fmt.Fprintf(os.Stderr, "%s: %s\n", cs[i].Args, err) err,
} fmt.Sprintf("check.Run: Audit %s failed\nfailing command: %s",
c.Audit,
cs[i].Stderr = os.Stderr cs[i].Args,
),
)
// cs[i].Stderr = os.Stderr
i++ i++
} }
@ -107,9 +121,13 @@ func (c *Check) Run() {
i = 0 i = 0
for i < n { for i < n {
err := cs[i].Start() err := cs[i].Start()
if err != nil { errmsgs += handleError(
fmt.Fprintf(os.Stderr, "%s: %s\n", cs[i].Args, err) err,
} fmt.Sprintf("check.Run: Audit %s failed\nfailing command: %s",
c.Audit,
cs[i].Args,
),
)
i++ i++
} }
@ -117,9 +135,13 @@ func (c *Check) Run() {
i = 0 i = 0
for i < n { for i < n {
err := cs[i].Wait() err := cs[i].Wait()
if err != nil { errmsgs += handleError(
fmt.Fprintf(os.Stderr, "%s: %s\n", cs[i].Args, err) err,
} fmt.Sprintf("check.Run: Audit %s failed\nfailing command: %s",
c.Audit,
cs[i].Args,
),
)
if i < n-1 { if i < n-1 {
cs[i].Stdout.(io.Closer).Close() cs[i].Stdout.(io.Closer).Close()
@ -128,6 +150,10 @@ func (c *Check) Run() {
i++ i++
} }
if verbose {
fmt.Fprintf(os.Stderr, "%s\n", errmsgs)
}
res := c.Tests.execute(out.String()) res := c.Tests.execute(out.String())
if res { if res {
c.State = PASS c.State = PASS

@ -68,7 +68,7 @@ func NewControls(t NodeType, in []byte) (*Controls, error) {
} }
// RunGroup runs all checks in a group. // RunGroup runs all checks in a group.
func (controls *Controls) RunGroup(gids ...string) Summary { func (controls *Controls) RunGroup(verbose bool, gids ...string) Summary {
g := []*Group{} g := []*Group{}
controls.Summary.Pass, controls.Summary.Fail, controls.Summary.Warn = 0, 0, 0 controls.Summary.Pass, controls.Summary.Fail, controls.Summary.Warn = 0, 0, 0
@ -82,7 +82,7 @@ func (controls *Controls) RunGroup(gids ...string) Summary {
for _, gid := range gids { for _, gid := range gids {
if gid == group.ID { if gid == group.ID {
for _, check := range group.Checks { for _, check := range group.Checks {
check.Run() check.Run(verbose)
summarize(controls, check) summarize(controls, check)
} }
@ -96,7 +96,7 @@ func (controls *Controls) RunGroup(gids ...string) Summary {
} }
// RunChecks runs the checks with the supplied IDs. // RunChecks runs the checks with the supplied IDs.
func (controls *Controls) RunChecks(ids ...string) Summary { func (controls *Controls) RunChecks(verbose bool, ids ...string) Summary {
g := []*Group{} g := []*Group{}
m := make(map[string]*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 = 0, 0, 0
@ -110,7 +110,7 @@ func (controls *Controls) RunChecks(ids ...string) Summary {
for _, check := range group.Checks { for _, check := range group.Checks {
for _, id := range ids { for _, id := range ids {
if id == check.ID { if id == check.ID {
check.Run() check.Run(verbose)
summarize(controls, check) summarize(controls, check)
// Check if we have already added this checks group. // Check if we have already added this checks group.

@ -27,6 +27,8 @@ import (
) )
var ( var (
errmsgs string
kubeMasterBin = []string{"kube-apiserver", "kube-scheduler", "kube-controller-manager"} kubeMasterBin = []string{"kube-apiserver", "kube-scheduler", "kube-controller-manager"}
xMasterBin = []string{"etcd", "flanneld"} xMasterBin = []string{"etcd", "flanneld"}
kubeMasterConf = []string{} kubeMasterConf = []string{}
@ -51,6 +53,13 @@ var (
} }
) )
func handleError(err error, context string) (errmsg string) {
if err != nil {
errmsg = fmt.Sprintf("%s, error: %s\n", context, err)
}
return
}
func runChecks(t check.NodeType) { func runChecks(t check.NodeType) {
var summary check.Summary var summary check.Summary
var file string var file string
@ -85,18 +94,18 @@ func runChecks(t check.NodeType) {
if groupList != "" && checkList == "" { if groupList != "" && checkList == "" {
ids := cleanIDs(groupList) ids := cleanIDs(groupList)
summary = controls.RunGroup(ids...) summary = controls.RunGroup(verbose, ids...)
} else if checkList != "" && groupList == "" { } else if checkList != "" && groupList == "" {
ids := cleanIDs(checkList) ids := cleanIDs(checkList)
summary = controls.RunChecks(ids...) summary = controls.RunChecks(verbose, ids...)
} else if checkList != "" && groupList != "" { } else if checkList != "" && groupList != "" {
fmt.Fprintf(os.Stderr, "group option and check option can't be used together\n") fmt.Fprintf(os.Stderr, "group option and check option can't be used together\n")
os.Exit(1) os.Exit(1)
} else { } else {
summary = controls.RunGroup() summary = controls.RunGroup(verbose)
} }
// if we successfully ran some tests and it's json format, ignore the warnings // if we successfully ran some tests and it's json format, ignore the warnings
@ -129,6 +138,8 @@ func cleanIDs(list string) []string {
// Any check failing here is a show stopper. // Any check failing here is a show stopper.
func verifyNodeType(t check.NodeType) []string { func verifyNodeType(t check.NodeType) []string {
var w []string var w []string
// Always clear out error messages.
errmsgs = ""
// Set up and check for config files. // Set up and check for config files.
kubeConfDir = viper.Get("kubeConfDir").(string) kubeConfDir = viper.Get("kubeConfDir").(string)
@ -160,6 +171,10 @@ func verifyNodeType(t check.NodeType) []string {
w = append(w, verifyKubeVersion(kubeFederatedBin[0])...) w = append(w, verifyKubeVersion(kubeFederatedBin[0])...)
} }
if verbose {
fmt.Fprintf(os.Stderr, "%s\n", errmsgs)
}
return w return w
} }
@ -239,11 +254,11 @@ func verifyBin(binPath []string) []string {
// Run ps command // Run ps command
cmd := exec.Command("ps", "-C", binList, "-o", "cmd", "--no-headers") cmd := exec.Command("ps", "-C", binList, "-o", "cmd", "--no-headers")
cmd.Stderr = os.Stderr
out, err := cmd.Output() out, err := cmd.Output()
if err != nil { errmsgs += handleError(
fmt.Fprintf(os.Stderr, "%s: %s\n", cmd.Args, err) err,
} fmt.Sprintf("verifyBin: %s failed", binList),
)
// Actual verification // Actual verification
for _, b := range binPath { for _, b := range binPath {
@ -264,15 +279,15 @@ func verifyKubeVersion(b string) []string {
// Check version // Check version
cmd := exec.Command(b, "--version") cmd := exec.Command(b, "--version")
cmd.Stderr = os.Stderr
out, err := cmd.Output() out, err := cmd.Output()
if err != nil { errmsgs += handleError(
fmt.Fprintf(os.Stderr, "%s: %s\n", cmd.Args, err) err,
} fmt.Sprintf("verifyKubeVersion: failed"),
)
matched := strings.Contains(string(out), kubeVersion) matched := strings.Contains(string(out), kubeVersion)
if !matched { if !matched {
w = append(w, fmt.Sprintf("%s unsupported version.", b)) w = append(w, fmt.Sprintf("%s unsupported version\n", b))
} }
return w return w

@ -37,6 +37,8 @@ var (
kubeConfDir string kubeConfDir string
etcdConfDir string etcdConfDir string
flanneldConfDir string flanneldConfDir string
verbose bool
) )
// RootCmd represents the base command when called without any subcommands // RootCmd represents the base command when called without any subcommands
@ -72,6 +74,7 @@ func init() {
`Run all the checks under this comma-delimited list of groups. Example --group="1.1"`, `Run all the checks under this comma-delimited list of groups. Example --group="1.1"`,
) )
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./cfg/config.yaml)") RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./cfg/config.yaml)")
RootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output (default false)")
} }
// initConfig reads in config file and ENV variables if set. // initConfig reads in config file and ENV variables if set.

@ -14,7 +14,9 @@
package main package main
import "github.com/aquasecurity/kube-bench/cmd" import (
"github.com/aquasecurity/kube-bench/cmd"
)
func main() { func main() {
cmd.Execute() cmd.Execute()

Loading…
Cancel
Save