Repository: aquasecurity/starboard
Pull request #330 (2021-01-11 20:11:52)

refactor: kubehunter package
Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>

codecov[bot]: # [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/330?src=pr&el=h1) Report
> Merging [#330](https://codecov.io/gh/aquasecurity/starboard/pull/330?src=pr&el=desc) (c8deb20) into [main](https://codecov.io/gh/aquasecurity/starboard/commit/69e885c30eac3306622f53a2c3adc9718c001fde?el=desc) (69e885c) will **decrease** coverage by `36.25%`.
> The diff coverage is `76.00%`.

[![Impacted file tree graph](https://codecov.io/gh/aquasecurity/starboard/pull/330/graphs/tree.svg?width=650&height=150&src=pr&token=qqTGKAJ0Wb)](https://codecov.io/gh/aquasecurity/starboard/pull/330?src=pr&el=tree)

```diff
@@             Coverage Diff             @@
##             main     #330       +/-   ##
===========================================
- Coverage   62.35%   26.10%   -36.26%     
===========================================
  Files          56       53        -3     
  Lines        2763     2567      -196     
===========================================
- Hits         1723      670     -1053     
- Misses        816     1843     +1027     
+ Partials      224       54      -170     
```


| [Impacted Files](https://codecov.io/gh/aquasecurity/starboard/pull/330?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/cmd/scan\_kubehunter.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2NtZC9zY2FuX2t1YmVodW50ZXIuZ28=) | `0.00% <0.00%> (-19.24%)` | :arrow_down: |
| [pkg/kubehunter/writer.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2t1YmVodW50ZXIvd3JpdGVyLmdv) | `82.60% <82.60%> (ø)` | |
| [pkg/cmd/get.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2NtZC9nZXQuZ28=) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/find.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2NtZC9maW5kLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/root.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2NtZC9yb290Lmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/scan.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2NtZC9zY2FuLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/polaris.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2NtZC9wb2xhcmlzLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/version.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2NtZC92ZXJzaW9uLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/kube\_bench.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2NtZC9rdWJlX2JlbmNoLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/kube\_hunter.go](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree#diff-cGtnL2NtZC9rdWJlX2h1bnRlci5nbw==) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| ... and [31 more](https://codecov.io/gh/aquasecurity/starboard/pull/330/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/330?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/starboard/pull/330?src=pr&el=footer). Last update [69e885c...c8deb20](https://codecov.io/gh/aquasecurity/starboard/pull/330?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/pkg/cmd/scan_kubehunter.go b/pkg/cmd/scan_kubehunter.go
index 0078086..b313a6f 100644
--- a/pkg/cmd/scan_kubehunter.go
+++ b/pkg/cmd/scan_kubehunter.go
@@ -3,11 +3,9 @@ package cmd
 import (
 	"context"
 
-	"github.com/aquasecurity/starboard/pkg/starboard"
-
-	starboardapi "github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
+	"github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
 	"github.com/aquasecurity/starboard/pkg/kubehunter"
-	"github.com/aquasecurity/starboard/pkg/kubehunter/crd"
+	"github.com/aquasecurity/starboard/pkg/starboard"
 	"github.com/spf13/cobra"
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/client-go/kubernetes"
@@ -56,10 +54,10 @@ func ScanKubeHunterReports(cf *genericclioptions.ConfigFlags) func(cmd *cobra.Co
 		if err != nil {
 			return err
 		}
-		starboardClientset, err := starboardapi.NewForConfig(kubeConfig)
+		starboardClientset, err := versioned.NewForConfig(kubeConfig)
 		if err != nil {
 			return err
 		}
-		return crd.NewWriter(starboardClientset).Write(ctx, report, kubeHunterReportName)
+		return kubehunter.NewWriter(starboardClientset).Write(ctx, report, kubeHunterReportName)
 	}
 }
diff --git a/pkg/kubehunter/crd/writer.go b/pkg/kubehunter/crd/writer.go
deleted file mode 100644
index 4223928..0000000
--- a/pkg/kubehunter/crd/writer.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package crd
-
-import (
-	"context"
-	"errors"
-	"strings"
-
-	apierrors "k8s.io/apimachinery/pkg/api/errors"
-
-	"github.com/aquasecurity/starboard/pkg/kube"
-
-	"github.com/aquasecurity/starboard/pkg/kubehunter"
-
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
-	starboardapi "github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
-	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-type writer struct {
-	clientset starboardapi.Interface
-}
-
-func NewWriter(clientset starboardapi.Interface) kubehunter.Writer {
-	return &writer{
-		clientset: clientset,
-	}
-
-}
-
-func (w *writer) Write(ctx context.Context, report starboard.KubeHunterOutput, cluster string) error {
-	if strings.TrimSpace(cluster) == "" {
-		return errors.New("cluster name must not be blank")
-	}
-	_, err := w.clientset.AquasecurityV1alpha1().KubeHunterReports().Create(ctx, &starboard.KubeHunterReport{
-		ObjectMeta: meta.ObjectMeta{
-			Name: cluster,
-			Labels: map[string]string{
-				kube.LabelResourceKind: "Cluster",
-				kube.LabelResourceName: cluster,
-			},
-		},
-		Report: report,
-	}, meta.CreateOptions{})
-	if err != nil && apierrors.IsAlreadyExists(err) {
-		found, err := w.clientset.AquasecurityV1alpha1().KubeHunterReports().Get(ctx, cluster, meta.GetOptions{})
-		if err != nil {
-			return err
-		}
-		deepCopy := found.DeepCopy()
-		deepCopy.Report = report
-		_, err = w.clientset.AquasecurityV1alpha1().KubeHunterReports().Update(ctx, deepCopy, meta.UpdateOptions{})
-		return err
-	}
-	return err
-}
diff --git a/pkg/kubehunter/writer.go b/pkg/kubehunter/writer.go
index 93c5a9c..9d1aa68 100644
--- a/pkg/kubehunter/writer.go
+++ b/pkg/kubehunter/writer.go
@@ -2,10 +2,53 @@ package kubehunter
 
 import (
 	"context"
+	"errors"
+	"strings"
 
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
+	"github.com/aquasecurity/starboard/pkg/kube"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 type Writer interface {
-	Write(ctx context.Context, report starboard.KubeHunterOutput, cluster string) error
+	Write(ctx context.Context, report v1alpha1.KubeHunterOutput, cluster string) error
+}
+
+type writer struct {
+	clientset versioned.Interface
+}
+
+func NewWriter(clientset versioned.Interface) Writer {
+	return &writer{
+		clientset: clientset,
+	}
+}
+
+func (w *writer) Write(ctx context.Context, report v1alpha1.KubeHunterOutput, cluster string) error {
+	if strings.TrimSpace(cluster) == "" {
+		return errors.New("cluster name must not be blank")
+	}
+	_, err := w.clientset.AquasecurityV1alpha1().KubeHunterReports().Create(ctx, &v1alpha1.KubeHunterReport{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: cluster,
+			Labels: map[string]string{
+				kube.LabelResourceKind: "Cluster",
+				kube.LabelResourceName: cluster,
+			},
+		},
+		Report: report,
+	}, metav1.CreateOptions{})
+	if err != nil && apierrors.IsAlreadyExists(err) {
+		found, err := w.clientset.AquasecurityV1alpha1().KubeHunterReports().Get(ctx, cluster, metav1.GetOptions{})
+		if err != nil {
+			return err
+		}
+		deepCopy := found.DeepCopy()
+		deepCopy.Report = report
+		_, err = w.clientset.AquasecurityV1alpha1().KubeHunterReports().Update(ctx, deepCopy, metav1.UpdateOptions{})
+		return err
+	}
+	return err
 }


Test patch:
diff --git a/pkg/kubehunter/writer_test.go b/pkg/kubehunter/writer_test.go
new file mode 100644
index 0000000..f32827d
--- /dev/null
+++ b/pkg/kubehunter/writer_test.go
@@ -0,0 +1,103 @@
+package kubehunter_test
+
+import (
+	"context"
+	"testing"
+
+	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/generated/clientset/versioned/fake"
+	"github.com/aquasecurity/starboard/pkg/kube"
+	"github.com/aquasecurity/starboard/pkg/kubehunter"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func TestWriter_Write(t *testing.T) {
+
+	t.Run("Should create KubeHunterReport", func(t *testing.T) {
+		clientset := fake.NewSimpleClientset()
+
+		writer := kubehunter.NewWriter(clientset)
+		err := writer.Write(context.TODO(), v1alpha1.KubeHunterOutput{
+			Summary: v1alpha1.KubeHunterSummary{
+				HighCount: 7,
+			},
+		}, "my-cluster")
+		require.NoError(t, err)
+
+		list, err := clientset.AquasecurityV1alpha1().KubeHunterReports().List(context.TODO(), metav1.ListOptions{})
+		require.NoError(t, err)
+
+		reports := map[string]v1alpha1.KubeHunterReport{}
+		for _, item := range list.Items {
+			reports[item.Name] = item
+		}
+		assert.Equal(t, map[string]v1alpha1.KubeHunterReport{
+			"my-cluster": {
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "my-cluster",
+					Labels: map[string]string{
+						kube.LabelResourceKind: "Cluster",
+						kube.LabelResourceName: "my-cluster",
+					},
+				},
+				Report: v1alpha1.KubeHunterOutput{
+					Summary: v1alpha1.KubeHunterSummary{
+						HighCount: 7,
+					},
+				},
+			},
+		}, reports)
+	})
+
+	t.Run("Should update KubeHunterReport", func(t *testing.T) {
+		clientset := fake.NewSimpleClientset(&v1alpha1.KubeHunterReport{
+			ObjectMeta: metav1.ObjectMeta{
+				Name: "my-cluster",
+				Labels: map[string]string{
+					kube.LabelResourceKind: "Cluster",
+					kube.LabelResourceName: "my-cluster",
+				},
+			},
+			Report: v1alpha1.KubeHunterOutput{
+				Summary: v1alpha1.KubeHunterSummary{
+					HighCount: 1,
+				},
+			},
+		})
+
+		writer := kubehunter.NewWriter(clientset)
+		err := writer.Write(context.TODO(), v1alpha1.KubeHunterOutput{
+			Summary: v1alpha1.KubeHunterSummary{
+				HighCount: 3,
+			},
+		}, "my-cluster")
+		require.NoError(t, err)
+
+		list, err := clientset.AquasecurityV1alpha1().KubeHunterReports().List(context.TODO(), metav1.ListOptions{})
+		require.NoError(t, err)
+
+		reports := map[string]v1alpha1.KubeHunterReport{}
+		for _, item := range list.Items {
+			reports[item.Name] = item
+		}
+		assert.Equal(t, map[string]v1alpha1.KubeHunterReport{
+			"my-cluster": {
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "my-cluster",
+					Labels: map[string]string{
+						kube.LabelResourceKind: "Cluster",
+						kube.LabelResourceName: "my-cluster",
+					},
+				},
+				Report: v1alpha1.KubeHunterOutput{
+					Summary: v1alpha1.KubeHunterSummary{
+						HighCount: 3,
+					},
+				},
+			},
+		}, reports)
+	})
+
+}