diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index a55a8e50b..798427e0f 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -115,6 +115,36 @@ jobs: contents: read checks: write + cis-benchmark: + needs: + - "lint-gha" + - "lint-go" + - "lint-test-helm" + - "pre-commit" + - "unit-test" + strategy: + matrix: + config: + - {"provider": "Nutanix", "kubernetesMinor": "v1.32", "kubernetesVersion": "v1.32.3", "baseOS": "rocky-9.5"} + # Uncomment below once we have the ability to run e2e tests on other providers from GHA. + # - {"provider": "AWS", "kubernetesMinor": "v1.29", "kubernetesVersion": "v1.29.6"} + fail-fast: false + name: CIS Benchmark (${{ matrix.config.provider }} provider, Kubernetes ${{ matrix.config.kubernetesMinor }}) + uses: ./.github/workflows/e2e.yml + with: + focus: Quick start + provider: ${{ matrix.config.provider }} + kubernetes-version: ${{ matrix.config.kubernetesVersion }} + runs-on: ${{ matrix.config.provider == 'Nutanix' && 'self-hosted-ncn-dind' || 'ubuntu-22.04' }} + base-os: ${{ matrix.config.provider == 'Nutanix' && matrix.config.baseOS || '' }} + run-cis-benchmark: true + extra-labels: "cni:Cilium && addonStrategy:HelmAddon" + secrets: inherit + permissions: + contents: read + checks: write + + lint-go: runs-on: ubuntu-24.04 strategy: diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 12661a3ff..82c5b3690 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -14,6 +14,9 @@ on: focus: description: e2e tests to focus type: string + extra-labels: + description: Extra labels to pass to the e2e tests + type: string runs-on: description: The runner to run the e2e tests on type: string @@ -26,6 +29,10 @@ on: description: The OS image to use for the machine template type: string required: false + run-cis-benchmark: + description: Whether to run the CIS benchmark tests + type: boolean + default: false jobs: e2e-test: @@ -78,7 +85,7 @@ jobs: df -h - name: Run e2e tests - run: devbox run -- make e2e-test E2E_LABEL='provider:${{ inputs.provider }}' E2E_SKIP='${{ inputs.skip }}' E2E_FOCUS='${{ inputs.focus }}' E2E_VERBOSE=true + run: devbox run -- make e2e-test E2E_LABEL='provider:${{ inputs.provider }}${{format(' {0} {1}', inputs.extra-labels != '' && '&&' || '', inputs.extra-labels)}}' E2E_SKIP='${{ inputs.skip }}' E2E_FOCUS='${{ inputs.focus }}' E2E_VERBOSE=true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} @@ -95,6 +102,17 @@ jobs: KUBERNETES_VERSION_NUTANIX: ${{ inputs.kubernetes-version }} KINDEST_IMAGE_TAG: ${{ inputs.kubernetes-version }} E2E_KUBERNETES_VERSION: ${{ inputs.kubernetes-version }} + RUN_CIS_BENCHMARK: ${{ inputs.run-cis-benchmark }} + + - name: Add job summary for CIS benchmark + if: failure() && inputs.run-cis-benchmark + run: | + { + echo '## CIS Benchmark'; + echo '```plain'; + cat test/e2e/cis-benchmark-report.txt; + echo '```'; + } >>"${GITHUB_STEP_SUMMARY}" - if: success() || failure() # always run even if the previous step fails name: Publish e2e test report diff --git a/.gitignore b/.gitignore index 177e3755b..147fc64f4 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ test/e2e/config/caren-envsubst.yaml hack/tools/fetch-images/fetch-images caren-images.txt hack/examples/release/*-cluster-class.yaml +test/e2e/cis-benchmark-report.txt diff --git a/devbox.json b/devbox.json index 32c5c3add..b09ff1a51 100644 --- a/devbox.json +++ b/devbox.json @@ -37,6 +37,7 @@ "path:./hack/flakes#clusterctl-aws", "path:./hack/flakes#goprintconst", "path:./hack/flakes#helm-with-plugins", + "path:./hack/flakes#kubescape", "path:./hack/flakes#release-please" ], "shell": { diff --git a/hack/flakes/flake.nix b/hack/flakes/flake.nix index b6474ee53..e35e88ae5 100644 --- a/hack/flakes/flake.nix +++ b/hack/flakes/flake.nix @@ -106,6 +106,23 @@ helm-schema ]; }; + + kubescape = buildGo124Module rec { + name = "kubescape"; + version = "3.0.34"; + src = fetchFromGitHub { + owner = "kubescape"; + repo = "kubescape"; + tag = "v${version}"; + hash = "sha256-dZPSnq2kLbgD/QxdDpYnAiIvXOXAgO2dXWWG6ijRUsQ="; + fetchSubmodules = true; + }; + doCheck = false; + subPackages = [ "." ]; + proxyVendor = true; + vendorHash = "sha256-+HMT8MnBc5N/19+hYtY8A4mw3IaXyvjx2a2+GnksV/4="; + ldflags = [ "-s" "-w" "-X=github.com/kubescape/kubescape/v3/core/cautils.BuildNumber=v${version}" ]; + }; }; formatter = alejandra; diff --git a/test/e2e/quick_start_test.go b/test/e2e/quick_start_test.go index 0ab8b0dcc..6c8df0bc3 100644 --- a/test/e2e/quick_start_test.go +++ b/test/e2e/quick_start_test.go @@ -8,6 +8,7 @@ package e2e import ( "fmt" "os" + "os/exec" "slices" "strconv" "strings" @@ -307,6 +308,49 @@ var _ = Describe("Quick start", func() { ), }, ) + + if os.Getenv("RUN_CIS_BENCHMARK") == "true" { + By("Running CIS benchmark against workload cluster") + + kubescapeInstallCmd := exec.Command( //nolint:gosec // Only used for testing so safe here. + "helm", + "upgrade", + "--install", + "kubescape", + "--repo=https://kubescape.github.io/helm-charts/", + "kubescape-operator", + "--namespace=kubescape", + "--create-namespace", + "--wait", + "--wait-for-jobs", + fmt.Sprintf( + "--kubeconfig=%s", + workloadProxy.GetKubeconfigPath(), + ), + ) + kubescapeInstallCmd.Stdout = GinkgoWriter + kubescapeInstallCmd.Stderr = GinkgoWriter + Expect( + kubescapeInstallCmd.Run(), + ).To(Succeed(), "kubescape operator installation failed") + + kubescapeScanCmd := exec.Command( //nolint:gosec // Only used for testing so safe here. + "kubescape", + "scan", + "framework", + "cis-v1.10.0", + "--compliance-threshold=100", + "--output=cis-benchmark-report.txt", + "--kubeconfig", + workloadProxy.GetKubeconfigPath(), + ) + kubescapeScanCmd.Stdout = GinkgoWriter + kubescapeScanCmd.Stderr = GinkgoWriter + + Expect( + kubescapeScanCmd.Run(), + ).To(Succeed(), "CIS benchmark scan failed") + } }, } })