Skip to content
Merged
78 changes: 78 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: build-image

on:
workflow_dispatch:
inputs:
IMAGE_TAG:
required: true
type: string
description: "Image tag for the node-agent image"
STORAGE_REF:
required: false
type: string
default: ""
description: "Branch/tag/commit of k8sstormcenter/storage to use (leave empty to keep go.mod default)"
PLATFORMS:
type: boolean
required: false
default: false
description: "Build for both amd64 and arm64"

jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
packages: write
contents: read
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: actions/setup-go@v5
with:
go-version: "1.25"

- name: Update storage dependency
if: ${{ inputs.STORAGE_REF != '' }}
env:
STORAGE_REF: ${{ inputs.STORAGE_REF }}
run: |
echo "Replacing github.com/kubescape/storage with github.com/k8sstormcenter/storage@${STORAGE_REF}"
go mod edit -replace "github.com/kubescape/storage=github.com/k8sstormcenter/storage@${STORAGE_REF}"
GOPROXY=direct GONOSUMCHECK="github.com/k8sstormcenter/*" go mod tidy
echo "Resolved storage version:"
grep "k8sstormcenter/storage" go.sum | head -1

- name: Ensure ig is installed
run: |
curl -L https://github.com/inspektor-gadget/inspektor-gadget/releases/download/v0.45.0/ig_0.45.0_amd64.deb -O
sudo dpkg -i ig_0.45.0_amd64.deb

- name: Build gadgets
run: make gadgets

- name: Set up QEMU
if: ${{ inputs.PLATFORMS }}
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: build/Dockerfile
tags: ghcr.io/${{ github.repository_owner }}/node-agent:${{ inputs.IMAGE_TAG }}
build-args: image_version=${{ inputs.IMAGE_TAG }}
platforms: ${{ inputs.PLATFORMS && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
push: true
2 changes: 1 addition & 1 deletion .github/workflows/bypass.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
needs: reset-run-number
uses: ./.github/workflows/incluster-comp-pr-merged.yaml
with:
IMAGE_NAME: quay.io/${{ github.repository_owner }}/node-agent
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/node-agent
IMAGE_TAG: v0.2.${{ needs.reset-run-number.outputs.run-number }}
COMPONENT_NAME: nodeAgent
CGO_ENABLED: 0
Expand Down
34 changes: 26 additions & 8 deletions .github/workflows/component-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,37 @@ name: Node Agent Component Tests
on:
pull_request:
types: [synchronize, ready_for_review, opened, reopened]
workflow_dispatch:
inputs:
build_image:
description: 'Build and push a new container image for the test'
type: boolean
required: false
default: false

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-push-image:
# Only run this job if it's a manual trigger with the box checked.
if: github.event_name == 'workflow_dispatch' && github.event.inputs.build_image == true
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Login to Quay.io
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: quay.io/kubescape
username: ${{ secrets.QUAYIO_REGISTRY_USERNAME }}
password: ${{ secrets.QUAYIO_REGISTRY_PASSWORD }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Install IG
run: |
sudo apt-get update
Expand All @@ -33,9 +47,9 @@ jobs:
run: |
COMMIT_HASH=$(git rev-parse --short HEAD)
export IMAGE_TAG=test-${COMMIT_HASH}
export IMAGE_REPO=quay.io/kubescape/node-agent
export IMAGE_REPO=ghcr.io/${{ github.repository_owner }}/node-agent
echo "image_repo=${IMAGE_REPO}" >> "$GITHUB_OUTPUT"
export IMAGE_NAME=quay.io/kubescape/node-agent:${IMAGE_TAG}
export IMAGE_NAME=ghcr.io/${{ github.repository_owner }}/node-agent:${IMAGE_TAG}
echo "image_tag=${IMAGE_TAG}" >> "$GITHUB_OUTPUT"
make docker-build TAG=${IMAGE_TAG} IMAGE=${IMAGE_REPO} && make docker-push TAG=${IMAGE_TAG} IMAGE=${IMAGE_REPO}
outputs:
Expand All @@ -44,7 +58,6 @@ jobs:

component-tests:
runs-on: ubuntu-latest
needs: build-and-push-image
continue-on-error: true
strategy:
matrix:
Expand Down Expand Up @@ -72,6 +85,7 @@ jobs:
Test_22_AlertOnPartialNetworkProfileTest,
Test_23_RuleCooldownTest,
Test_24_ProcessTreeDepthTest
Test_27_RegexFileOpenMatchTest
]
steps:
- name: Checkout code
Expand Down Expand Up @@ -101,7 +115,11 @@ jobs:
run: |
STORAGE_TAG=$(./tests/scripts/storage-tag.sh)
echo "Storage tag that will be used: ${STORAGE_TAG}"
helm upgrade --install kubescape ./tests/chart --set clusterName=`kubectl config current-context` --set nodeAgent.image.tag=${{ needs.build-and-push-image.outputs.image_tag }} --set nodeAgent.image.repository=${{ needs.build-and-push-image.outputs.image_repo }} --set storage.image.tag=${STORAGE_TAG} -n kubescape --create-namespace --wait --timeout 5m --debug
IMAGE_TAG="latest"
IMAGE_REPO='ghcr.io/k8sstormcenter/node-agent'
echo "Using Node Agent image: ${IMAGE_REPO}:${IMAGE_TAG}"
# End of constanze modification
helm upgrade --install kubescape ./tests/chart --set clusterName=`kubectl config current-context` --set nodeAgent.image.tag=${IMAGE_TAG} --set nodeAgent.image.repository=${IMAGE_REPO} --set storage.image.tag=${STORAGE_TAG} -n kubescape --create-namespace --wait --timeout 5m --debug
# Check that the node-agent pod is running
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=node-agent -n kubescape --timeout=300s
sleep 5
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/incluster-comp-pr-merged.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ jobs:
id: unit-test
run: go test -exec sudo -v ./...

- name: Login to Quay
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAYIO_REGISTRY_USERNAME }}
password: ${{ secrets.QUAYIO_REGISTRY_PASSWORD }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v6
Expand Down Expand Up @@ -349,12 +349,12 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Quay
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAYIO_REGISTRY_USERNAME }}
password: ${{ secrets.QUAYIO_REGISTRY_PASSWORD }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Docker retag
run: |
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/pr-created.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ concurrency:

jobs:
pr-created:
permissions:
pull-requests: write
security-events: write
contents: read
uses: ./.github/workflows/incluster-comp-pr-created.yaml
with:
GO_VERSION: "1.25"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-merged.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
needs: reset-run-number
uses: ./.github/workflows/incluster-comp-pr-merged.yaml
with:
IMAGE_NAME: quay.io/${{ github.repository_owner }}/node-agent
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/node-agent
IMAGE_TAG: v0.3.${{ needs.reset-run-number.outputs.run-number }}
COMPONENT_NAME: nodeAgent
CGO_ENABLED: 0
Expand Down
4 changes: 2 additions & 2 deletions tests/chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ global:
storage:
name: "storage"
image:
repository: quay.io/kubescape/storage
repository: ghcr.io/k8sstormcenter/storage
tag: v0.0.156
pullPolicy: Always
cleanupInterval: "6h"
Expand All @@ -50,7 +50,7 @@ storage:
nodeAgent:
name: node-agent
image:
repository: quay.io/kubescape/node-agent
repository: ghcr.io/k8sstormcenter/node-agent
tag: v0.2.21
pullPolicy: IfNotPresent

Expand Down
73 changes: 73 additions & 0 deletions tests/component_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1565,3 +1565,76 @@ func Test_24_ProcessTreeDepthTest(t *testing.T) {

t.Logf("Found alerts for the process tree depth: %v", alerts)
}

func Test_27_RegexFileOpenMatchTest(t *testing.T) {
start := time.Now()
defer tearDownTest(t, start)

t.Log("Starting regex file open match component test")

// 1. Setup workload and initial profile
ns := testutils.NewRandomNamespace()
wl, err := testutils.NewTestWorkload(ns.Name, path.Join(utils.CurrentDir(), "resources/nginx-deployment.yaml"))
require.NoError(t, err, "Failed to create workload")
require.NoError(t, wl.WaitForReady(80), "Workload failed to be ready")
require.NoError(t, wl.WaitForApplicationProfileCompletion(80), "Application profile did not complete")

// Wait for the initial profile to be processed
time.Sleep(30 * time.Second)

initialProfile, err := wl.GetApplicationProfile()
require.NoError(t, err, "Failed to get initial profile")

// 2. Apply a user-managed profile with a regex rule for file opens
t.Log("Applying user-managed profile...")
// Create the user-managed profile
userProfile := &v1beta1.ApplicationProfile{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("ug-%s", initialProfile.Name),
Namespace: initialProfile.Namespace,
Annotations: map[string]string{
"kubescape.io/managed-by": "User",
},
},
Spec: v1beta1.ApplicationProfileSpec{
Architectures: []string{"amd64"},
Containers: []v1beta1.ApplicationProfileContainer{
{
Name: "nginx",
Execs: []v1beta1.ExecCalls{
{
Path: "/usr/bin/ls",
Args: []string{"/usr/bin/ls", "-l"},
},
},
Opens: []v1beta1.OpenCalls{
{Path: "/etc/nginx/*", Flags: []string{"O_RDONLY"}},
{Path: "/var/log/nginx/*", Flags: []string{"O_WRONLY", "O_CREAT"}},
},
},
},
},
}

// Create the user-managed profile
k8sClient := k8sinterface.NewKubernetesApi()
storageClient := spdxv1beta1client.NewForConfigOrDie(k8sClient.K8SConfig)
_, err = storageClient.ApplicationProfiles(ns.Name).Create(context.Background(), userProfile, metav1.CreateOptions{})
require.NoError(t, err, "Failed to create user profile")

// Wait for the user profile to be processed by the system
time.Sleep(60 * time.Second)

// 3. Trigger file open events to test the regex rule
t.Log("Triggering file open events to test regex rule")
_, _, _ = wl.ExecIntoPod([]string{"cat", "/etc/nginx/nginx.conf"}, "nginx") // Should be allowed by regex
_, _, _ = wl.ExecIntoPod([]string{"cat", "/etc/hostname"}, "nginx") // Should be blocked (alert)

time.Sleep(30 * time.Second) // Wait for alerts

// 4. Verify alerts
alerts, err := testutils.GetAlerts(wl.Namespace)
require.NoError(t, err, "Failed to get alerts")
testutils.AssertNotContains(t, alerts, "Unexpected file open", "cat", "nginx", []bool{true})
testutils.AssertContains(t, alerts, "Unexpected file open", "cat", "hostname", []bool{true})
}
2 changes: 1 addition & 1 deletion tests/scripts/storage-tag.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#/bin/bash
curl -s https://raw.githubusercontent.com/kubescape/helm-charts/main/charts/kubescape-operator/values.yaml -o values.yaml
curl -s https://raw.githubusercontent.com/bob/test/localtestbuild/kubescape/values.yaml -o values.yaml
yq '.storage.image.tag' < values.yaml
rm -rf values.yaml
Loading