tetragon

Форк
0
/
manager_test.go 
421 строка · 12.8 Кб
1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright Authors of Tetragon
3

4
package sensors
5

6
import (
7
	"context"
8
	"errors"
9
	"fmt"
10
	"sync"
11
	"testing"
12
	"time"
13

14
	"github.com/cilium/tetragon/api/v1/tetragon"
15
	"github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1"
16
	"github.com/cilium/tetragon/pkg/policyfilter"
17
	"github.com/cilium/tetragon/pkg/sensors/program"
18
	"github.com/cilium/tetragon/pkg/tracingpolicy"
19

20
	slimv1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/apis/meta/v1"
21
	"github.com/stretchr/testify/assert"
22
	"github.com/stretchr/testify/require"
23
)
24

25
type dummyHandler struct {
26
	s SensorIface
27
	e error
28
}
29

30
func (d *dummyHandler) PolicyHandler(_ tracingpolicy.TracingPolicy, _ policyfilter.PolicyID) (SensorIface, error) {
31
	return d.s, d.e
32
}
33

34
// TestAddPolicy tests the addition of a policy with a dummy sensor
35
func TestAddPolicy(t *testing.T) {
36
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
37
	defer cancel()
38

39
	RegisterPolicyHandlerAtInit("dummy", &dummyHandler{s: &Sensor{Name: "dummy-sensor"}})
40
	t.Cleanup(func() {
41
		delete(registeredPolicyHandlers, "dummy")
42
	})
43

44
	policy := v1alpha1.TracingPolicy{}
45
	mgr, err := StartSensorManager("", nil)
46
	assert.NoError(t, err)
47
	t.Cleanup(func() {
48
		if err := mgr.StopSensorManager(ctx); err != nil {
49
			panic("failed to stop sensor manager")
50
		}
51
	})
52
	policy.ObjectMeta.Name = "test-policy"
53
	err = mgr.AddTracingPolicy(ctx, &policy)
54
	assert.NoError(t, err)
55
	l, err := mgr.ListSensors(ctx)
56
	assert.NoError(t, err)
57
	assert.Equal(t, []SensorStatus{{Name: "dummy-sensor", Enabled: true, Collection: "test-policy (object:0/) (type:/)"}}, *l)
58
}
59

60
// TestAddPolicies tests the addition of a policy with two dummy sensors
61
func TestAddPolicies(t *testing.T) {
62
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
63
	defer cancel()
64

65
	RegisterPolicyHandlerAtInit("dummy1", &dummyHandler{s: &Sensor{Name: "dummy-sensor1"}})
66
	RegisterPolicyHandlerAtInit("dummy2", &dummyHandler{s: &Sensor{Name: "dummy-sensor2"}})
67
	t.Cleanup(func() {
68
		delete(registeredPolicyHandlers, "dummy1")
69
		delete(registeredPolicyHandlers, "dummy2")
70
	})
71

72
	policy := v1alpha1.TracingPolicy{}
73
	mgr, err := StartSensorManager("", nil)
74
	assert.NoError(t, err)
75
	t.Cleanup(func() {
76
		if err := mgr.StopSensorManager(ctx); err != nil {
77
			panic("failed to stop sensor manager")
78
		}
79
	})
80
	policy.ObjectMeta.Name = "test-policy"
81
	err = mgr.AddTracingPolicy(ctx, &policy)
82
	assert.NoError(t, err)
83
	l, err := mgr.ListSensors(ctx)
84
	assert.NoError(t, err)
85
	assert.ElementsMatch(t, []SensorStatus{
86
		{Name: "dummy-sensor1", Enabled: true, Collection: "test-policy (object:0/) (type:/)"},
87
		{Name: "dummy-sensor2", Enabled: true, Collection: "test-policy (object:0/) (type:/)"},
88
	}, *l)
89
}
90

91
// TestAddPolicySpecError tests the addition of a policy where a spec fails to load
92
func TestAddPolicySpecError(t *testing.T) {
93
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
94
	defer cancel()
95

96
	RegisterPolicyHandlerAtInit("dummy", &dummyHandler{s: &Sensor{Name: "dummy-sensor"}})
97
	RegisterPolicyHandlerAtInit("spec-fail", &dummyHandler{e: errors.New("spec load is expected to fail: failed")})
98
	t.Cleanup(func() {
99
		delete(registeredPolicyHandlers, "dummy")
100
		delete(registeredPolicyHandlers, "spec-fail")
101
	})
102

103
	policy := v1alpha1.TracingPolicy{}
104
	mgr, err := StartSensorManager("", nil)
105
	assert.NoError(t, err)
106
	t.Cleanup(func() {
107
		if err := mgr.StopSensorManager(ctx); err != nil {
108
			panic("failed to stop sensor manager")
109
		}
110
	})
111
	policy.ObjectMeta.Name = "test-policy"
112
	err = mgr.AddTracingPolicy(ctx, &policy)
113
	assert.NotNil(t, err)
114
	t.Logf("got error (as expected): %s", err)
115
	l, err := mgr.ListSensors(ctx)
116
	assert.NoError(t, err)
117
	assert.Equal(t, []SensorStatus{}, *l)
118
}
119

120
// TestAddPolicyLoadError tests the addition of a policy where the sensor is expected to fail
121
func TestAddPolicyLoadError(t *testing.T) {
122
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
123
	defer cancel()
124

125
	RegisterPolicyHandlerAtInit("dummy", &dummyHandler{s: &Sensor{Name: "dummy-sensor"}})
126
	RegisterPolicyHandlerAtInit("load-fail", &dummyHandler{s: &Sensor{
127
		Name:  "dummy-sensor",
128
		Progs: []*program.Program{{Name: "bpf-program-that-does-not-exist"}},
129
	}})
130
	t.Cleanup(func() {
131
		delete(registeredPolicyHandlers, "dummy")
132
		delete(registeredPolicyHandlers, "load-fail")
133
	})
134

135
	policy := v1alpha1.TracingPolicy{}
136
	mgr, err := StartSensorManager("", nil)
137
	assert.NoError(t, err)
138
	t.Cleanup(func() {
139
		if err := mgr.StopSensorManager(ctx); err != nil {
140
			panic("failed to stop sensor manager")
141
		}
142
	})
143
	policy.ObjectMeta.Name = "test-policy"
144
	addError := mgr.AddTracingPolicy(ctx, &policy)
145
	assert.NotNil(t, addError)
146
	t.Logf("got error (as expected): %s", addError)
147

148
	l, err := mgr.ListTracingPolicies(ctx)
149
	assert.NoError(t, err)
150
	assert.Len(t, l.Policies, 1)
151
	assert.Equal(t, LoadErrorState.ToTetragonState(), l.Policies[0].State)
152
	assert.Equal(t, addError.Error(), l.Policies[0].Error)
153
}
154

155
func TestPolicyFilterDisabled(t *testing.T) {
156
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
157
	defer cancel()
158

159
	handler, err := newHandler(policyfilter.DisabledState(), newCollectionMap(), "")
160
	assert.NoError(t, err)
161
	mgr, err := startSensorManager(handler, handler.collections, nil)
162
	assert.NoError(t, err)
163
	defer mgr.StopSensorManager(ctx)
164

165
	policy := v1alpha1.TracingPolicy{}
166

167
	// normal policy should succeed
168
	policyName := "test-policy"
169
	policyNamespace := ""
170
	policy.ObjectMeta.Name = policyName
171
	err = mgr.AddTracingPolicy(ctx, &policy)
172
	require.NoError(t, err, fmt.Sprintf("Add tracing policy failed with error: %v", err))
173
	err = mgr.DeleteTracingPolicy(ctx, policyName, policyNamespace)
174
	require.NoError(t, err)
175
	err = mgr.AddTracingPolicy(ctx, &policy)
176
	require.NoError(t, err)
177
	err = mgr.DeleteTracingPolicy(ctx, policyName, policyNamespace)
178
	require.NoError(t, err)
179

180
	// namespaced policy with disabled state should fail
181
	namespacedPolicy := v1alpha1.TracingPolicyNamespaced{}
182
	policy.ObjectMeta.Name = policyName
183
	namespacedPolicy.ObjectMeta.Name = policyName
184
	namespacedPolicy.ObjectMeta.Namespace = "namespace"
185
	err = mgr.AddTracingPolicy(ctx, &namespacedPolicy)
186
	require.Error(t, err)
187

188
	// policy with pod selector should fail
189
	policy.Spec.PodSelector = &slimv1.LabelSelector{
190
		MatchExpressions: []slimv1.LabelSelectorRequirement{{
191
			Key:      "app",
192
			Operator: slimv1.LabelSelectorOpExists,
193
		}},
194
	}
195
	err = mgr.AddTracingPolicy(ctx, &policy)
196
	require.Error(t, err)
197
}
198

199
func TestPolicyStates(t *testing.T) {
200
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
201
	defer cancel()
202

203
	t.Run("LoadError", func(t *testing.T) {
204
		RegisterPolicyHandlerAtInit("load-fail", &dummyHandler{s: &Sensor{
205
			Name:  "dummy-sensor",
206
			Progs: []*program.Program{{Name: "bpf-program-that-does-not-exist"}},
207
		}})
208
		t.Cleanup(func() {
209
			delete(registeredPolicyHandlers, "load-fail")
210
		})
211

212
		policy := v1alpha1.TracingPolicy{}
213
		mgr, err := StartSensorManager("", nil)
214
		require.NoError(t, err)
215
		t.Cleanup(func() {
216
			if err := mgr.StopSensorManager(ctx); err != nil {
217
				panic("failed to stop sensor manager")
218
			}
219
		})
220
		policy.ObjectMeta.Name = "test-policy"
221
		addError := mgr.AddTracingPolicy(ctx, &policy)
222
		assert.NotNil(t, addError)
223

224
		l, err := mgr.ListTracingPolicies(ctx)
225
		assert.NoError(t, err)
226
		assert.Len(t, l.Policies, 1)
227
		assert.Equal(t, LoadErrorState.ToTetragonState(), l.Policies[0].State)
228
		assert.Equal(t, addError.Error(), l.Policies[0].Error)
229
	})
230

231
	t.Run("EnabledDisabled", func(t *testing.T) {
232
		RegisterPolicyHandlerAtInit("dummy", &dummyHandler{s: &Sensor{Name: "dummy-sensor"}})
233
		t.Cleanup(func() {
234
			delete(registeredPolicyHandlers, "dummy")
235
		})
236

237
		policy := v1alpha1.TracingPolicy{}
238
		mgr, err := StartSensorManager("", nil)
239
		require.NoError(t, err)
240
		t.Cleanup(func() {
241
			if err := mgr.StopSensorManager(ctx); err != nil {
242
				panic("failed to stop sensor manager")
243
			}
244
		})
245
		policy.ObjectMeta.Name = "test-policy"
246
		err = mgr.AddTracingPolicy(ctx, &policy)
247
		assert.NoError(t, err)
248

249
		l, err := mgr.ListTracingPolicies(ctx)
250
		assert.NoError(t, err)
251
		assert.Len(t, l.Policies, 1)
252
		assert.Equal(t, EnabledState.ToTetragonState(), l.Policies[0].State)
253

254
		err = mgr.DisableTracingPolicy(ctx, policy.ObjectMeta.Name, policy.Namespace)
255
		assert.NoError(t, err)
256
		l, err = mgr.ListTracingPolicies(ctx)
257
		assert.NoError(t, err)
258
		assert.Len(t, l.Policies, 1)
259
		assert.Equal(t, DisabledState.ToTetragonState(), l.Policies[0].State)
260
	})
261
}
262

263
// TestPolicyLoadErrorOverride tests the fact that you can add a TracingPolicy
264
// with the same name as an existing one if it's in a LoadError state
265
func TestPolicyLoadErrorOverride(t *testing.T) {
266
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
267
	defer cancel()
268

269
	RegisterPolicyHandlerAtInit("load-fail", &dummyHandler{s: &Sensor{
270
		Name:  "dummy-sensor",
271
		Progs: []*program.Program{{Name: "bpf-program-that-does-not-exist"}},
272
	}})
273
	t.Cleanup(func() {
274
		delete(registeredPolicyHandlers, "load-fail")
275
	})
276

277
	policy := v1alpha1.TracingPolicy{}
278
	mgr, err := StartSensorManager("", nil)
279
	require.NoError(t, err)
280
	t.Cleanup(func() {
281
		if err := mgr.StopSensorManager(ctx); err != nil {
282
			panic("failed to stop sensor manager")
283
		}
284
	})
285
	policy.ObjectMeta.Name = "test-policy"
286
	addError := mgr.AddTracingPolicy(ctx, &policy)
287
	assert.NotNil(t, addError)
288

289
	l, err := mgr.ListTracingPolicies(ctx)
290
	assert.NoError(t, err)
291
	assert.Len(t, l.Policies, 1)
292
	assert.Equal(t, LoadErrorState.ToTetragonState(), l.Policies[0].State)
293
	assert.Equal(t, addError.Error(), l.Policies[0].Error)
294

295
	// try to override the existing registered LoadError policy
296
	delete(registeredPolicyHandlers, "load-fail")
297
	RegisterPolicyHandlerAtInit("dummy", &dummyHandler{s: &Sensor{Name: "dummy-sensor"}})
298
	t.Cleanup(func() {
299
		delete(registeredPolicyHandlers, "dummy")
300
	})
301
	addError = mgr.AddTracingPolicy(ctx, &policy)
302
	assert.NoError(t, addError)
303

304
	l, err = mgr.ListTracingPolicies(ctx)
305
	assert.NoError(t, err)
306
	assert.Len(t, l.Policies, 1)
307
	assert.Equal(t, EnabledState.ToTetragonState(), l.Policies[0].State)
308
}
309

310
func TestPolicyListingWhileLoadUnload(t *testing.T) {
311
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
312
	defer cancel()
313

314
	polName := "test-policy"
315
	testSensor := makeTestDelayedSensor(t)
316

317
	mgr, err := StartSensorManager("", nil)
318
	require.NoError(t, err)
319
	t.Cleanup(func() {
320
		if err := mgr.StopSensorManager(ctx); err != nil {
321
			panic("failed to stop sensor manager")
322
		}
323
	})
324

325
	checkPolicy := func(t *testing.T, statuses []*tetragon.TracingPolicyStatus, state tetragon.TracingPolicyState) {
326
		require.Equal(t, 1, len(statuses))
327
		pol := statuses[0]
328
		require.Equal(t, pol.Name, polName)
329
		require.Equal(t, pol.State, state)
330
	}
331

332
	var wg sync.WaitGroup
333

334
	wg.Add(1)
335
	go func() {
336
		// wait until at least one policy shows up, verify that it's in loading state and
337
		// unblock the loading of the policy
338
		for {
339
			l, err := mgr.ListTracingPolicies(ctx)
340
			require.NoError(t, err)
341
			if len(l.Policies) > 0 {
342
				checkPolicy(t, l.Policies, tetragon.TracingPolicyState_TP_STATE_LOADING)
343
				testSensor.unblock(t)
344
				break
345
			}
346
			time.Sleep(1 * time.Millisecond)
347
		}
348
		wg.Done()
349
	}()
350

351
	t.Log("adding policy")
352
	policy := v1alpha1.TracingPolicy{}
353
	policy.ObjectMeta.Name = polName
354
	err = mgr.AddTracingPolicy(ctx, &policy)
355
	require.NoError(t, err)
356
	wg.Wait()
357

358
	// check that policy is now enabled
359
	l, err := mgr.ListTracingPolicies(ctx)
360
	require.NoError(t, err)
361
	checkPolicy(t, l.Policies, tetragon.TracingPolicyState_TP_STATE_ENABLED)
362

363
	wg.Add(1)
364
	go func() {
365
		// wait until at least one policy shows up, verify that it's in unloading state and
366
		// unblock the unloading of the policy
367
		for {
368
			l, err := mgr.ListTracingPolicies(ctx)
369
			require.NoError(t, err)
370
			require.Equal(t, len(l.Policies), 1)
371
			if l.Policies[0].State == tetragon.TracingPolicyState_TP_STATE_UNLOADING {
372
				testSensor.unblock(t)
373
				break
374
			}
375
			time.Sleep(1 * time.Millisecond)
376
		}
377
		wg.Done()
378
	}()
379

380
	t.Log("disabling policy")
381
	err = mgr.DisableTracingPolicy(ctx, polName, "")
382
	require.NoError(t, err)
383
	wg.Wait()
384

385
	// check that policy is now disabled
386
	l, err = mgr.ListTracingPolicies(ctx)
387
	require.NoError(t, err)
388
	checkPolicy(t, l.Policies, tetragon.TracingPolicyState_TP_STATE_DISABLED)
389

390
	wg.Add(1)
391
	go func() {
392
		for {
393
			l, err := mgr.ListTracingPolicies(ctx)
394
			require.NoError(t, err)
395
			require.Equal(t, len(l.Policies), 1, "policies:", l.Policies)
396
			if l.Policies[0].State == tetragon.TracingPolicyState_TP_STATE_LOADING {
397
				testSensor.unblock(t)
398
				break
399
			}
400
			time.Sleep(1000 * time.Millisecond)
401
		}
402
		wg.Done()
403
	}()
404

405
	t.Log("re-enabling policy")
406
	err = mgr.EnableTracingPolicy(ctx, polName, "")
407
	require.NoError(t, err)
408
	wg.Wait()
409

410
	// check that policy is now diabled
411
	l, err = mgr.ListTracingPolicies(ctx)
412
	require.NoError(t, err)
413
	checkPolicy(t, l.Policies, tetragon.TracingPolicyState_TP_STATE_ENABLED)
414

415
	t.Log("deleting policy")
416
	err = mgr.DeleteTracingPolicy(ctx, polName, "")
417
	require.NoError(t, err)
418
	l, err = mgr.ListTracingPolicies(ctx)
419
	require.NoError(t, err)
420
	require.Equal(t, 0, len(l.Policies))
421
}
422

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.