Skip to content

Commit

Permalink
Add support for tests namespace and multiple vex docs
Browse files Browse the repository at this point in the history
  • Loading branch information
szh committed May 21, 2024
1 parent 4b19d39 commit a64cdd7
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 15 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/self-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ jobs:
uses: ./
with:
helm-chart-path: "charts/examples/charts/hello-world"
ready-condition: "kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=hello-world --timeout=300s"
namespace: "self-test"
ready-condition: "kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=hello-world --timeout=300s -n self-test"
test-command: "self-test/test.sh"
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ artifact.

- `helm-chart-path`: (Required) The path to the Helm chart that you want to
test.
- `namespace`: (Optional) The namespace that the Helm chart should be deployed
to. If omitted, the namespace will be set to `tests`.
- `ready-condition`: (Optional) A condition that the action should wait for
before collecting VEX information.
- `test-command`: (Optional) The command that should be run to test the
Expand All @@ -26,7 +28,8 @@ To use this action in your workflow, include it in your workflow file with the r
- uses: slashben/generate-vex-action@v1
with:
helm-chart-path: './path/to/your/chart' # Ex. './charts/hello-world'
ready-condition: 'your-condition' # Ex. `kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=hello-world --timeout=300s`
namespace: 'tests' # This is the default value
ready-condition: 'your-condition' # Ex. `kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=hello-world --timeout=300s -n tests`
test-command: 'your-test-command' # Ex. `./ci/test_integration.sh`
```
Expand All @@ -35,3 +38,8 @@ Replace `your-org/generate-vex-with-kubescape@v1` with the actual repository and
## Example

To see an example of this Action in use, check out the [self test](./.github/workflows/self-test.yml) workflow in this repository.

## Roadmap

- Use https://github.com/helm/kind-action
- Add signing of VEX documents
12 changes: 10 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ inputs:
helm-chart-path:
description: "Path to Helm chart to test"
required: true
namespace:
description: "Namespace to deploy the Helm chart into"
default: "tests"
required: false
ready-condition:
description: "Condition to wait for before collecting VEX info"
required: false
Expand All @@ -22,22 +26,26 @@ runs:
env:
HELM_CHART_PATH: ${{ inputs.helm-chart-path }}
READY_CONDITION: ${{ inputs.ready-condition }}
TESTS_NAMESPACE: ${{ inputs.namespace }}
run: $GITHUB_ACTION_PATH/install.sh
shell: bash

- name: "Run tests"
env:
TEST_COMMAND: ${{ inputs.test-command }}
TESTS_NAMESPACE: ${{ inputs.namespace }}
run: $GITHUB_ACTION_PATH/test.sh
shell: bash

- name: "Generate VEX"
run: $GITHUB_ACTION_PATH/generate.sh
env:
TESTS_NAMESPACE: ${{ inputs.namespace }}
shell: bash

- name: Upload VEX document
if: always()
uses: actions/upload-artifact@v4
with:
name: VEX document
path: vex.json
name: VEX documents
path: out/*.json
41 changes: 34 additions & 7 deletions generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,39 @@ while [[ -z $(kubectl -n kubescape get openvulnerabilityexchangecontainers.spdx.
done

echo "Saving VEX results..."
kubectl -n kubescape get openvulnerabilityexchangecontainer \
"$(kubectl -n kubescape get openvulnerabilityexchangecontainer -o jsonpath='{.items[0].metadata.name}')" \
-o jsonpath='{.spec}' > vex.json
mkdir -p out

echo "Affected:"
jq "." vex.json | grep -c "\"affected\""
# List available VEX documents
vex_docs=$(kubectl get openvulnerabilityexchangecontainer -n kubescape -o jsonpath='{.items[*].metadata.name}')

echo "Not affected:"
jq "." vex.json | grep -c "\"not_affected\""
# Iterate over the VEX documents and save them
for doc in $vex_docs; do
# Get the full VEX document object
vex_object=$(kubectl -n kubescape get openvulnerabilityexchangecontainer "$doc" -o json)

# Check the labels to see if this VEX is for a workload in the TESTS_NAMESPACE

workload_ns=$(jq -r ".metadata.labels[\"kubescape.io/workload-namespace\"]" <<< "$vex_object")
if [[ $workload_ns != "$TESTS_NAMESPACE" ]]; then
echo "Skipping VEX document $doc as it is not for the TESTS_NAMESPACE"
continue
fi

# Get the image name
image=$(jq -r ".metadata.labels[\"kubescape.io/image-id\"]" <<< "$vex_object")

# # Save the VEX document (the .spec portion) to a file
jq ".spec" <<< "$vex_object" > out/"$image".json

echo "Affected:"
jq "." out/"$image".json | grep -c "\"affected\""

echo "Not affected:"
jq "." out/"$image".json | grep -c "\"not_affected\""
done

# Check if there are any VEX documents saved
if [[ -z $(ls out) ]]; then
echo "No VEX documents saved. Exiting..."
exit 1
fi
2 changes: 1 addition & 1 deletion install.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -x

helm install "$HELM_CHART_PATH" --wait --timeout 300s --generate-name
helm install "$HELM_CHART_PATH" --wait --timeout 300s --generate-name -n "$TESTS_NAMESPACE" --create-namespace

if [[ -n "$READY_CONDITION" ]]; then
$READY_CONDITION
Expand Down
6 changes: 3 additions & 3 deletions self-test/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
set -x

# Get the pod name and container port of the test application
POD_NAME=$(kubectl get pods -l "app.kubernetes.io/name=hello-world" -o jsonpath="{.items[0].metadata.name}")
CONTAINER_PORT=$(kubectl get pod "$POD_NAME" -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
POD_NAME=$(kubectl -n self-test get pods -l "app.kubernetes.io/name=hello-world" -o jsonpath="{.items[0].metadata.name}")
CONTAINER_PORT=$(kubectl -n self-test get pod "$POD_NAME" -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
# Expose the test app on localhost
kubectl port-forward "$POD_NAME" 8080:"$CONTAINER_PORT" &
kubectl -n self-test port-forward "$POD_NAME" 8080:"$CONTAINER_PORT" &
sleep 5
# Test the application by sending a request to it a number of times
for _ in {1..10}; do
Expand Down

0 comments on commit a64cdd7

Please sign in to comment.