Skip to content

Commit eebe2b6

Browse files
feat(serverless-agent): add parameter to use bare pdig to instrument certain containers (#380)
Signed-off-by: francesco-racciatti <[email protected]>
1 parent 5b77776 commit eebe2b6

File tree

5 files changed

+506
-120
lines changed

5 files changed

+506
-120
lines changed

sysdig/data_source_sysdig_fargate_ECS_test.go

Lines changed: 213 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,17 @@ package sysdig
55
import (
66
"context"
77
"encoding/json"
8+
"fmt"
89
"os"
10+
"reflect"
911
"sort"
1012
"testing"
1113

1214
"github.com/Jeffail/gabs/v2"
1315
"github.com/falcosecurity/kilt/runtimes/cloudformation/cfnpatcher"
1416
"github.com/stretchr/testify/assert"
15-
)
16-
17-
var (
18-
testKiltDefinition = KiltRecipeConfig{
19-
SysdigAccessKey: "sysdig_access_key",
20-
AgentImage: "workload_agent_image",
21-
OrchestratorHost: "orchestrator_host",
22-
OrchestratorPort: "orchestrator_port",
23-
CollectorHost: "collector_host",
24-
CollectorPort: "collector_port",
25-
SysdigLogging: "sysdig_logging",
26-
}
27-
28-
testIgnoreContainers = []string{}
2917

30-
testContainerDefinitionFiles = []string{
31-
"fargate_entrypoint_test",
32-
"fargate_env_test",
33-
"fargate_cmd_test",
34-
"fargate_linuxparameters_test",
35-
"fargate_combined_test",
36-
"fargate_volumesfrom_test",
37-
"fargate_field_case_test",
38-
}
18+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
3919
)
4020

4121
// sortContainerEnv goes into a container definition and sorts the environment variables
@@ -59,12 +39,8 @@ func sortAndCompare(t *testing.T, expected []byte, actual []byte) {
5939
assert.JSONEq(t, expectedJSON, actualJSON)
6040
}
6141

62-
func TestECStransformation(t *testing.T) {
63-
inputfile, err := os.ReadFile("testfiles/ECSinput.json")
64-
if err != nil {
65-
t.Fatalf("Cannot find testfiles/ECSinput.json")
66-
}
67-
42+
// getKiltRecipe returns the default json Kilt recipe
43+
func getKiltRecipe(t *testing.T) string {
6844
recipeConfig := KiltRecipeConfig{
6945
SysdigAccessKey: "sysdig_access_key",
7046
AgentImage: "workload_agent_image",
@@ -75,20 +51,144 @@ func TestECStransformation(t *testing.T) {
7551
SysdigLogging: "sysdig_logging",
7652
}
7753

78-
jsonConf, err := json.Marshal(&recipeConfig)
54+
jsonRecipeConfig, err := json.Marshal(&recipeConfig)
7955
if err != nil {
8056
t.Fatalf("Failed to serialize configuration: %v", err.Error())
8157
}
8258

59+
return string(jsonRecipeConfig)
60+
}
61+
62+
func TestContains(t *testing.T) {
63+
tests := []struct {
64+
slice []string
65+
target string
66+
result bool
67+
}{
68+
{
69+
slice: []string{"gimme", "fried", "chicken"},
70+
target: "chicken",
71+
result: true,
72+
},
73+
{
74+
slice: []string{"the", "answer", "is"},
75+
target: "42",
76+
result: false,
77+
},
78+
{
79+
slice: []string{""},
80+
target: "empty",
81+
result: false,
82+
},
83+
}
84+
for idx, tc := range tests {
85+
t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) {
86+
result := contains(tc.slice, tc.target)
87+
assert.Equal(t, tc.result, result, "Error, expected: %t, got: %t", tc.result, result)
88+
})
89+
}
90+
}
91+
92+
func TestNewPatchOptions(t *testing.T) {
93+
newMockResource := func() *schema.Resource {
94+
return &schema.Resource{
95+
Schema: map[string]*schema.Schema{
96+
"ignore_containers": {
97+
Type: schema.TypeList,
98+
Elem: &schema.Schema{Type: schema.TypeString},
99+
},
100+
"bare_pdig_on_containers": {
101+
Type: schema.TypeList,
102+
Elem: &schema.Schema{Type: schema.TypeString},
103+
},
104+
"log_configuration": {
105+
Type: schema.TypeSet,
106+
MaxItems: 1,
107+
Elem: &schema.Resource{
108+
Schema: map[string]*schema.Schema{
109+
"group": {
110+
Type: schema.TypeString,
111+
Required: true,
112+
},
113+
"stream_prefix": {
114+
Type: schema.TypeString,
115+
Required: true,
116+
},
117+
"region": {
118+
Type: schema.TypeString,
119+
Required: true,
120+
},
121+
},
122+
},
123+
},
124+
},
125+
}
126+
}
127+
128+
// Create a mock resource
129+
resource := newMockResource()
130+
data := resource.Data(nil)
131+
132+
var err error
133+
err = data.Set("bare_pdig_on_containers", []interface{}{
134+
"gimme", "fried", "chicken",
135+
})
136+
if err != nil {
137+
assert.FailNow(t, fmt.Sprintf("Could not set bare_pdig_on_containers, got error: %v", err))
138+
}
139+
140+
err = data.Set("ignore_containers", []interface{}{
141+
"gimme", "fried", "chicken",
142+
})
143+
if err != nil {
144+
assert.FailNow(t, fmt.Sprintf("Could not set ignore_containers, got error: %v", err))
145+
}
146+
147+
err = data.Set("log_configuration", []interface{}{
148+
map[string]interface{}{
149+
"group": "gimme",
150+
"stream_prefix": "fried",
151+
"region": "chicken",
152+
},
153+
})
154+
if err != nil {
155+
assert.FailNow(t, fmt.Sprintf("Could not set log_configuration, got error: %v", err))
156+
}
157+
158+
// Expected vs actual
159+
expectedPatchOptions := &patchOptions{
160+
BarePdigOnContainers: []string{"gimme", "fried", "chicken"},
161+
IgnoreContainers: []string{"gimme", "fried", "chicken"},
162+
LogConfiguration: map[string]interface{}{
163+
"group": "gimme",
164+
"stream_prefix": "fried",
165+
"region": "chicken",
166+
},
167+
}
168+
actualPatchOptions := newPatchOptions(data)
169+
170+
if !reflect.DeepEqual(expectedPatchOptions, actualPatchOptions) {
171+
t.Errorf("patcConfigurations are not equal. Expected: %v, Actual: %v", expectedPatchOptions, actualPatchOptions)
172+
}
173+
}
174+
175+
func TestECStransformation(t *testing.T) {
176+
inputfile, err := os.ReadFile("testfiles/ECSinput.json")
177+
if err != nil {
178+
t.Fatalf("Cannot find testfiles/ECSinput.json")
179+
}
180+
83181
kiltConfig := &cfnpatcher.Configuration{
84182
Kilt: agentinoKiltDefinition,
85183
ImageAuthSecret: "image_auth_secret",
86184
OptIn: false,
87185
UseRepositoryHints: true,
88-
RecipeConfig: string(jsonConf),
186+
RecipeConfig: getKiltRecipe(t),
89187
}
90188

91-
patchedOutput, err := patchFargateTaskDefinition(context.Background(), string(inputfile), kiltConfig, nil, &testIgnoreContainers)
189+
patchOpts := &patchOptions{}
190+
191+
patchedOutput, err := patchFargateTaskDefinition(context.Background(), string(inputfile), kiltConfig, patchOpts)
92192
if err != nil {
93193
t.Fatalf("Cannot execute PatchFargateTaskDefinition : %v", err.Error())
94194
}
@@ -140,66 +240,97 @@ func TestECStransformation(t *testing.T) {
140240
assert.Equal(t, patchedContainerDefinitions[0].EntryPoint2, "")
141241
}
142242

143-
func TestTransform(t *testing.T) {
144-
for _, testName := range testContainerDefinitionFiles {
145-
t.Run(testName, func(t *testing.T) {
146-
jsonConfig, _ := json.Marshal(testKiltDefinition)
147-
kiltConfig := &cfnpatcher.Configuration{
148-
Kilt: agentinoKiltDefinition,
149-
ImageAuthSecret: "image_auth_secret",
150-
OptIn: false,
151-
UseRepositoryHints: true,
152-
RecipeConfig: string(jsonConfig),
153-
}
154-
155-
inputContainerDefinition, _ := os.ReadFile("testfiles/" + testName + ".json")
156-
patched, _ := patchFargateTaskDefinition(context.Background(), string(inputContainerDefinition), kiltConfig, nil, &testIgnoreContainers)
157-
expectedContainerDefinition, _ := os.ReadFile("testfiles/" + testName + "_expected.json")
158-
159-
sortAndCompare(t, expectedContainerDefinition, []byte(*patched))
160-
})
161-
}
162-
}
163-
164-
func TestLogGroup(t *testing.T) {
165-
jsonConfig, _ := json.Marshal(testKiltDefinition)
243+
func TestPatchFargateTaskDefinition(t *testing.T) {
244+
// Kilt Configuration, test invariant
166245
kiltConfig := &cfnpatcher.Configuration{
167246
Kilt: agentinoKiltDefinition,
168247
ImageAuthSecret: "image_auth_secret",
169248
OptIn: false,
170249
UseRepositoryHints: true,
171-
RecipeConfig: string(jsonConfig),
250+
RecipeConfig: getKiltRecipe(t),
172251
}
173252

174-
logConfig := map[string]interface{}{
175-
"group": "test_log_group",
176-
"stream_prefix": "test_prefix",
177-
"region": "test_region",
253+
// File readers
254+
readFile := func(fileName string) string {
255+
content, _ := os.ReadFile("testfiles/" + fileName + ".json")
256+
return string(content)
178257
}
179258

180-
inputContainerDefinition, _ := os.ReadFile("testfiles/fargate_log_group.json")
181-
patched, _ := patchFargateTaskDefinition(context.Background(), string(inputContainerDefinition), kiltConfig, logConfig, &testIgnoreContainers)
182-
expectedContainerDefinition, _ := os.ReadFile("testfiles/fargate_log_group_expected.json")
183-
184-
sortAndCompare(t, expectedContainerDefinition, []byte(*patched))
185-
}
186-
187-
func TestIgnoreContainers(t *testing.T) {
188-
jsonConfig, _ := json.Marshal(testKiltDefinition)
189-
kiltConfig := &cfnpatcher.Configuration{
190-
Kilt: agentinoKiltDefinition,
191-
ImageAuthSecret: "image_auth_secret",
192-
OptIn: false,
193-
UseRepositoryHints: true,
194-
RecipeConfig: string(jsonConfig),
259+
getContainerDefinitionOriginal := func(fileName string) string {
260+
return readFile(fileName)
195261
}
196262

197-
fileTemplate := "fargate_ignore_container_test"
198-
ignoreContainers := []string{"other", "another"}
199-
200-
inputContainerDefinition, _ := os.ReadFile("testfiles/" + fileTemplate + ".json")
201-
patched, _ := patchFargateTaskDefinition(context.Background(), string(inputContainerDefinition), kiltConfig, nil, &ignoreContainers)
202-
expectedContainerDefinition, _ := os.ReadFile("testfiles/" + fileTemplate + "_expected.json")
263+
getContainerDefinitionPatched := func(fileName string) string {
264+
return readFile(fileName + "_expected")
265+
}
203266

204-
sortAndCompare(t, expectedContainerDefinition, []byte(*patched))
267+
tests := []struct {
268+
testName string
269+
patchOpts *patchOptions
270+
}{
271+
{
272+
testName: `fargate_entrypoint_test`,
273+
patchOpts: &patchOptions{},
274+
},
275+
{
276+
testName: `fargate_env_test`,
277+
patchOpts: &patchOptions{},
278+
},
279+
{
280+
testName: `fargate_cmd_test`,
281+
patchOpts: &patchOptions{},
282+
},
283+
{
284+
testName: `fargate_linuxparameters_test`,
285+
patchOpts: &patchOptions{},
286+
},
287+
{
288+
testName: `fargate_combined_test`,
289+
patchOpts: &patchOptions{},
290+
},
291+
{
292+
testName: `fargate_volumesfrom_test`,
293+
patchOpts: &patchOptions{},
294+
},
295+
{
296+
testName: `fargate_field_case_test`,
297+
patchOpts: &patchOptions{},
298+
},
299+
{
300+
testName: `fargate_log_group`,
301+
patchOpts: &patchOptions{
302+
LogConfiguration: map[string]interface{}{
303+
"group": "test_log_group",
304+
"stream_prefix": "test_prefix",
305+
"region": "test_region",
306+
},
307+
},
308+
},
309+
{
310+
testName: `fargate_ignore_container_test`,
311+
patchOpts: &patchOptions{
312+
IgnoreContainers: []string{"other", "another"},
313+
},
314+
},
315+
{
316+
testName: `fargate_bare_pdig`,
317+
patchOpts: &patchOptions{
318+
BarePdigOnContainers: []string{"barePdig"},
319+
IgnoreContainers: []string{"skipped"},
320+
},
321+
},
322+
}
323+
for _, tc := range tests {
324+
t.Run(tc.testName, func(t *testing.T) {
325+
patched, err := patchFargateTaskDefinition(
326+
context.Background(),
327+
getContainerDefinitionOriginal(tc.testName),
328+
kiltConfig,
329+
tc.patchOpts)
330+
if err != nil {
331+
assert.FailNow(t, fmt.Sprintf("Could not patch task definition, got error: %v", err))
332+
}
333+
sortAndCompare(t, []byte(getContainerDefinitionPatched(tc.testName)), []byte(*patched))
334+
})
335+
}
205336
}

0 commit comments

Comments
 (0)