Repository: aquasecurity/kube-bench
Pull request #822 (2021-02-22 09:23:37)

Add logging
Some old logging was a bit misleading and lacking in information so I changed some and mostly add more logs, 
Also now the checks logs has the check ID so it much more clear what log belong to which test. 
In the image you can see how a test log looks like now:

![image](https://user-images.githubusercontent.com/12915002/108687731-bcec0900-74ff-11eb-88c2-45364ab46d66.png)

And this is before:
![image](https://user-images.githubusercontent.com/12915002/108688240-5c110080-7500-11eb-9aa8-308dd7f19ab5.png)


codecov[bot]: # [Codecov](https://codecov.io/gh/aquasecurity/kube-bench/pull/822?src=pr&el=h1) Report
> Merging [#822](https://codecov.io/gh/aquasecurity/kube-bench/pull/822?src=pr&el=desc) (89b12bc) into [main](https://codecov.io/gh/aquasecurity/kube-bench/commit/ade7fb0759f8796f55a464adc06cc15804c71d80?el=desc) (ade7fb0) will **increase** coverage by `0.39%`.
> The diff coverage is `91.66%`.

[![Impacted file tree graph](https://codecov.io/gh/aquasecurity/kube-bench/pull/822/graphs/tree.svg?width=650&height=150&src=pr&token=MVaDEmdgi9)](https://codecov.io/gh/aquasecurity/kube-bench/pull/822?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##             main     #822      +/-   ##
==========================================
+ Coverage   66.58%   66.98%   +0.39%     
==========================================
  Files          14       14              
  Lines        1257     1275      +18     
==========================================
+ Hits          837      854      +17     
- Misses        364      365       +1     
  Partials       56       56              
```


| [Impacted Files](https://codecov.io/gh/aquasecurity/kube-bench/pull/822?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [check/check.go](https://codecov.io/gh/aquasecurity/kube-bench/pull/822/diff?src=pr&el=tree#diff-Y2hlY2svY2hlY2suZ28=) | `81.35% <83.33%> (+0.44%)` | :arrow_up: |
| [check/test.go](https://codecov.io/gh/aquasecurity/kube-bench/pull/822/diff?src=pr&el=tree#diff-Y2hlY2svdGVzdC5nbw==) | `91.90% <100.00%> (+0.40%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/aquasecurity/kube-bench/pull/822?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/aquasecurity/kube-bench/pull/822?src=pr&el=footer). Last update [ade7fb0...f8a07be](https://codecov.io/gh/aquasecurity/kube-bench/pull/822?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index cbd93dc..7609d6e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,3 +1,4 @@
+---
 name: Build
 on:
   push:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 33cf5f6..77ccdeb 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,3 +1,4 @@
+---
 name: Release
 on:
   push:
diff --git a/Dockerfile b/Dockerfile
index c939155..6e02882 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.15 AS build
+FROM golang:1.16 AS build
 WORKDIR /go/src/github.com/aquasecurity/kube-bench/
 COPY go.mod go.sum ./
 COPY main.go .
@@ -10,7 +10,7 @@ ARG GOOS=linux
 ARG GOARCH=amd64
 RUN GO111MODULE=on CGO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH go build -a -ldflags "-X github.com/aquasecurity/kube-bench/cmd.KubeBenchVersion=${KUBEBENCH_VERSION} -w" -o /go/bin/kube-bench
 
-FROM alpine:3.12 AS run
+FROM alpine:3.13 AS run
 WORKDIR /opt/kube-bench/
 # add GNU ps for -C, -o cmd, and --no-headers support
 # https://github.com/aquasecurity/kube-bench/issues/109
diff --git a/README.md b/README.md
index 83416bb..135e592 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,8 @@ Table of Contents
   - [CIS Kubernetes Benchmark support](#cis-kubernetes-benchmark-support)
   - [Installation](#installation)
   - [Running kube-bench](#running-kube-bench)
+    - [Specifying the benchmark or Kubernetes version](#specifying-the-benchmark-or-kubernetes-version)
+    - [Specifying Benchmark sections](#specifying-benchmark-sections)
     - [Running inside a container](#running-inside-a-container)
     - [Running in a Kubernetes cluster](#running-in-a-kubernetes-cluster)
     - [Running in an AKS cluster](#running-in-an-aks-cluster)
@@ -76,6 +78,8 @@ kube-bench supports the tests for Kubernetes as defined in the [CIS Kubernetes B
 
 By default, kube-bench will determine the test set to run based on the Kubernetes version running on the machine, but please note that kube-bench does not automatically detect OpenShift and GKE - see the section below on [Running kube-bench](https://github.com/aquasecurity/kube-bench#running-kube-bench).
 
+The test files for the various versions of CIS Benchmark can be found in directories
+with same name as the CIS Benchmark versions under `cfg/`, for example `cfg/cis-1.5`.
 ## Installation
 
 You can choose to
@@ -88,45 +92,48 @@ You can choose to
 
 If you run kube-bench directly from the command line you may need to be root / sudo to have access to all the config files.
 
-kube-bench automatically selects which `controls` to use based on the detected
-node type and the version of Kubernetes a cluster is running. This behavior
-can be overridden by specifying the `master` or `node` subcommand and the
-`--version` flag on the command line.
+By default kube-bench attempts to auto-detect the running version of Kubernetes, and map this to the corresponding CIS Benchmark version. For example, Kubernetes version 1.15 is mapped to CIS Benchmark version `cis-1.15` which is the benchmark version valid for Kubernetes 1.15.
 
+kube-bench also attempts to identify the components running on the node, and uses this to determine which tests to run (for example, only running the master node tests if the node is running an API server). 
 
-The Kubernetes version can also be set with the `KUBE_BENCH_VERSION` environment variable.
-The value of `--version` takes precedence over the value of `KUBE_BENCH_VERSION`.
+### Specifying the benchmark or Kubernetes version
 
-For example, run kube-bench against a master with version auto-detection:
+kube-bench uses the Kubernetes API, or access to the `kubectl` or `kubelet` executables to try to determine the Kubernetes version, and hence which benchmark to run. If you wish to override this, or if none of these methods are available, you can specify either the Kubernetes version or CIS Benchmark as a command line parameter.  
 
-```
-kube-bench master
-```
+You can specify a particular version of Kubernetes by setting the `--version` flag or with the `KUBE_BENCH_VERSION` environment variable. The value of `--version` takes precedence over the value of `KUBE_BENCH_VERSION`.
 
-Or run kube-bench against a worker node using the tests for Kubernetes version 1.13:
+For example, run kube-bench using the tests for Kubernetes version 1.13:
 
 ```
-kube-bench node --version 1.13
+kube-bench --version 1.13
 ```
 
-`kube-bench` will map the `--version` to the corresponding CIS Benchmark version as indicated by the mapping table above. For example, if you specify `--version 1.15`, this is mapped to CIS Benchmark version `cis-1.15`.
 
-Alternatively, you can specify `--benchmark` to run a specific CIS Benchmark version:
+You can specify `--benchmark` to run a specific CIS Benchmark version:
 
 ```
-kube-bench node --benchmark cis-1.5
+kube-bench --benchmark cis-1.5
 ```
 
-If you want to target specific CIS Benchmark `target` (i.e master, node, etcd, etc...)
+**Note:**  It is an error to specify both `--version` and `--benchmark` flags together
+
+### Specifying Benchmark sections
+
+If you want to run specific CIS Benchmark sections (i.e master, node, etcd, etc...)
 you can use the `run --targets` subcommand.
+
 ```
-kube-bench --benchmark cis-1.5 run --targets master,node
+kube-bench run --targets master,node
 ```
+
 or
+
 ```
-kube-bench --benchmark cis-1.5 run --targets master,node,etcd,policies
+kube-bench run --targets master,node,etcd,policies
 ```
 
+Check the contents of the benchmark directory under `cfg` to see which targets are available for that benchmark. Each file except `config.yaml` represents a target (also known as a `control` in other parts of this documentation). 
+
 The following table shows the valid targets based on the CIS Benchmark version.
 | CIS Benchmark | Targets |
 |---|---|
@@ -135,40 +142,31 @@ The following table shows the valid targets based on the CIS Benchmark version.
 | gke-1.0| master, controlplane, node, etcd, policies, managedservices |
 | eks-1.0| controlplane, node, policies, managedservices |
 
-If no targets are specified, `kube-bench` will determine the appropriate targets based on the CIS Benchmark version.
-
-`controls` for the various versions of CIS Benchmark can be found in directories
-with same name as the CIS Benchmark versions under `cfg/`, for example `cfg/cis-1.5`.
-
-**Note:**  **`It is an error to specify both --version and --benchmark flags together`**
-
+If no targets are specified, `kube-bench` will determine the appropriate targets based on the CIS Benchmark version and the components detected on the node. The detection is done by verifying which components are running, as defined in the config files (see [Configuration](#configuration).
 ### Running inside a container
 
 You can avoid installing kube-bench on the host by running it inside a container using the host PID namespace and mounting the `/etc` and `/var` directories where the configuration and other files are located on the host so that kube-bench can check their existence and permissions.
 
 ```
-docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t aquasec/kube-bench:latest [master|node] --version 1.13
+docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t aquasec/kube-bench:latest --version 1.13
 ```
 
 > Note: the tests require either the kubelet or kubectl binary in the path in order to auto-detect the Kubernetes version. You can pass `-v $(which kubectl):/usr/local/mount-from-host/bin/kubectl` to resolve this. You will also need to pass in kubeconfig credentials. For example:
 
 ```
-docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config -t aquasec/kube-bench:latest [master|node]
+docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config -t aquasec/kube-bench:latest 
 ```
 
 You can use your own configs by mounting them over the default ones in `/opt/kube-bench/cfg/`
 
 ```
-docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t -v path/to/my-config.yaml:/opt/kube-bench/cfg/config.yam -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config aquasec/kube-bench:latest [master|node]
+docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t -v path/to/my-config.yaml:/opt/kube-bench/cfg/config.yam -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config aquasec/kube-bench:latest
 ```
 
 ### Running in a Kubernetes cluster
 
 You can run kube-bench inside a pod, but it will need access to the host's PID namespace in order to check the running processes, as well as access to some directories on the host where config files and other files are stored.
 
-Master nodes are automatically detected by kube-bench and will run master checks when possible.
-The detection is done by verifying that mandatory components for master, as defined in the config files, are running (see [Configuration](#configuration)).
-
 The supplied `job.yaml` file can be applied to run the tests as a job. For example:
 
 ```bash
@@ -191,18 +189,14 @@ kubectl logs kube-bench-j76s9
 ...
 ```
 
-You can still force to run specific master or node checks using respectively `job-master.yaml` and `job-node.yaml`.
-
-To run the tests on the master node, the pod needs to be scheduled on that node. This involves setting a nodeSelector and tolerations in the pod spec.
+To run tests on the master node, the pod needs to be scheduled on that node. This involves setting a nodeSelector and tolerations in the pod spec.
 
 The default labels applied to master nodes has changed since Kubernetes 1.11, so if you are using an older version you may need to modify the nodeSelector and tolerations to run the job on the master node.
-
-
 ### Running in an AKS cluster
 
 1. Create an AKS cluster(e.g. 1.13.7) with RBAC enabled, otherwise there would be 4 failures
 
-1. Use the [kubectl-enter plugin] (https://github.com/kvaps/kubectl-enter) to shell into a node
+1. Use the [kubectl-enter plugin](https://github.com/kvaps/kubectl-enter) to shell into a node
 `
 kubectl-enter {node-name}
 `
@@ -212,7 +206,7 @@ could open nsg 22 port and assign a public ip for one agent node (only for testi
 1. Run CIS benchmark to view results:
 ```
 docker run --rm -v `pwd`:/host aquasec/kube-bench:latest install
-./kube-bench node
+./kube-bench 
 ```
 kube-bench cannot be run on AKS master nodes
 
@@ -282,7 +276,7 @@ This command copies the kube-bench binary and configuration files to your host f
 docker run --rm -v `pwd`:/host aquasec/kube-bench:latest install
 ```
 
-You can then run `./kube-bench [master|node]`.
+You can then run `./kube-bench`.
 
 ### Download and Install binaries
 
@@ -318,12 +312,12 @@ tar -xvf kube-bench_0.3.1_linux_amd64.tar.gz
 
 You can then run kube-bench directly:
 ```
-kube-bench [master|node]
+kube-bench
 ```
 
 If you manually downloaded the kube-bench binary (using curl command above), you have to specify the location of configuration directory and file. For example:
 ```
-./kube-bench --config-dir `pwd`/cfg --config `pwd`/cfg/config.yaml [master|node]
+./kube-bench --config-dir `pwd`/cfg --config `pwd`/cfg/config.yaml 
 ```
 
 See previous section on [Running kube-bench](#running-kube-bench) for further details on using the kube-bench binary.
diff --git a/cfg/cis-1.5/policies.yaml b/cfg/cis-1.5/policies.yaml
index ace5282..5ba7090 100644
--- a/cfg/cis-1.5/policies.yaml
+++ b/cfg/cis-1.5/policies.yaml
@@ -131,7 +131,7 @@ groups:
         text: "Minimize the admission of containers with capabilities assigned (Not Scored)"
         type: "manual"
         remediation: |
-          Review the use of capabilites in applications runnning on your cluster. Where a namespace
+          Review the use of capabilites in applications running on your cluster. Where a namespace
           contains applicaions which do not require any Linux capabities to operate consider adding
           a PSP which forbids the admission of containers which do not drop all capabilities.
         scored: false
diff --git a/cfg/cis-1.6/policies.yaml b/cfg/cis-1.6/policies.yaml
index 14b5ffa..980762a 100644
--- a/cfg/cis-1.6/policies.yaml
+++ b/cfg/cis-1.6/policies.yaml
@@ -131,7 +131,7 @@ groups:
         text: "Minimize the admission of containers with capabilities assigned (Manual)"
         type: "manual"
         remediation: |
-          Review the use of capabilites in applications runnning on your cluster. Where a namespace
+          Review the use of capabilites in applications running on your cluster. Where a namespace
           contains applicaions which do not require any Linux capabities to operate consider adding
           a PSP which forbids the admission of containers which do not drop all capabilities.
         scored: false
diff --git a/cfg/gke-1.0/policies.yaml b/cfg/gke-1.0/policies.yaml
index 2f26fbd..54ce12b 100644
--- a/cfg/gke-1.0/policies.yaml
+++ b/cfg/gke-1.0/policies.yaml
@@ -131,7 +131,7 @@ groups:
         text: "Minimize the admission of containers with capabilities assigned (Scored) "
         type: "manual"
         remediation: |
-          Review the use of capabilites in applications runnning on your cluster. Where a namespace
+          Review the use of capabilites in applications running on your cluster. Where a namespace
           contains applications which do not require any Linux capabities to operate consider adding
           a PSP which forbids the admission of containers which do not drop all capabilities.
         scored: true
diff --git a/check/check.go b/check/check.go
index da621d7..6e91f23 100644
--- a/check/check.go
+++ b/check/check.go
@@ -107,12 +107,14 @@ func (r *defaultRunner) Run(c *Check) State {
 // Run executes the audit commands specified in a check and outputs
 // the results.
 func (c *Check) run() State {
+	glog.V(3).Infof("-----   Running check %v   -----", c.ID)
 	// Since this is an Scored check
 	// without tests return a 'WARN' to alert
 	// the user that this check needs attention
 	if c.Scored && strings.TrimSpace(c.Type) == "" && c.Tests == nil {
 		c.Reason = "There are no tests"
 		c.State = WARN
+		glog.V(3).Info(c.Reason)
 		return c.State
 	}
 
@@ -120,6 +122,7 @@ func (c *Check) run() State {
 	if c.Type == SKIP {
 		c.Reason = "Test marked as skip"
 		c.State = INFO
+		glog.V(3).Info(c.Reason)
 		return c.State
 	}
 
@@ -127,6 +130,7 @@ func (c *Check) run() State {
 	if c.Type == MANUAL {
 		c.Reason = "Test marked as a manual test"
 		c.State = WARN
+		glog.V(3).Info(c.Reason)
 		return c.State
 	}
 
@@ -138,6 +142,7 @@ func (c *Check) run() State {
 		} else {
 			c.State = WARN
 		}
+		glog.V(3).Info(c.Reason)
 		return c.State
 	}
 
@@ -172,12 +177,13 @@ func (c *Check) run() State {
 		} else {
 			c.State = WARN
 		}
+		glog.V(3).Info(c.Reason)
 	}
 
 	if finalOutput != nil {
-		glog.V(3).Infof("Check.ID: %s Command: %q TestResult: %t State: %q \n", c.ID, lastCommand, finalOutput.testResult, c.State)
+		glog.V(3).Infof("Command: %q TestResult: %t State: %q \n", lastCommand, finalOutput.testResult, c.State)
 	} else {
-		glog.V(3).Infof("Check.ID: %s Command: %q TestResult: <<EMPTY>> \n", c.ID, lastCommand)
+		glog.V(3).Infof("Command: %q TestResult: <<EMPTY>> \n", lastCommand)
 	}
 
 	if c.Reason != "" {
@@ -212,7 +218,7 @@ func (c *Check) execute() (finalOutput *testOutput, err error) {
 	res := make([]testOutput, len(ts.TestItems))
 	expectedResultArr := make([]string, len(res))
 
-	glog.V(3).Infof("%d tests", len(ts.TestItems))
+	glog.V(3).Infof("Running %d test_items", len(ts.TestItems))
 	for i, t := range ts.TestItems {
 
 		t.isMultipleOutput = c.IsMultiple
@@ -236,6 +242,7 @@ func (c *Check) execute() (finalOutput *testOutput, err error) {
 			t.auditUsed = AuditEnv
 			result = *(t.execute(c.AuditEnvOutput))
 		}
+		glog.V(2).Infof("Used %s", t.auditUsed)
 		res[i] = result
 		expectedResultArr[i] = res[i].ExpectedResult
 	}
@@ -289,8 +296,8 @@ func runAudit(audit string) (output string, err error) {
 	if err != nil {
 		err = fmt.Errorf("failed to run: %q, output: %q, error: %s", audit, output, err)
 	} else {
-		glog.V(3).Infof("Command %q\n - Output:\n %q", audit, output)
-
+		glog.V(3).Infof("Command: %q", audit)
+		glog.V(3).Infof("Output:\n %q", output)
 	}
 	return output, err
 }
diff --git a/cmd/kubernetes_version.go b/cmd/kubernetes_version.go
index de5cb9e..3f3f7e9 100644
--- a/cmd/kubernetes_version.go
+++ b/cmd/kubernetes_version.go
@@ -33,24 +33,28 @@ func (k *KubeVersion) BaseVersion() string {
 }
 
 func getKubeVersionFromRESTAPI() (*KubeVersion, error) {
+	glog.V(2).Info("Try to get version from Rest API")
 	k8sVersionURL := getKubernetesURL()
 	serviceaccount := "/var/run/secrets/kubernetes.io/serviceaccount"
 	cacertfile := fmt.Sprintf("%s/ca.crt", serviceaccount)
 	tokenfile := fmt.Sprintf("%s/token", serviceaccount)
 
-	tlsCert, err := loadCertficate(cacertfile)
+	tlsCert, err := loadCertificate(cacertfile)
 	if err != nil {
+		glog.V(2).Infof("Failed loading certificate Error: %s", err)
 		return nil, err
 	}
 
 	tb, err := ioutil.ReadFile(tokenfile)
 	if err != nil {
+		glog.V(2).Infof("Failed reading token file Error: %s", err)
 		return nil, err
 	}
 	token := strings.TrimSpace(string(tb))
 
 	data, err := getWebDataWithRetry(k8sVersionURL, token, tlsCert)
 	if err != nil {
+		glog.V(2).Infof("Failed to get data Error: %s", err)
 		return nil, err
 	}
 
@@ -143,7 +147,7 @@ func getWebData(srvURL, token string, cacert *tls.Certificate) ([]byte, error) {
 	return ioutil.ReadAll(resp.Body)
 }
 
-func loadCertficate(certFile string) (*tls.Certificate, error) {
+func loadCertificate(certFile string) (*tls.Certificate, error) {
 	cacert, err := ioutil.ReadFile(certFile)
 	if err != nil {
 		return nil, err
diff --git a/cmd/master.go b/cmd/master.go
index 5b345e9..e8db8e3 100644
--- a/cmd/master.go
+++ b/cmd/master.go
@@ -37,6 +37,7 @@ var masterCmd = &cobra.Command{
 		runChecks(check.MASTER, filename)
 		writeOutput(controlsCollection)
 	},
+	Deprecated: "this command will be retired soon. Please use the `run` command with `--targets=master` instead.",
 }
 
 func init() {
diff --git a/cmd/node.go b/cmd/node.go
index 707bff6..4eb13db 100644
--- a/cmd/node.go
+++ b/cmd/node.go
@@ -37,6 +37,7 @@ var nodeCmd = &cobra.Command{
 		runChecks(check.NODE, filename)
 		writeOutput(controlsCollection)
 	},
+	Deprecated: "this command will be retired soon. Please use the `run` command with `--targets=node` instead.",
 }
 
 func init() {
diff --git a/cmd/run.go b/cmd/run.go
index 20199c5..16b6641 100644
--- a/cmd/run.go
+++ b/cmd/run.go
@@ -52,7 +52,10 @@ var runCmd = &cobra.Command{
 
 		// Merge version-specific config if any.
 		path := filepath.Join(cfgDir, bv)
-		mergeConfig(path)
+		err = mergeConfig(path)
+		if err != nil {
+			fmt.Printf("Error in mergeConfig: %v\n", err)
+		}
 
 		err = run(targets, bv)
 		if err != nil {
diff --git a/cmd/util.go b/cmd/util.go
index 91476d9..e143a12 100644
--- a/cmd/util.go
+++ b/cmd/util.go
@@ -291,17 +291,22 @@ func getKubeVersion() (*KubeVersion, error) {
 	_, err := exec.LookPath("kubectl")
 
 	if err != nil {
+		glog.V(3).Infof("Error locating kubectl: %s", err)
 		_, err = exec.LookPath("kubelet")
 		if err != nil {
+			glog.V(3).Infof("Error locating kubelet: %s", err)
 			// Search for the kubelet binary all over the filesystem and run the first match to get the kubernetes version
 			cmd := exec.Command("/bin/sh", "-c", "`find / -type f -executable -name kubelet 2>/dev/null | grep -m1 .` --version")
 			out, err := cmd.CombinedOutput()
 			if err == nil {
+				glog.V(3).Infof("Found kubelet and query kubernetes version is: %s", string(out))
 				return getVersionFromKubeletOutput(string(out)), nil
 			}
 
 			glog.Warning(missingKubectlKubeletMessage)
-			return nil, fmt.Errorf("unable to find the programs kubectl or kubelet in the PATH")
+			glog.V(1).Info("unable to find the programs kubectl or kubelet in the PATH")
+			glog.V(1).Infof("Cant detect version, assuming default %s", defaultKubeVersion)
+			return &KubeVersion{baseVersion: defaultKubeVersion}, nil 
 		}
 		return getKubeVersionFromKubelet(), nil
 	}
@@ -313,6 +318,7 @@ func getKubeVersionFromKubectl() *KubeVersion {
 	cmd := exec.Command("kubectl", "version", "-o", "json")
 	out, err := cmd.CombinedOutput()
 	if err != nil {
+		glog.V(2).Infof("Failed to query kubectl: %s", err)
 		glog.V(2).Info(err)
 	}
 
@@ -324,6 +330,7 @@ func getKubeVersionFromKubelet() *KubeVersion {
 	out, err := cmd.CombinedOutput()
 
 	if err != nil {
+		glog.V(2).Infof("Failed to query kubelet: %s", err)
 		glog.V(2).Info(err)
 	}
 
@@ -331,7 +338,7 @@ func getKubeVersionFromKubelet() *KubeVersion {
 }
 
 func getVersionFromKubectlOutput(s string) *KubeVersion {
-	glog.V(2).Info(s)
+	glog.V(2).Infof("Kubectl output: %s", s)
 	type versionResult struct {
 		ServerVersion VersionResponse
 	}
@@ -354,7 +361,7 @@ func getVersionFromKubectlOutput(s string) *KubeVersion {
 }
 
 func getVersionFromKubeletOutput(s string) *KubeVersion {
-	glog.V(2).Info(s)
+	glog.V(2).Infof("Kubelet output: %s", s)
 	serverVersionRe := regexp.MustCompile(`Kubernetes v(\d+.\d+)`)
 	subs := serverVersionRe.FindStringSubmatch(s)
 	if len(subs) < 2 {
diff --git a/docs/asff.md b/docs/asff.md
index 7445d84..40cdfbe 100644
--- a/docs/asff.md
+++ b/docs/asff.md
@@ -15,7 +15,7 @@ You can configure kube-bench with the `--asff` to send findings to AWS Security
 
 ## Configure permissions in an IAM Role
 
-* Grant these permissions to the IAM Role that the kube-bench pod will be associated with. There are two potions:
+* Grant these permissions to the IAM Role that the kube-bench pod will be associated with. There are two options:
   * You can run the kube-bench pod under a specific [service account associated with an IAM role](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) that has these permissions to write Security Hub findings.
   * Alternatively the pod can be granted permissions specified by the Role that your [EKS node group uses](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html).
   
@@ -36,16 +36,14 @@ Here is an example IAM Policy that you can attach to your EKS node group's IAM R
 }
 ```
 
-## Configure and rebuild kube-bench
+### Modify the job configuration
 
-You will need to download, build and push the kube-bench container image to your ECR repo as described in Step 3 of the [EKS instructions][eks-instructions], except that before you build the container image, you need to edit `cfg/eks-1.0/config.yaml` to specify the AWS account, AWS region, and the EKS Cluster ARN.
+* Modify the kube-bench Configmap in `job-eks-asff.yaml` to specify the AWS account, AWS region, and the EKS Cluster ARN.
+* In the same file, modify the image specifed in the Job to use the kube-bench image pushed to your ECR
+* [Optional] - If you have created a dedicated IAM role to be used with kube-bench as described above in [Configure permissions in an IAM Role](#configure-permissions-in-an-iam-role), you will need to add the IAM role arn to the kube-bench ServiceAccount in `job-eks-asff.yaml`.
+* Make sure that `job-eks-asff.yaml` specifies the container image you just pushed to your ECR registry.
 
-## Modify the job configuration
-
-* Modify `job-eks.yaml` to specify the `--asff` flag, so that kube-bench writes output in ASFF format to Security Hub
-* Make sure that `job-eks.yaml` specifies the container image you just pushed to your ECR registry.
-
-You can now run kube-bench as a pod in your cluster: `kubectl apply -f job-eks.yaml`
+You can now run kube-bench as a pod in your cluster: `kubectl apply -f job-eks-asff.yaml`
 
 Findings will be generated for any kube-bench test that generates a `[FAIL]` or `[WARN]` output. If all tests pass, no findings will be generated. However, it's recommended that you consult the pod log output to check whether any findings were generated but could not be written to Security Hub.
 
diff --git a/job-eks-asff.yaml b/job-eks-asff.yaml
new file mode 100644
index 0000000..741e282
--- /dev/null
+++ b/job-eks-asff.yaml
@@ -0,0 +1,67 @@
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: kube-bench
+  # If using a dedicated IAM role for kube-bench, uncomment the annotations
+  # block below and replace the ROLE_ARN
+  # annotations:
+  #   eks.amazonaws.com/role-arn: "<ROLE_ARN>"
+
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: kube-bench-eks-config
+data:
+  config.yaml: |
+    AWS_ACCOUNT: "<AWS_ACCT_NUMBER>"
+    AWS_REGION: "<AWS_REGION>"
+    CLUSTER_ARN: "<AWS_CLUSTER_ARN>"
+
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: kube-bench
+spec:
+  template:
+    spec:
+      hostPID: true
+      containers:
+        - name: kube-bench
+          # Push the image to your ECR and then refer to it here
+          image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref>
+          command: ["kube-bench", "node", "--benchmark", "eks-1.0", "--asff"]
+          volumeMounts:
+            - name: var-lib-kubelet
+              mountPath: /var/lib/kubelet
+              readOnly: true
+            - name: etc-systemd
+              mountPath: /etc/systemd
+              readOnly: true
+            - name: etc-kubernetes
+              mountPath: /etc/kubernetes
+              readOnly: true
+            - name: kube-bench-eks-config
+              mountPath: "/opt/kube-bench/cfg/eks-1.0/config.yaml"
+              subPath: config.yaml
+              readOnly: true
+      restartPolicy: Never
+      serviceAccountName: kube-bench
+      volumes:
+        - name: var-lib-kubelet
+          hostPath:
+            path: "/var/lib/kubelet"
+        - name: etc-systemd
+          hostPath:
+            path: "/etc/systemd"
+        - name: etc-kubernetes
+          hostPath:
+            path: "/etc/kubernetes"
+        - name: kube-bench-eks-config
+          configMap:
+            name: kube-bench-eks-config
+            items:
+              - key: config.yaml
+                path: config.yaml
diff --git a/job-eks.yaml b/job-eks.yaml
index 7a51e75..720c428 100644
--- a/job-eks.yaml
+++ b/job-eks.yaml
@@ -10,11 +10,9 @@ spec:
       containers:
         - name: kube-bench
           # Push the image to your ECR and then refer to it here
-          image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref>
-          # Use the --asff flag if you would like to send findings to AWS Security Hub
-          # Note that this requires you to rebuild a version of the kube-bench image
-          # after editing the cfg/eks-1.0/config.yaml with your account information
-          # command: ["kube-bench", "node", "--benchmark", "eks-1.0", "--asff"]
+          # image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref>
+          image: aquasec/kube-bench:latest
+          # To send findings to AWS Security Hub, refer to `job-eks-asff.yaml` instead
           command: ["kube-bench", "node", "--benchmark", "eks-1.0"]
           volumeMounts:
             - name: var-lib-kubelet
diff --git a/job-master.yaml b/job-master.yaml
index ad6be40..4154506 100644
--- a/job-master.yaml
+++ b/job-master.yaml
@@ -16,7 +16,7 @@ spec:
       containers:
         - name: kube-bench
           image: aquasec/kube-bench:latest
-          command: ["kube-bench", "master"]
+          command: ["kube-bench", "run", "--targets=master"]
           volumeMounts:
             - name: var-lib-etcd
               mountPath: /var/lib/etcd
diff --git a/job-node.yaml b/job-node.yaml
index 7160f4a..6d4bbce 100644
--- a/job-node.yaml
+++ b/job-node.yaml
@@ -10,7 +10,7 @@ spec:
       containers:
         - name: kube-bench
           image: aquasec/kube-bench:latest
-          command: ["kube-bench", "node"]
+          command: ["kube-bench", "run", "--targets=node"]
           volumeMounts:
             - name: var-lib-kubelet
               mountPath: /var/lib/kubelet


Test patch:
diff --git a/check/test.go b/check/test.go
index b5abd30..3c63d45 100644
--- a/check/test.go
+++ b/check/test.go
@@ -126,6 +126,9 @@ func (t flagTestItem) findValue(s string) (match bool, value string, err error)
 		// flag: somevalue
 		// --flag
 		// somevalue
+		// DOESN'T COVER - use pathTestItem implementation of findValue() for this
+		// flag:
+		//	 - wehbook
 		pttn := `(` + t.Flag + `)(=|: *)*([^\s]*) *`
 		flagRe := regexp.MustCompile(pttn)
 		vals := flagRe.FindStringSubmatch(s)
@@ -145,7 +148,7 @@ func (t flagTestItem) findValue(s string) (match bool, value string, err error)
 			err = fmt.Errorf("invalid flag in testItem definition: %s", s)
 		}
 	}
-	glog.V(3).Infof("In flagTestItem.findValue %s, match %v, s %s, t.Flag %s", value, match, s, t.Flag)
+	glog.V(3).Infof("In flagTestItem.findValue %s", value)
 
 	return match, value, err
 }
@@ -183,6 +186,7 @@ func (t envTestItem) findValue(s string) (match bool, value string, err error) {
 			value = ""
 		}
 	}
+	glog.V(3).Infof("In envTestItem.findValue %s", value)
 	return match, value, nil
 }
 
@@ -232,10 +236,22 @@ func (t testItem) evaluate(s string) *testOutput {
 	}
 
 	result.flagFound = match
-	glog.V(3).Info(fmt.Sprintf("found %v", result.flagFound))
-
-
-	return result
+	var isExist = "exists"
+	if !result.flagFound{
+		isExist = "does not exist"
+	}
+	switch t.auditUsed {
+        case "auditCommand": 
+			glog.V(3).Infof("Flag '%s' %s", t.Flag, isExist)
+        case "auditConfig":
+			glog.V(3).Infof("Path '%s' %s", t.Path, isExist)
+		case "auditEnv":
+			glog.V(3).Infof("Env '%s' %s", t.Env, isExist)
+		default: 
+		glog.V(3).Infof("Error with identify audit used %s", t.auditUsed)
+    	}
+	
+    	return result
 }
 
 func compareOp(tCompareOp string, flagVal string, tCompareValue string, flagName string) (string, bool) {
diff --git a/cmd/common_test.go b/cmd/common_test.go
index 60fb234..eefe501 100644
--- a/cmd/common_test.go
+++ b/cmd/common_test.go
@@ -195,17 +195,19 @@ func TestIsMaster(t *testing.T) {
 	defer restore()
 
 	for _, tc := range testCases {
-		cfgFile = tc.cfgFile
-		initConfig()
-
-		oldGetBinariesFunc := getBinariesFunc
-		getBinariesFunc = tc.getBinariesFunc
-		defer func() {
-			getBinariesFunc = oldGetBinariesFunc
-			cfgFile = ""
+		func() {
+			cfgFile = tc.cfgFile
+			initConfig()
+
+			oldGetBinariesFunc := getBinariesFunc
+			getBinariesFunc = tc.getBinariesFunc
+			defer func() {
+				getBinariesFunc = oldGetBinariesFunc
+				cfgFile = ""
+			}()
+
+			assert.Equal(t, tc.isMaster, isMaster(), tc.name)
 		}()
-
-		assert.Equal(t, tc.isMaster, isMaster(), tc.name)
 	}
 }
 
@@ -356,7 +358,7 @@ func TestGetBenchmarkVersion(t *testing.T) {
 		succeed          bool
 	}{
 		{n: "both versions", kubeVersion: "1.11", benchmarkVersion: "cis-1.3", exp: "cis-1.3", callFn: withNoPath, v: viper.New(), succeed: false},
-		{n: "no version-missing-kubectl", kubeVersion: "", benchmarkVersion: "", v: viperWithData, exp: "", callFn: withNoPath, succeed: false},
+		{n: "no version-missing-kubectl", kubeVersion: "", benchmarkVersion: "", v: viperWithData, exp: "cis-1.6", callFn: withNoPath, succeed: true},
 		{n: "no version-fakeKubectl", kubeVersion: "", benchmarkVersion: "", v: viperWithData, exp: "cis-1.5", callFn: withFakeKubectl, succeed: true},
 		{n: "kubeVersion", kubeVersion: "1.15", benchmarkVersion: "", v: viperWithData, exp: "cis-1.5", callFn: withNoPath, succeed: true},
 		{n: "ocpVersion310", kubeVersion: "ocp-3.10", benchmarkVersion: "", v: viperWithData, exp: "rh-0.7", callFn: withNoPath, succeed: true},
@@ -506,17 +508,19 @@ func TestIsEtcd(t *testing.T) {
 	defer restore()
 
 	for _, tc := range testCases {
-		cfgFile = tc.cfgFile
-		initConfig()
-
-		oldGetBinariesFunc := getBinariesFunc
-		getBinariesFunc = tc.getBinariesFunc
-		defer func() {
-			getBinariesFunc = oldGetBinariesFunc
-			cfgFile = ""
+		func() {
+			cfgFile = tc.cfgFile
+			initConfig()
+
+			oldGetBinariesFunc := getBinariesFunc
+			getBinariesFunc = tc.getBinariesFunc
+			defer func() {
+				getBinariesFunc = oldGetBinariesFunc
+				cfgFile = ""
+			}()
+
+			assert.Equal(t, tc.isEtcd, isEtcd(), tc.name)
 		}()
-
-		assert.Equal(t, tc.isEtcd, isEtcd(), tc.name)
 	}
 }
 
diff --git a/cmd/kubernetes_version_test.go b/cmd/kubernetes_version_test.go
index 66d9b0a..b06f79f 100644
--- a/cmd/kubernetes_version_test.go
+++ b/cmd/kubernetes_version_test.go
@@ -11,8 +11,8 @@ import (
 	"testing"
 )
 
-func TestLoadCertficate(t *testing.T) {
-	tmp, err := ioutil.TempDir("", "TestFakeLoadCertficate")
+func TestLoadCertificate(t *testing.T) {
+	tmp, err := ioutil.TempDir("", "TestFakeLoadCertificate")
 	if err != nil {
 		t.Fatalf("unable to create temp directory: %v", err)
 	}
@@ -58,7 +58,7 @@ FAjB57z2NcIgJuVpQnGRYtr/JcH2Qdsq8bLtXaojUIWOOqoTDRLYozdMOOQ=
 
 	for id, c := range cases {
 		t.Run(strconv.Itoa(id), func(t *testing.T) {
-			tlsCert, err := loadCertficate(c.file)
+			tlsCert, err := loadCertificate(c.file)
 			if !c.fail {
 				if err != nil {
 					t.Errorf("unexpected error: %v", err)
diff --git a/integration/testdata/cis-1.5/job.data b/integration/testdata/cis-1.5/job.data
index 984d113..9c2e7a0 100644
--- a/integration/testdata/cis-1.5/job.data
+++ b/integration/testdata/cis-1.5/job.data
@@ -353,7 +353,7 @@ UIDs not including 0.
 5.2.8 Ensure that allowedCapabilities is not present in PSPs for the cluster unless
 it is set to an empty array.
 
-5.2.9 Review the use of capabilites in applications runnning on your cluster. Where a namespace
+5.2.9 Review the use of capabilites in applications running on your cluster. Where a namespace
 contains applicaions which do not require any Linux capabities to operate consider adding
 a PSP which forbids the admission of containers which do not drop all capabilities.
 
diff --git a/integration/testdata/cis-1.6/job.data b/integration/testdata/cis-1.6/job.data
index 54e79a4..54ec2b0 100644
--- a/integration/testdata/cis-1.6/job.data
+++ b/integration/testdata/cis-1.6/job.data
@@ -356,7 +356,7 @@ UIDs not including 0.
 5.2.8 Ensure that allowedCapabilities is not present in PSPs for the cluster unless
 it is set to an empty array.
 
-5.2.9 Review the use of capabilites in applications runnning on your cluster. Where a namespace
+5.2.9 Review the use of capabilites in applications running on your cluster. Where a namespace
 contains applicaions which do not require any Linux capabities to operate consider adding
 a PSP which forbids the admission of containers which do not drop all capabilities.
 
@@ -416,4 +416,4 @@ resources and that all new resources are created in a specific namespace.
 72 checks PASS
 11 checks FAIL
 39 checks WARN
-0 checks INFO
\ No newline at end of file
+0 checks INFO