Skip to content

Commit

Permalink
test(kube-hunter): Add integration test for kube-hunter command
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>
  • Loading branch information
danielpacak committed Jul 28, 2020
1 parent bce75c3 commit 728e9b0
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 78 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,24 @@ jobs:
file: ./coverage.txt
- name: Setup Kubernetes cluster (KIND)
uses: engineerd/setup-kind@v0.4.0
with:
version: v0.8.1
- name: Test connection to Kubernetes cluster
run: |
kubectl cluster-info
kubectl describe node
- name: Run integration tests
run: |
make integration-tests
kubectl get crd
env:
KUBECONFIG: /home/runner/.kube/config
- name: Debug
if: always()
run: |
kubectl get events -n starboard
kubectl describe pod -n starboard
kubectl logs -n starboard job/$(kubectl get job -n starboard -o jsonpath='{.items[0].metadata.name}')
- name: Release snapshot
uses: goreleaser/goreleaser-action@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ unit-tests: $(SOURCES)
go test -v -short -race -timeout 30s -coverprofile=coverage.txt -covermode=atomic ./...

integration-tests: build
go test -v ./integration-tests
go test ./itest -ginkgo.v -ginkgo.progress -test.v
66 changes: 0 additions & 66 deletions integration-tests/starboard_integration_test.go

This file was deleted.

102 changes: 102 additions & 0 deletions itest/integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package itest

import (
"context"
"os/exec"
"time"

. "github.com/onsi/gomega/gbytes"

"github.com/aquasecurity/starboard/pkg/kube"
. "github.com/onsi/gomega/gstruct"

. "github.com/onsi/gomega/gexec"
apiextentions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"

meta "k8s.io/apimachinery/pkg/apis/meta/v1"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("Starboard CLI", func() {

BeforeEach(func() {
command := exec.Command(pathToStarboardCLI, []string{"init", "-v", "3"}...)
session, err := Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Eventually(session).Should(Exit(0))
})

PDescribe("Running init command", func() {
It("should initialize Starboard", func() {

crdsList, err := apiextensionsClientset.CustomResourceDefinitions().List(context.TODO(), meta.ListOptions{})
Expect(err).ToNot(HaveOccurred())

GetNames := func(crds []apiextentions.CustomResourceDefinition) []string {
names := make([]string, len(crds))
for i, crd := range crds {
names[i] = crd.Name
}
return names
}

Expect(crdsList.Items).To(WithTransform(GetNames, ContainElements(
"ciskubebenchreports.aquasecurity.github.io",
"configauditreports.aquasecurity.github.io",
"kubehunterreports.aquasecurity.github.io",
"vulnerabilities.aquasecurity.github.io",
)))

_, err = kubernetesClientset.CoreV1().Namespaces().Get(context.TODO(), "starboard", meta.GetOptions{})
Expect(err).ToNot(HaveOccurred())

// TODO Assert other Kubernetes resources that we create in the init command
})
})

PDescribe("Running version command", func() {
It("should print the current version of the executable binary", func() {
command := exec.Command(pathToStarboardCLI, []string{"version"}...)
session, err := Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Eventually(session).Should(Say("Starboard Version: {Version:dev Commit:none Date:unknown}\n"))
})
})

Describe("Running kube-hunter", func() {
It("should run kube-hunter", func() {

command := exec.Command(pathToStarboardCLI, "kube-hunter", "-v", "3", "--delete-scan-job=false")
session, err := Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Eventually(session, 2*time.Minute).Should(Exit(0))

report, err := starboardClientset.AquasecurityV1alpha1().KubeHunterReports().
Get(context.TODO(), "cluster", meta.GetOptions{})

Expect(err).ToNot(HaveOccurred())
Expect(report.Labels).To(MatchAllKeys(Keys{
kube.LabelResourceKind: Equal("Cluster"),
kube.LabelResourceName: Equal("cluster"),
}))
})
})

//AfterEach(func() {
// command := exec.Command(pathToStarboardCLI, []string{"cleanup", "-v", "3"}...)
// session, err := Start(command, GinkgoWriter, GinkgoWriter)
// Expect(err).ToNot(HaveOccurred())
// Eventually(session).Should(Exit(0))
//
// // TODO We have to wait for the termination of the starboard namespace. Otherwise the init command fails
// // TODO when it attempts to create Kubernetes objects in the namespace that is being terminated.
// // TODO Maybe the cleanup command should block and wait unit the namespace is terminated?
// Eventually(func() bool {
// _, err := kubernetesClientset.CoreV1().Namespaces().Get(context.TODO(), "starboard", meta.GetOptions{})
// return errors.IsNotFound(err)
// }, 10*time.Second).Should(BeTrue())
//})

})
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package integration_tests
package itest

import (
"os"
"testing"

"github.com/onsi/gomega/gexec"
starboardapi "github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"

. "github.com/onsi/gomega/gexec"
"k8s.io/client-go/tools/clientcmd"

. "github.com/onsi/ginkgo"
Expand All @@ -16,6 +18,7 @@ import (
var (
kubernetesClientset kubernetes.Interface
apiextensionsClientset apiextensions.ApiextensionsV1beta1Interface
starboardClientset starboardapi.Interface
)

var (
Expand All @@ -24,7 +27,7 @@ var (

var _ = BeforeSuite(func() {
var err error
pathToStarboardCLI, err = gexec.Build("github.com/aquasecurity/starboard/cmd/starboard")
pathToStarboardCLI, err = Build("github.com/aquasecurity/starboard/cmd/starboard")
Expect(err).ToNot(HaveOccurred())

config, err := clientcmd.BuildConfigFromFlags("", os.Getenv("KUBECONFIG"))
Expand All @@ -35,6 +38,9 @@ var _ = BeforeSuite(func() {

apiextensionsClientset, err = apiextensions.NewForConfig(config)
Expect(err).ToNot(HaveOccurred())

starboardClientset, err = starboardapi.NewForConfig(config)
Expect(err).ToNot(HaveOccurred())
})

func TestStarboardCLI(t *testing.T) {
Expand All @@ -46,5 +52,5 @@ func TestStarboardCLI(t *testing.T) {
}

var _ = AfterSuite(func() {
gexec.CleanupBuildArtifacts()
CleanupBuildArtifacts()
})
23 changes: 16 additions & 7 deletions pkg/kubehunter/crd/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"errors"
"strings"

apierrors "k8s.io/apimachinery/pkg/api/errors"

"github.com/aquasecurity/starboard/pkg/kube"

"github.com/aquasecurity/starboard/pkg/kubehunter"
Expand All @@ -25,14 +27,11 @@ func NewWriter(clientset starboardapi.Interface) kubehunter.Writer {

}

func (w *writer) Write(ctx context.Context, report starboard.KubeHunterOutput, cluster string) (err error) {
func (w *writer) Write(ctx context.Context, report starboard.KubeHunterOutput, cluster string) error {
if strings.TrimSpace(cluster) == "" {
err = errors.New("cluster name must not be blank")
return
return errors.New("cluster name must not be blank")
}
// TODO Check if an instance of the report with the given name already exists.
// TODO If exists just update it, create new instance otherwise
_, err = w.clientset.AquasecurityV1alpha1().KubeHunterReports().Create(ctx, &starboard.KubeHunterReport{
_, err := w.clientset.AquasecurityV1alpha1().KubeHunterReports().Create(ctx, &starboard.KubeHunterReport{
ObjectMeta: meta.ObjectMeta{
Name: cluster,
Labels: map[string]string{
Expand All @@ -42,5 +41,15 @@ func (w *writer) Write(ctx context.Context, report starboard.KubeHunterOutput, c
},
Report: report,
}, meta.CreateOptions{})
return
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
}

0 comments on commit 728e9b0

Please sign in to comment.