303 lines
9.1 KiB
Go
303 lines
9.1 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright 2024 The Falco Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package unit
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gruntwork-io/terratest/modules/helm"
|
|
"github.com/stretchr/testify/require"
|
|
corev1 "k8s.io/api/core/v1"
|
|
)
|
|
|
|
func TestDriverConfigInFalcoConfig(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
helmChartPath, err := filepath.Abs(chartPath)
|
|
require.NoError(t, err)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
values map[string]string
|
|
expected func(t *testing.T, config any)
|
|
}{
|
|
{
|
|
"defaultValues",
|
|
nil,
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, bufSizePreset, dropFailedExit, err := getKmodConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "kmod", kind)
|
|
require.Equal(t, float64(4), bufSizePreset)
|
|
require.False(t, dropFailedExit)
|
|
},
|
|
},
|
|
{
|
|
"kind=kmod",
|
|
map[string]string{
|
|
"driver.kind": "kmod",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, bufSizePreset, dropFailedExit, err := getKmodConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "kmod", kind)
|
|
require.Equal(t, float64(4), bufSizePreset)
|
|
require.False(t, dropFailedExit)
|
|
},
|
|
},
|
|
{
|
|
"kind=module(alias)",
|
|
map[string]string{
|
|
"driver.kind": "module",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, bufSizePreset, dropFailedExit, err := getKmodConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "kmod", kind)
|
|
require.Equal(t, float64(4), bufSizePreset)
|
|
require.False(t, dropFailedExit)
|
|
},
|
|
},
|
|
{
|
|
"kmod=onfig",
|
|
map[string]string{
|
|
"driver.kmod.bufSizePreset": "6",
|
|
"driver.kmod.dropFailedExit": "true",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, bufSizePreset, dropFailedExit, err := getKmodConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "kmod", kind)
|
|
require.Equal(t, float64(6), bufSizePreset)
|
|
require.True(t, dropFailedExit)
|
|
},
|
|
},
|
|
{
|
|
"kind=ebpf",
|
|
map[string]string{
|
|
"driver.kind": "ebpf",
|
|
"driver.ebpf.bufSizePreset": "6",
|
|
"driver.ebpf.dropFailedExit": "true",
|
|
"driver.ebpf.path": "testing/Path/ebpf",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, path, bufSizePreset, dropFailedExit, err := getEbpfConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "ebpf", kind)
|
|
require.Equal(t, "testing/Path/ebpf", path)
|
|
require.Equal(t, float64(6), bufSizePreset)
|
|
require.True(t, dropFailedExit)
|
|
},
|
|
},
|
|
{
|
|
"ebpf=config",
|
|
map[string]string{
|
|
"driver.kind": "ebpf",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, path, bufSizePreset, dropFailedExit, err := getEbpfConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "ebpf", kind)
|
|
require.Equal(t, "${HOME}/.falco/falco-bpf.o", path)
|
|
require.Equal(t, float64(4), bufSizePreset)
|
|
require.False(t, dropFailedExit)
|
|
},
|
|
},
|
|
{
|
|
"kind=modern_ebpf",
|
|
map[string]string{
|
|
"driver.kind": "modern_ebpf",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, bufSizePreset, cpusForEachBuffer, dropFailedExit, err := getModernEbpfConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "modern_ebpf", kind)
|
|
require.Equal(t, float64(4), bufSizePreset)
|
|
require.Equal(t, float64(2), cpusForEachBuffer)
|
|
require.False(t, dropFailedExit)
|
|
},
|
|
},
|
|
{
|
|
"kind=modern-bpf(alias)",
|
|
map[string]string{
|
|
"driver.kind": "modern-bpf",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, bufSizePreset, cpusForEachBuffer, dropFailedExit, err := getModernEbpfConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "modern_ebpf", kind)
|
|
require.Equal(t, float64(4), bufSizePreset)
|
|
require.Equal(t, float64(2), cpusForEachBuffer)
|
|
require.False(t, dropFailedExit)
|
|
},
|
|
},
|
|
{
|
|
"modernEbpf=config",
|
|
map[string]string{
|
|
"driver.kind": "modern-bpf",
|
|
"driver.modernEbpf.bufSizePreset": "6",
|
|
"driver.modernEbpf.dropFailedExit": "true",
|
|
"driver.modernEbpf.cpusForEachBuffer": "8",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, bufSizePreset, cpusForEachBuffer, dropFailedExit, err := getModernEbpfConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "modern_ebpf", kind)
|
|
require.Equal(t, float64(6), bufSizePreset)
|
|
require.Equal(t, float64(8), cpusForEachBuffer)
|
|
require.True(t, dropFailedExit)
|
|
},
|
|
},
|
|
{
|
|
"kind=gvisor",
|
|
map[string]string{
|
|
"driver.kind": "gvisor",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, config, root, err := getGvisorConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "gvisor", kind)
|
|
require.Equal(t, "/gvisor-config/pod-init.json", config)
|
|
require.Equal(t, "/host/run/containerd/runsc/k8s.io", root)
|
|
},
|
|
},
|
|
{
|
|
"gvisor=config",
|
|
map[string]string{
|
|
"driver.kind": "gvisor",
|
|
"driver.gvisor.runsc.root": "/my/root/test",
|
|
},
|
|
func(t *testing.T, config any) {
|
|
require.Len(t, config, 2, "should have only two items")
|
|
kind, config, root, err := getGvisorConfig(config)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "gvisor", kind)
|
|
require.Equal(t, "/gvisor-config/pod-init.json", config)
|
|
require.Equal(t, "/host/my/root/test/k8s.io", root)
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, testCase := range testCases {
|
|
testCase := testCase
|
|
|
|
t.Run(testCase.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
options := &helm.Options{SetValues: testCase.values}
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/configmap.yaml"})
|
|
|
|
var cm corev1.ConfigMap
|
|
helm.UnmarshalK8SYaml(t, output, &cm)
|
|
var config map[string]interface{}
|
|
|
|
helm.UnmarshalK8SYaml(t, cm.Data["falco.yaml"], &config)
|
|
engine := config["engine"]
|
|
testCase.expected(t, engine)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDriverConfigWithUnsupportedDriver(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
helmChartPath, err := filepath.Abs(chartPath)
|
|
require.NoError(t, err)
|
|
|
|
values := map[string]string{
|
|
"driver.kind": "notExisting",
|
|
}
|
|
options := &helm.Options{SetValues: values}
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/configmap.yaml"})
|
|
require.Error(t, err)
|
|
require.True(t, strings.Contains(err.Error(), "unsupported driver kind: \"notExisting\". Supported drivers [kmod ebpf modern_ebpf gvisor], alias [module modern-bpf]"))
|
|
}
|
|
|
|
func getKmodConfig(config interface{}) (kind string, bufSizePreset float64, dropFailedExit bool, err error) {
|
|
configMap, ok := config.(map[string]interface{})
|
|
if !ok {
|
|
err = fmt.Errorf("can't assert type of config")
|
|
return
|
|
}
|
|
|
|
kind = configMap["kind"].(string)
|
|
kmod := configMap["kmod"].(map[string]interface{})
|
|
bufSizePreset = kmod["buf_size_preset"].(float64)
|
|
dropFailedExit = kmod["drop_failed_exit"].(bool)
|
|
|
|
return
|
|
}
|
|
|
|
func getEbpfConfig(config interface{}) (kind, path string, bufSizePreset float64, dropFailedExit bool, err error) {
|
|
configMap, ok := config.(map[string]interface{})
|
|
if !ok {
|
|
err = fmt.Errorf("can't assert type of config")
|
|
return
|
|
}
|
|
|
|
kind = configMap["kind"].(string)
|
|
ebpf := configMap["ebpf"].(map[string]interface{})
|
|
bufSizePreset = ebpf["buf_size_preset"].(float64)
|
|
dropFailedExit = ebpf["drop_failed_exit"].(bool)
|
|
path = ebpf["probe"].(string)
|
|
|
|
return
|
|
}
|
|
|
|
func getModernEbpfConfig(config interface{}) (kind string, bufSizePreset, cpusForEachBuffer float64, dropFailedExit bool, err error) {
|
|
configMap, ok := config.(map[string]interface{})
|
|
if !ok {
|
|
err = fmt.Errorf("can't assert type of config")
|
|
return
|
|
}
|
|
|
|
kind = configMap["kind"].(string)
|
|
modernEbpf := configMap["modern_ebpf"].(map[string]interface{})
|
|
bufSizePreset = modernEbpf["buf_size_preset"].(float64)
|
|
dropFailedExit = modernEbpf["drop_failed_exit"].(bool)
|
|
cpusForEachBuffer = modernEbpf["cpus_for_each_buffer"].(float64)
|
|
|
|
return
|
|
}
|
|
|
|
func getGvisorConfig(cfg interface{}) (kind, config, root string, err error) {
|
|
configMap, ok := cfg.(map[string]interface{})
|
|
if !ok {
|
|
err = fmt.Errorf("can't assert type of config")
|
|
return
|
|
}
|
|
|
|
kind = configMap["kind"].(string)
|
|
gvisor := configMap["gvisor"].(map[string]interface{})
|
|
config = gvisor["config"].(string)
|
|
root = gvisor["root"].(string)
|
|
|
|
return
|
|
}
|