From 85c44b6475f48351a462d0bc1c67d9f489e33a22 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 23 Mar 2024 20:03:25 +0000 Subject: [PATCH 01/17] tetragon: Add throttle message Adding throttle message that is going to be triggered when the cgroup cross the rate limit or comes back. message ProcessThrottle { // Throttle type ThrottleType type = 1; // Cgroup name string cgroup = 2; } Signed-off-by: Jiri Olsa --- api/v1/README.md | 33 ++ .../codegen/eventchecker/eventchecker.pb.go | 143 +++++++ .../codegen/eventchecker/yaml/yaml.pb.go | 9 + api/v1/tetragon/codegen/helpers/helpers.pb.go | 2 + api/v1/tetragon/events.pb.go | 396 ++++++++++++------ api/v1/tetragon/events.pb.json.go | 16 + api/v1/tetragon/events.proto | 15 + api/v1/tetragon/types.pb.go | 10 + .../tetragon/api/v1/tetragon/events.pb.go | 396 ++++++++++++------ .../api/v1/tetragon/events.pb.json.go | 16 + .../tetragon/api/v1/tetragon/events.proto | 15 + .../tetragon/api/v1/tetragon/types.pb.go | 10 + docs/content/en/docs/reference/grpc-api.md | 21 + docs/content/en/docs/reference/metrics.md | 10 +- .../codegen/eventchecker/eventchecker.pb.go | 143 +++++++ .../codegen/eventchecker/yaml/yaml.pb.go | 9 + .../v1/tetragon/codegen/helpers/helpers.pb.go | 2 + .../tetragon/api/v1/tetragon/events.pb.go | 396 ++++++++++++------ .../api/v1/tetragon/events.pb.json.go | 16 + .../tetragon/api/v1/tetragon/events.proto | 15 + .../tetragon/api/v1/tetragon/types.pb.go | 10 + 21 files changed, 1318 insertions(+), 365 deletions(-) diff --git a/api/v1/README.md b/api/v1/README.md index 9c58ae15488..e084ed388e9 100644 --- a/api/v1/README.md +++ b/api/v1/README.md @@ -67,11 +67,13 @@ - [Filter](#tetragon-Filter) - [GetEventsRequest](#tetragon-GetEventsRequest) - [GetEventsResponse](#tetragon-GetEventsResponse) + - [ProcessThrottle](#tetragon-ProcessThrottle) - [RateLimitInfo](#tetragon-RateLimitInfo) - [RedactionFilter](#tetragon-RedactionFilter) - [EventType](#tetragon-EventType) - [FieldFilterAction](#tetragon-FieldFilterAction) + - [ThrottleType](#tetragon-ThrottleType) - [tetragon/stack.proto](#tetragon_stack-proto) - [StackAddress](#tetragon-StackAddress) @@ -1271,6 +1273,7 @@ Capability set to filter over. NOTE: you may specify only ONE set here. | process_tracepoint | [ProcessTracepoint](#tetragon-ProcessTracepoint) | | ProcessTracepoint contains information about the pre-defined tracepoint and the process that invoked them. | | process_loader | [ProcessLoader](#tetragon-ProcessLoader) | | | | process_uprobe | [ProcessUprobe](#tetragon-ProcessUprobe) | | | +| process_throttle | [ProcessThrottle](#tetragon-ProcessThrottle) | | | | test | [Test](#tetragon-Test) | | | | rate_limit_info | [RateLimitInfo](#tetragon-RateLimitInfo) | | | | node_name | [string](#string) | | Name of the node where this event was observed. | @@ -1282,6 +1285,22 @@ Capability set to filter over. NOTE: you may specify only ONE set here. + + +### ProcessThrottle + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| type | [ThrottleType](#tetragon-ThrottleType) | | Throttle type | +| cgroup | [string](#string) | | Cgroup name | + + + + + + ### RateLimitInfo @@ -1333,6 +1352,7 @@ GetEventsResponse event oneof. | PROCESS_TRACEPOINT | 10 | | | PROCESS_LOADER | 11 | | | PROCESS_UPROBE | 12 | | +| PROCESS_THROTTLE | 27 | | | TEST | 40000 | | | RATE_LIMIT_INFO | 40001 | | @@ -1349,6 +1369,19 @@ Determines the behavior of a field filter | EXCLUDE | 1 | | + + + +### ThrottleType + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| THROTTLE_UNKNOWN | 0 | | +| THROTTLE_START | 1 | | +| THROTTLE_STOP | 2 | | + + diff --git a/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go b/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go index 2213e2449d2..64c0f66c8b7 100644 --- a/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go +++ b/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go @@ -280,6 +280,8 @@ func CheckerFromEvent(event Event) (EventChecker, error) { return NewProcessLoaderChecker("").FromProcessLoader(ev), nil case *tetragon.RateLimitInfo: return NewRateLimitInfoChecker("").FromRateLimitInfo(ev), nil + case *tetragon.ProcessThrottle: + return NewProcessThrottleChecker("").FromProcessThrottle(ev), nil default: return nil, fmt.Errorf("Unhandled event type %T", event) @@ -340,6 +342,8 @@ func EventFromResponse(response *tetragon.GetEventsResponse) (Event, error) { return ev.ProcessLoader, nil case *tetragon.GetEventsResponse_RateLimitInfo: return ev.RateLimitInfo, nil + case *tetragon.GetEventsResponse_ProcessThrottle: + return ev.ProcessThrottle, nil default: return nil, fmt.Errorf("Unknown event type %T", response.Event) @@ -1959,6 +1963,93 @@ func (checker *RateLimitInfoChecker) FromRateLimitInfo(event *tetragon.RateLimit return checker } +// ProcessThrottleChecker implements a checker struct to check a ProcessThrottle event +type ProcessThrottleChecker struct { + CheckerName string `json:"checkerName"` + Type *ThrottleTypeChecker `json:"type,omitempty"` + Cgroup *stringmatcher.StringMatcher `json:"cgroup,omitempty"` +} + +// CheckEvent checks a single event and implements the EventChecker interface +func (checker *ProcessThrottleChecker) CheckEvent(event Event) error { + if ev, ok := event.(*tetragon.ProcessThrottle); ok { + return checker.Check(ev) + } + return fmt.Errorf("%s: %T is not a ProcessThrottle event", CheckerLogPrefix(checker), event) +} + +// CheckResponse checks a single gRPC response and implements the EventChecker interface +func (checker *ProcessThrottleChecker) CheckResponse(response *tetragon.GetEventsResponse) error { + event, err := EventFromResponse(response) + if err != nil { + return err + } + return checker.CheckEvent(event) +} + +// NewProcessThrottleChecker creates a new ProcessThrottleChecker +func NewProcessThrottleChecker(name string) *ProcessThrottleChecker { + return &ProcessThrottleChecker{CheckerName: name} +} + +// Get the name associated with the checker +func (checker *ProcessThrottleChecker) GetCheckerName() string { + return checker.CheckerName +} + +// Get the type of the checker as a string +func (checker *ProcessThrottleChecker) GetCheckerType() string { + return "ProcessThrottleChecker" +} + +// Check checks a ProcessThrottle event +func (checker *ProcessThrottleChecker) Check(event *tetragon.ProcessThrottle) error { + if event == nil { + return fmt.Errorf("%s: ProcessThrottle event is nil", CheckerLogPrefix(checker)) + } + + fieldChecks := func() error { + if checker.Type != nil { + if err := checker.Type.Check(&event.Type); err != nil { + return fmt.Errorf("Type check failed: %w", err) + } + } + if checker.Cgroup != nil { + if err := checker.Cgroup.Match(event.Cgroup); err != nil { + return fmt.Errorf("Cgroup check failed: %w", err) + } + } + return nil + } + if err := fieldChecks(); err != nil { + return fmt.Errorf("%s: %w", CheckerLogPrefix(checker), err) + } + return nil +} + +// WithType adds a Type check to the ProcessThrottleChecker +func (checker *ProcessThrottleChecker) WithType(check tetragon.ThrottleType) *ProcessThrottleChecker { + wrappedCheck := ThrottleTypeChecker(check) + checker.Type = &wrappedCheck + return checker +} + +// WithCgroup adds a Cgroup check to the ProcessThrottleChecker +func (checker *ProcessThrottleChecker) WithCgroup(check *stringmatcher.StringMatcher) *ProcessThrottleChecker { + checker.Cgroup = check + return checker +} + +//FromProcessThrottle populates the ProcessThrottleChecker using data from a ProcessThrottle event +func (checker *ProcessThrottleChecker) FromProcessThrottle(event *tetragon.ProcessThrottle) *ProcessThrottleChecker { + if event == nil { + return checker + } + checker.Type = NewThrottleTypeChecker(event.Type) + checker.Cgroup = stringmatcher.Full(event.Cgroup) + return checker +} + // ImageChecker implements a checker struct to check a Image field type ImageChecker struct { Id *stringmatcher.StringMatcher `json:"id,omitempty"` @@ -6411,3 +6502,55 @@ func (enum *TaintedBitsTypeChecker) Check(val *tetragon.TaintedBitsType) error { } return nil } + +// ThrottleTypeChecker checks a tetragon.ThrottleType +type ThrottleTypeChecker tetragon.ThrottleType + +// MarshalJSON implements json.Marshaler interface +func (enum ThrottleTypeChecker) MarshalJSON() ([]byte, error) { + if name, ok := tetragon.ThrottleType_name[int32(enum)]; ok { + name = strings.TrimPrefix(name, "THROTTLE_") + return json.Marshal(name) + } + + return nil, fmt.Errorf("Unknown ThrottleType %d", enum) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (enum *ThrottleTypeChecker) UnmarshalJSON(b []byte) error { + var str string + if err := yaml.UnmarshalStrict(b, &str); err != nil { + return err + } + + // Convert to uppercase if not already + str = strings.ToUpper(str) + + // Look up the value from the enum values map + if n, ok := tetragon.ThrottleType_value[str]; ok { + *enum = ThrottleTypeChecker(n) + } else if n, ok := tetragon.ThrottleType_value["THROTTLE_"+str]; ok { + *enum = ThrottleTypeChecker(n) + } else { + return fmt.Errorf("Unknown ThrottleType %s", str) + } + + return nil +} + +// NewThrottleTypeChecker creates a new ThrottleTypeChecker +func NewThrottleTypeChecker(val tetragon.ThrottleType) *ThrottleTypeChecker { + enum := ThrottleTypeChecker(val) + return &enum +} + +// Check checks a ThrottleType against the checker +func (enum *ThrottleTypeChecker) Check(val *tetragon.ThrottleType) error { + if val == nil { + return fmt.Errorf("ThrottleTypeChecker: ThrottleType is nil and does not match expected value %s", tetragon.ThrottleType(*enum)) + } + if *enum != ThrottleTypeChecker(*val) { + return fmt.Errorf("ThrottleTypeChecker: ThrottleType has value %s which does not match expected value %s", (*val), tetragon.ThrottleType(*enum)) + } + return nil +} diff --git a/api/v1/tetragon/codegen/eventchecker/yaml/yaml.pb.go b/api/v1/tetragon/codegen/eventchecker/yaml/yaml.pb.go index 81f7e977b93..f3ff5347a95 100644 --- a/api/v1/tetragon/codegen/eventchecker/yaml/yaml.pb.go +++ b/api/v1/tetragon/codegen/eventchecker/yaml/yaml.pb.go @@ -148,6 +148,7 @@ type eventCheckerHelper struct { Test *eventchecker.TestChecker `json:"test,omitempty"` ProcessLoader *eventchecker.ProcessLoaderChecker `json:"loader,omitempty"` RateLimitInfo *eventchecker.RateLimitInfoChecker `json:"rateLimitInfo,omitempty"` + ProcessThrottle *eventchecker.ProcessThrottleChecker `json:"throttle,omitempty"` } // EventChecker is a wrapper around the EventChecker interface to help unmarshaling @@ -210,6 +211,12 @@ func (checker *EventChecker) UnmarshalJSON(b []byte) error { } eventChecker = helper.RateLimitInfo } + if helper.ProcessThrottle != nil { + if eventChecker != nil { + return fmt.Errorf("EventChecker: cannot define more than one checker, got %T but already had %T", helper.ProcessThrottle, eventChecker) + } + eventChecker = helper.ProcessThrottle + } checker.EventChecker = eventChecker return nil } @@ -234,6 +241,8 @@ func (checker EventChecker) MarshalJSON() ([]byte, error) { helper.ProcessLoader = c case *eventchecker.RateLimitInfoChecker: helper.RateLimitInfo = c + case *eventchecker.ProcessThrottleChecker: + helper.ProcessThrottle = c default: return nil, fmt.Errorf("EventChecker: unknown checker type %T", c) } diff --git a/api/v1/tetragon/codegen/helpers/helpers.pb.go b/api/v1/tetragon/codegen/helpers/helpers.pb.go index 4c51ffae860..55f80b413ef 100644 --- a/api/v1/tetragon/codegen/helpers/helpers.pb.go +++ b/api/v1/tetragon/codegen/helpers/helpers.pb.go @@ -34,6 +34,8 @@ func ResponseTypeString(response *tetragon.GetEventsResponse) (string, error) { return tetragon.EventType_PROCESS_LOADER.String(), nil case *tetragon.GetEventsResponse_ProcessUprobe: return tetragon.EventType_PROCESS_UPROBE.String(), nil + case *tetragon.GetEventsResponse_ProcessThrottle: + return tetragon.EventType_PROCESS_THROTTLE.String(), nil case *tetragon.GetEventsResponse_Test: return tetragon.EventType_TEST.String(), nil case *tetragon.GetEventsResponse_RateLimitInfo: diff --git a/api/v1/tetragon/events.pb.go b/api/v1/tetragon/events.pb.go index d0755844e13..f11dc36ba6c 100644 --- a/api/v1/tetragon/events.pb.go +++ b/api/v1/tetragon/events.pb.go @@ -41,6 +41,7 @@ const ( EventType_PROCESS_TRACEPOINT EventType = 10 EventType_PROCESS_LOADER EventType = 11 EventType_PROCESS_UPROBE EventType = 12 + EventType_PROCESS_THROTTLE EventType = 27 EventType_TEST EventType = 40000 EventType_RATE_LIMIT_INFO EventType = 40001 ) @@ -55,6 +56,7 @@ var ( 10: "PROCESS_TRACEPOINT", 11: "PROCESS_LOADER", 12: "PROCESS_UPROBE", + 27: "PROCESS_THROTTLE", 40000: "TEST", 40001: "RATE_LIMIT_INFO", } @@ -66,6 +68,7 @@ var ( "PROCESS_TRACEPOINT": 10, "PROCESS_LOADER": 11, "PROCESS_UPROBE": 12, + "PROCESS_THROTTLE": 27, "TEST": 40000, "RATE_LIMIT_INFO": 40001, } @@ -145,6 +148,55 @@ func (FieldFilterAction) EnumDescriptor() ([]byte, []int) { return file_tetragon_events_proto_rawDescGZIP(), []int{1} } +type ThrottleType int32 + +const ( + ThrottleType_THROTTLE_UNKNOWN ThrottleType = 0 + ThrottleType_THROTTLE_START ThrottleType = 1 + ThrottleType_THROTTLE_STOP ThrottleType = 2 +) + +// Enum value maps for ThrottleType. +var ( + ThrottleType_name = map[int32]string{ + 0: "THROTTLE_UNKNOWN", + 1: "THROTTLE_START", + 2: "THROTTLE_STOP", + } + ThrottleType_value = map[string]int32{ + "THROTTLE_UNKNOWN": 0, + "THROTTLE_START": 1, + "THROTTLE_STOP": 2, + } +) + +func (x ThrottleType) Enum() *ThrottleType { + p := new(ThrottleType) + *p = x + return p +} + +func (x ThrottleType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ThrottleType) Descriptor() protoreflect.EnumDescriptor { + return file_tetragon_events_proto_enumTypes[2].Descriptor() +} + +func (ThrottleType) Type() protoreflect.EnumType { + return &file_tetragon_events_proto_enumTypes[2] +} + +func (x ThrottleType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ThrottleType.Descriptor instead. +func (ThrottleType) EnumDescriptor() ([]byte, []int) { + return file_tetragon_events_proto_rawDescGZIP(), []int{2} +} + type Filter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -818,6 +870,63 @@ func (x *RateLimitInfo) GetNumberOfDroppedProcessEvents() uint64 { return 0 } +type ProcessThrottle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Throttle type + Type ThrottleType `protobuf:"varint,1,opt,name=type,proto3,enum=tetragon.ThrottleType" json:"type,omitempty"` + // Cgroup name + Cgroup string `protobuf:"bytes,2,opt,name=cgroup,proto3" json:"cgroup,omitempty"` +} + +func (x *ProcessThrottle) Reset() { + *x = ProcessThrottle{} + if protoimpl.UnsafeEnabled { + mi := &file_tetragon_events_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProcessThrottle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcessThrottle) ProtoMessage() {} + +func (x *ProcessThrottle) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_events_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProcessThrottle.ProtoReflect.Descriptor instead. +func (*ProcessThrottle) Descriptor() ([]byte, []int) { + return file_tetragon_events_proto_rawDescGZIP(), []int{9} +} + +func (x *ProcessThrottle) GetType() ThrottleType { + if x != nil { + return x.Type + } + return ThrottleType_THROTTLE_UNKNOWN +} + +func (x *ProcessThrottle) GetCgroup() string { + if x != nil { + return x.Cgroup + } + return "" +} + type GetEventsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -835,6 +944,7 @@ type GetEventsResponse struct { // *GetEventsResponse_ProcessTracepoint // *GetEventsResponse_ProcessLoader // *GetEventsResponse_ProcessUprobe + // *GetEventsResponse_ProcessThrottle // *GetEventsResponse_Test // *GetEventsResponse_RateLimitInfo Event isGetEventsResponse_Event `protobuf_oneof:"event"` @@ -852,7 +962,7 @@ type GetEventsResponse struct { func (x *GetEventsResponse) Reset() { *x = GetEventsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_tetragon_events_proto_msgTypes[9] + mi := &file_tetragon_events_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -865,7 +975,7 @@ func (x *GetEventsResponse) String() string { func (*GetEventsResponse) ProtoMessage() {} func (x *GetEventsResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_events_proto_msgTypes[9] + mi := &file_tetragon_events_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -878,7 +988,7 @@ func (x *GetEventsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetEventsResponse.ProtoReflect.Descriptor instead. func (*GetEventsResponse) Descriptor() ([]byte, []int) { - return file_tetragon_events_proto_rawDescGZIP(), []int{9} + return file_tetragon_events_proto_rawDescGZIP(), []int{10} } func (m *GetEventsResponse) GetEvent() isGetEventsResponse_Event { @@ -930,6 +1040,13 @@ func (x *GetEventsResponse) GetProcessUprobe() *ProcessUprobe { return nil } +func (x *GetEventsResponse) GetProcessThrottle() *ProcessThrottle { + if x, ok := x.GetEvent().(*GetEventsResponse_ProcessThrottle); ok { + return x.ProcessThrottle + } + return nil +} + func (x *GetEventsResponse) GetTest() *Test { if x, ok := x.GetEvent().(*GetEventsResponse_Test); ok { return x.Test @@ -1000,6 +1117,10 @@ type GetEventsResponse_ProcessUprobe struct { ProcessUprobe *ProcessUprobe `protobuf:"bytes,12,opt,name=process_uprobe,json=processUprobe,proto3,oneof"` } +type GetEventsResponse_ProcessThrottle struct { + ProcessThrottle *ProcessThrottle `protobuf:"bytes,27,opt,name=process_throttle,json=processThrottle,proto3,oneof"` +} + type GetEventsResponse_Test struct { Test *Test `protobuf:"bytes,40000,opt,name=test,proto3,oneof"` } @@ -1020,6 +1141,8 @@ func (*GetEventsResponse_ProcessLoader) isGetEventsResponse_Event() {} func (*GetEventsResponse_ProcessUprobe) isGetEventsResponse_Event() {} +func (*GetEventsResponse_ProcessThrottle) isGetEventsResponse_Event() {} + func (*GetEventsResponse_Test) isGetEventsResponse_Event() {} func (*GetEventsResponse_RateLimitInfo) isGetEventsResponse_Event() {} @@ -1146,64 +1269,80 @@ var file_tetragon_events_proto_rawDesc = []byte{ 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1c, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x22, 0xab, 0x05, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, - 0x69, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, - 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x12, 0x4c, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x61, - 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, - 0x65, 0x72, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, - 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0xc0, 0xb8, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x54, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, - 0x0f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0xc1, 0xb8, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0xe8, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x2f, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, - 0x65, 0x12, 0x45, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x2a, 0xb1, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, - 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, - 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x10, 0x05, 0x12, 0x12, - 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, - 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x52, - 0x41, 0x43, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, - 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x12, - 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x55, 0x50, 0x52, 0x4f, 0x42, 0x45, - 0x10, 0x0c, 0x12, 0x0a, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, 0xc0, 0xb8, 0x02, 0x12, 0x15, - 0x0a, 0x0f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x49, 0x4e, 0x46, - 0x4f, 0x10, 0xc1, 0xb8, 0x02, 0x2a, 0x2d, 0x0a, 0x11, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, - 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x43, 0x4c, 0x55, - 0x44, 0x45, 0x10, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x73, 0x22, 0x55, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xf3, 0x05, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x65, 0x63, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x48, 0x00, 0x52, + 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x0c, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x4c, 0x0a, 0x12, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, + 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x46, 0x0a, 0x10, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x65, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0xc0, 0xb8, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x54, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x0f, + 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0xc1, 0xb8, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x48, 0x00, 0x52, 0x0d, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0xe8, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x2f, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, + 0x12, 0x45, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x2a, 0xc7, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, + 0x0a, 0x05, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, + 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, + 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x10, 0x05, 0x12, 0x12, 0x0a, + 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, + 0x09, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x52, 0x41, + 0x43, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, + 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x12, 0x0a, + 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x55, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, + 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, 0x52, + 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x1b, 0x12, 0x0a, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, + 0xc0, 0xb8, 0x02, 0x12, 0x15, 0x0a, 0x0f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, + 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0xc1, 0xb8, 0x02, 0x2a, 0x2d, 0x0a, 0x11, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, + 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x01, 0x2a, 0x4b, 0x0a, 0x0c, 0x54, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x48, 0x52, + 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, + 0x12, 0x0a, 0x0e, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, + 0x54, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, + 0x53, 0x54, 0x4f, 0x50, 0x10, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1218,70 +1357,74 @@ func file_tetragon_events_proto_rawDescGZIP() []byte { return file_tetragon_events_proto_rawDescData } -var file_tetragon_events_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_tetragon_events_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_tetragon_events_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_tetragon_events_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_tetragon_events_proto_goTypes = []interface{}{ (EventType)(0), // 0: tetragon.EventType (FieldFilterAction)(0), // 1: tetragon.FieldFilterAction - (*Filter)(nil), // 2: tetragon.Filter - (*CapFilter)(nil), // 3: tetragon.CapFilter - (*CapFilterSet)(nil), // 4: tetragon.CapFilterSet - (*RedactionFilter)(nil), // 5: tetragon.RedactionFilter - (*FieldFilter)(nil), // 6: tetragon.FieldFilter - (*GetEventsRequest)(nil), // 7: tetragon.GetEventsRequest - (*AggregationOptions)(nil), // 8: tetragon.AggregationOptions - (*AggregationInfo)(nil), // 9: tetragon.AggregationInfo - (*RateLimitInfo)(nil), // 10: tetragon.RateLimitInfo - (*GetEventsResponse)(nil), // 11: tetragon.GetEventsResponse - (*wrapperspb.BoolValue)(nil), // 12: google.protobuf.BoolValue - (CapabilitiesType)(0), // 13: tetragon.CapabilitiesType - (*fieldmaskpb.FieldMask)(nil), // 14: google.protobuf.FieldMask - (*durationpb.Duration)(nil), // 15: google.protobuf.Duration - (*ProcessExec)(nil), // 16: tetragon.ProcessExec - (*ProcessExit)(nil), // 17: tetragon.ProcessExit - (*ProcessKprobe)(nil), // 18: tetragon.ProcessKprobe - (*ProcessTracepoint)(nil), // 19: tetragon.ProcessTracepoint - (*ProcessLoader)(nil), // 20: tetragon.ProcessLoader - (*ProcessUprobe)(nil), // 21: tetragon.ProcessUprobe - (*Test)(nil), // 22: tetragon.Test - (*timestamppb.Timestamp)(nil), // 23: google.protobuf.Timestamp + (ThrottleType)(0), // 2: tetragon.ThrottleType + (*Filter)(nil), // 3: tetragon.Filter + (*CapFilter)(nil), // 4: tetragon.CapFilter + (*CapFilterSet)(nil), // 5: tetragon.CapFilterSet + (*RedactionFilter)(nil), // 6: tetragon.RedactionFilter + (*FieldFilter)(nil), // 7: tetragon.FieldFilter + (*GetEventsRequest)(nil), // 8: tetragon.GetEventsRequest + (*AggregationOptions)(nil), // 9: tetragon.AggregationOptions + (*AggregationInfo)(nil), // 10: tetragon.AggregationInfo + (*RateLimitInfo)(nil), // 11: tetragon.RateLimitInfo + (*ProcessThrottle)(nil), // 12: tetragon.ProcessThrottle + (*GetEventsResponse)(nil), // 13: tetragon.GetEventsResponse + (*wrapperspb.BoolValue)(nil), // 14: google.protobuf.BoolValue + (CapabilitiesType)(0), // 15: tetragon.CapabilitiesType + (*fieldmaskpb.FieldMask)(nil), // 16: google.protobuf.FieldMask + (*durationpb.Duration)(nil), // 17: google.protobuf.Duration + (*ProcessExec)(nil), // 18: tetragon.ProcessExec + (*ProcessExit)(nil), // 19: tetragon.ProcessExit + (*ProcessKprobe)(nil), // 20: tetragon.ProcessKprobe + (*ProcessTracepoint)(nil), // 21: tetragon.ProcessTracepoint + (*ProcessLoader)(nil), // 22: tetragon.ProcessLoader + (*ProcessUprobe)(nil), // 23: tetragon.ProcessUprobe + (*Test)(nil), // 24: tetragon.Test + (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp } var file_tetragon_events_proto_depIdxs = []int32{ - 12, // 0: tetragon.Filter.health_check:type_name -> google.protobuf.BoolValue + 14, // 0: tetragon.Filter.health_check:type_name -> google.protobuf.BoolValue 0, // 1: tetragon.Filter.event_set:type_name -> tetragon.EventType - 3, // 2: tetragon.Filter.capabilities:type_name -> tetragon.CapFilter - 4, // 3: tetragon.CapFilter.permitted:type_name -> tetragon.CapFilterSet - 4, // 4: tetragon.CapFilter.effective:type_name -> tetragon.CapFilterSet - 4, // 5: tetragon.CapFilter.inheritable:type_name -> tetragon.CapFilterSet - 13, // 6: tetragon.CapFilterSet.any:type_name -> tetragon.CapabilitiesType - 13, // 7: tetragon.CapFilterSet.all:type_name -> tetragon.CapabilitiesType - 13, // 8: tetragon.CapFilterSet.exactly:type_name -> tetragon.CapabilitiesType - 13, // 9: tetragon.CapFilterSet.none:type_name -> tetragon.CapabilitiesType - 2, // 10: tetragon.RedactionFilter.match:type_name -> tetragon.Filter + 4, // 2: tetragon.Filter.capabilities:type_name -> tetragon.CapFilter + 5, // 3: tetragon.CapFilter.permitted:type_name -> tetragon.CapFilterSet + 5, // 4: tetragon.CapFilter.effective:type_name -> tetragon.CapFilterSet + 5, // 5: tetragon.CapFilter.inheritable:type_name -> tetragon.CapFilterSet + 15, // 6: tetragon.CapFilterSet.any:type_name -> tetragon.CapabilitiesType + 15, // 7: tetragon.CapFilterSet.all:type_name -> tetragon.CapabilitiesType + 15, // 8: tetragon.CapFilterSet.exactly:type_name -> tetragon.CapabilitiesType + 15, // 9: tetragon.CapFilterSet.none:type_name -> tetragon.CapabilitiesType + 3, // 10: tetragon.RedactionFilter.match:type_name -> tetragon.Filter 0, // 11: tetragon.FieldFilter.event_set:type_name -> tetragon.EventType - 14, // 12: tetragon.FieldFilter.fields:type_name -> google.protobuf.FieldMask + 16, // 12: tetragon.FieldFilter.fields:type_name -> google.protobuf.FieldMask 1, // 13: tetragon.FieldFilter.action:type_name -> tetragon.FieldFilterAction - 12, // 14: tetragon.FieldFilter.invert_event_set:type_name -> google.protobuf.BoolValue - 2, // 15: tetragon.GetEventsRequest.allow_list:type_name -> tetragon.Filter - 2, // 16: tetragon.GetEventsRequest.deny_list:type_name -> tetragon.Filter - 8, // 17: tetragon.GetEventsRequest.aggregation_options:type_name -> tetragon.AggregationOptions - 6, // 18: tetragon.GetEventsRequest.field_filters:type_name -> tetragon.FieldFilter - 15, // 19: tetragon.AggregationOptions.window_size:type_name -> google.protobuf.Duration - 16, // 20: tetragon.GetEventsResponse.process_exec:type_name -> tetragon.ProcessExec - 17, // 21: tetragon.GetEventsResponse.process_exit:type_name -> tetragon.ProcessExit - 18, // 22: tetragon.GetEventsResponse.process_kprobe:type_name -> tetragon.ProcessKprobe - 19, // 23: tetragon.GetEventsResponse.process_tracepoint:type_name -> tetragon.ProcessTracepoint - 20, // 24: tetragon.GetEventsResponse.process_loader:type_name -> tetragon.ProcessLoader - 21, // 25: tetragon.GetEventsResponse.process_uprobe:type_name -> tetragon.ProcessUprobe - 22, // 26: tetragon.GetEventsResponse.test:type_name -> tetragon.Test - 10, // 27: tetragon.GetEventsResponse.rate_limit_info:type_name -> tetragon.RateLimitInfo - 23, // 28: tetragon.GetEventsResponse.time:type_name -> google.protobuf.Timestamp - 9, // 29: tetragon.GetEventsResponse.aggregation_info:type_name -> tetragon.AggregationInfo - 30, // [30:30] is the sub-list for method output_type - 30, // [30:30] is the sub-list for method input_type - 30, // [30:30] is the sub-list for extension type_name - 30, // [30:30] is the sub-list for extension extendee - 0, // [0:30] is the sub-list for field type_name + 14, // 14: tetragon.FieldFilter.invert_event_set:type_name -> google.protobuf.BoolValue + 3, // 15: tetragon.GetEventsRequest.allow_list:type_name -> tetragon.Filter + 3, // 16: tetragon.GetEventsRequest.deny_list:type_name -> tetragon.Filter + 9, // 17: tetragon.GetEventsRequest.aggregation_options:type_name -> tetragon.AggregationOptions + 7, // 18: tetragon.GetEventsRequest.field_filters:type_name -> tetragon.FieldFilter + 17, // 19: tetragon.AggregationOptions.window_size:type_name -> google.protobuf.Duration + 2, // 20: tetragon.ProcessThrottle.type:type_name -> tetragon.ThrottleType + 18, // 21: tetragon.GetEventsResponse.process_exec:type_name -> tetragon.ProcessExec + 19, // 22: tetragon.GetEventsResponse.process_exit:type_name -> tetragon.ProcessExit + 20, // 23: tetragon.GetEventsResponse.process_kprobe:type_name -> tetragon.ProcessKprobe + 21, // 24: tetragon.GetEventsResponse.process_tracepoint:type_name -> tetragon.ProcessTracepoint + 22, // 25: tetragon.GetEventsResponse.process_loader:type_name -> tetragon.ProcessLoader + 23, // 26: tetragon.GetEventsResponse.process_uprobe:type_name -> tetragon.ProcessUprobe + 12, // 27: tetragon.GetEventsResponse.process_throttle:type_name -> tetragon.ProcessThrottle + 24, // 28: tetragon.GetEventsResponse.test:type_name -> tetragon.Test + 11, // 29: tetragon.GetEventsResponse.rate_limit_info:type_name -> tetragon.RateLimitInfo + 25, // 30: tetragon.GetEventsResponse.time:type_name -> google.protobuf.Timestamp + 10, // 31: tetragon.GetEventsResponse.aggregation_info:type_name -> tetragon.AggregationInfo + 32, // [32:32] is the sub-list for method output_type + 32, // [32:32] is the sub-list for method input_type + 32, // [32:32] is the sub-list for extension type_name + 32, // [32:32] is the sub-list for extension extendee + 0, // [0:32] is the sub-list for field type_name } func init() { file_tetragon_events_proto_init() } @@ -1401,6 +1544,18 @@ func file_tetragon_events_proto_init() { } } file_tetragon_events_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProcessThrottle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tetragon_events_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetEventsResponse); i { case 0: return &v.state @@ -1413,13 +1568,14 @@ func file_tetragon_events_proto_init() { } } } - file_tetragon_events_proto_msgTypes[9].OneofWrappers = []interface{}{ + file_tetragon_events_proto_msgTypes[10].OneofWrappers = []interface{}{ (*GetEventsResponse_ProcessExec)(nil), (*GetEventsResponse_ProcessExit)(nil), (*GetEventsResponse_ProcessKprobe)(nil), (*GetEventsResponse_ProcessTracepoint)(nil), (*GetEventsResponse_ProcessLoader)(nil), (*GetEventsResponse_ProcessUprobe)(nil), + (*GetEventsResponse_ProcessThrottle)(nil), (*GetEventsResponse_Test)(nil), (*GetEventsResponse_RateLimitInfo)(nil), } @@ -1428,8 +1584,8 @@ func file_tetragon_events_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tetragon_events_proto_rawDesc, - NumEnums: 2, - NumMessages: 10, + NumEnums: 3, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/api/v1/tetragon/events.pb.json.go b/api/v1/tetragon/events.pb.json.go index 44af480b37a..589d91748f7 100644 --- a/api/v1/tetragon/events.pb.json.go +++ b/api/v1/tetragon/events.pb.json.go @@ -151,6 +151,22 @@ func (msg *RateLimitInfo) UnmarshalJSON(b []byte) error { }.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *ProcessThrottle) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseEnumNumbers: false, + EmitUnpopulated: false, + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *ProcessThrottle) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{ + DiscardUnknown: false, + }.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *GetEventsResponse) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ diff --git a/api/v1/tetragon/events.proto b/api/v1/tetragon/events.proto index 86ec34ce66f..f2bd554645f 100644 --- a/api/v1/tetragon/events.proto +++ b/api/v1/tetragon/events.proto @@ -25,6 +25,7 @@ enum EventType { PROCESS_TRACEPOINT = 10; PROCESS_LOADER = 11; PROCESS_UPROBE = 12; + PROCESS_THROTTLE = 27; TEST = 40000; RATE_LIMIT_INFO = 40001; @@ -151,6 +152,19 @@ message RateLimitInfo { uint64 number_of_dropped_process_events = 1; } +enum ThrottleType { + THROTTLE_UNKNOWN = 0; + THROTTLE_START = 1; + THROTTLE_STOP = 2; +} + +message ProcessThrottle { + // Throttle type + ThrottleType type = 1; + // Cgroup name + string cgroup = 2; +} + message GetEventsResponse { // The type-specific fields of an event. // @@ -169,6 +183,7 @@ message GetEventsResponse { ProcessTracepoint process_tracepoint = 10; ProcessLoader process_loader = 11; ProcessUprobe process_uprobe = 12; + ProcessThrottle process_throttle = 27; Test test = 40000; RateLimitInfo rate_limit_info = 40001; diff --git a/api/v1/tetragon/types.pb.go b/api/v1/tetragon/types.pb.go index d414b79f26c..f418b3eaca8 100644 --- a/api/v1/tetragon/types.pb.go +++ b/api/v1/tetragon/types.pb.go @@ -159,6 +159,14 @@ func (event *RateLimitInfo) Encapsulate() IsGetEventsResponse_Event { } } +// Encapsulate implements the Event interface. +// Returns the event wrapped by its GetEventsResponse_* type. +func (event *ProcessThrottle) Encapsulate() IsGetEventsResponse_Event { + return &GetEventsResponse_ProcessThrottle{ + ProcessThrottle: event, + } +} + // UnwrapGetEventsResponse gets the inner event type from a GetEventsResponse func UnwrapGetEventsResponse(response *GetEventsResponse) interface{} { event := response.GetEvent() @@ -182,6 +190,8 @@ func UnwrapGetEventsResponse(response *GetEventsResponse) interface{} { return ev.ProcessLoader case *GetEventsResponse_RateLimitInfo: return ev.RateLimitInfo + case *GetEventsResponse_ProcessThrottle: + return ev.ProcessThrottle } return nil } diff --git a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go index d0755844e13..f11dc36ba6c 100644 --- a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go +++ b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go @@ -41,6 +41,7 @@ const ( EventType_PROCESS_TRACEPOINT EventType = 10 EventType_PROCESS_LOADER EventType = 11 EventType_PROCESS_UPROBE EventType = 12 + EventType_PROCESS_THROTTLE EventType = 27 EventType_TEST EventType = 40000 EventType_RATE_LIMIT_INFO EventType = 40001 ) @@ -55,6 +56,7 @@ var ( 10: "PROCESS_TRACEPOINT", 11: "PROCESS_LOADER", 12: "PROCESS_UPROBE", + 27: "PROCESS_THROTTLE", 40000: "TEST", 40001: "RATE_LIMIT_INFO", } @@ -66,6 +68,7 @@ var ( "PROCESS_TRACEPOINT": 10, "PROCESS_LOADER": 11, "PROCESS_UPROBE": 12, + "PROCESS_THROTTLE": 27, "TEST": 40000, "RATE_LIMIT_INFO": 40001, } @@ -145,6 +148,55 @@ func (FieldFilterAction) EnumDescriptor() ([]byte, []int) { return file_tetragon_events_proto_rawDescGZIP(), []int{1} } +type ThrottleType int32 + +const ( + ThrottleType_THROTTLE_UNKNOWN ThrottleType = 0 + ThrottleType_THROTTLE_START ThrottleType = 1 + ThrottleType_THROTTLE_STOP ThrottleType = 2 +) + +// Enum value maps for ThrottleType. +var ( + ThrottleType_name = map[int32]string{ + 0: "THROTTLE_UNKNOWN", + 1: "THROTTLE_START", + 2: "THROTTLE_STOP", + } + ThrottleType_value = map[string]int32{ + "THROTTLE_UNKNOWN": 0, + "THROTTLE_START": 1, + "THROTTLE_STOP": 2, + } +) + +func (x ThrottleType) Enum() *ThrottleType { + p := new(ThrottleType) + *p = x + return p +} + +func (x ThrottleType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ThrottleType) Descriptor() protoreflect.EnumDescriptor { + return file_tetragon_events_proto_enumTypes[2].Descriptor() +} + +func (ThrottleType) Type() protoreflect.EnumType { + return &file_tetragon_events_proto_enumTypes[2] +} + +func (x ThrottleType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ThrottleType.Descriptor instead. +func (ThrottleType) EnumDescriptor() ([]byte, []int) { + return file_tetragon_events_proto_rawDescGZIP(), []int{2} +} + type Filter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -818,6 +870,63 @@ func (x *RateLimitInfo) GetNumberOfDroppedProcessEvents() uint64 { return 0 } +type ProcessThrottle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Throttle type + Type ThrottleType `protobuf:"varint,1,opt,name=type,proto3,enum=tetragon.ThrottleType" json:"type,omitempty"` + // Cgroup name + Cgroup string `protobuf:"bytes,2,opt,name=cgroup,proto3" json:"cgroup,omitempty"` +} + +func (x *ProcessThrottle) Reset() { + *x = ProcessThrottle{} + if protoimpl.UnsafeEnabled { + mi := &file_tetragon_events_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProcessThrottle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcessThrottle) ProtoMessage() {} + +func (x *ProcessThrottle) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_events_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProcessThrottle.ProtoReflect.Descriptor instead. +func (*ProcessThrottle) Descriptor() ([]byte, []int) { + return file_tetragon_events_proto_rawDescGZIP(), []int{9} +} + +func (x *ProcessThrottle) GetType() ThrottleType { + if x != nil { + return x.Type + } + return ThrottleType_THROTTLE_UNKNOWN +} + +func (x *ProcessThrottle) GetCgroup() string { + if x != nil { + return x.Cgroup + } + return "" +} + type GetEventsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -835,6 +944,7 @@ type GetEventsResponse struct { // *GetEventsResponse_ProcessTracepoint // *GetEventsResponse_ProcessLoader // *GetEventsResponse_ProcessUprobe + // *GetEventsResponse_ProcessThrottle // *GetEventsResponse_Test // *GetEventsResponse_RateLimitInfo Event isGetEventsResponse_Event `protobuf_oneof:"event"` @@ -852,7 +962,7 @@ type GetEventsResponse struct { func (x *GetEventsResponse) Reset() { *x = GetEventsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_tetragon_events_proto_msgTypes[9] + mi := &file_tetragon_events_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -865,7 +975,7 @@ func (x *GetEventsResponse) String() string { func (*GetEventsResponse) ProtoMessage() {} func (x *GetEventsResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_events_proto_msgTypes[9] + mi := &file_tetragon_events_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -878,7 +988,7 @@ func (x *GetEventsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetEventsResponse.ProtoReflect.Descriptor instead. func (*GetEventsResponse) Descriptor() ([]byte, []int) { - return file_tetragon_events_proto_rawDescGZIP(), []int{9} + return file_tetragon_events_proto_rawDescGZIP(), []int{10} } func (m *GetEventsResponse) GetEvent() isGetEventsResponse_Event { @@ -930,6 +1040,13 @@ func (x *GetEventsResponse) GetProcessUprobe() *ProcessUprobe { return nil } +func (x *GetEventsResponse) GetProcessThrottle() *ProcessThrottle { + if x, ok := x.GetEvent().(*GetEventsResponse_ProcessThrottle); ok { + return x.ProcessThrottle + } + return nil +} + func (x *GetEventsResponse) GetTest() *Test { if x, ok := x.GetEvent().(*GetEventsResponse_Test); ok { return x.Test @@ -1000,6 +1117,10 @@ type GetEventsResponse_ProcessUprobe struct { ProcessUprobe *ProcessUprobe `protobuf:"bytes,12,opt,name=process_uprobe,json=processUprobe,proto3,oneof"` } +type GetEventsResponse_ProcessThrottle struct { + ProcessThrottle *ProcessThrottle `protobuf:"bytes,27,opt,name=process_throttle,json=processThrottle,proto3,oneof"` +} + type GetEventsResponse_Test struct { Test *Test `protobuf:"bytes,40000,opt,name=test,proto3,oneof"` } @@ -1020,6 +1141,8 @@ func (*GetEventsResponse_ProcessLoader) isGetEventsResponse_Event() {} func (*GetEventsResponse_ProcessUprobe) isGetEventsResponse_Event() {} +func (*GetEventsResponse_ProcessThrottle) isGetEventsResponse_Event() {} + func (*GetEventsResponse_Test) isGetEventsResponse_Event() {} func (*GetEventsResponse_RateLimitInfo) isGetEventsResponse_Event() {} @@ -1146,64 +1269,80 @@ var file_tetragon_events_proto_rawDesc = []byte{ 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1c, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x22, 0xab, 0x05, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, - 0x69, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, - 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x12, 0x4c, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x61, - 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, - 0x65, 0x72, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, - 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0xc0, 0xb8, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x54, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, - 0x0f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0xc1, 0xb8, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0xe8, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x2f, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, - 0x65, 0x12, 0x45, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x2a, 0xb1, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, - 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, - 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x10, 0x05, 0x12, 0x12, - 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, - 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x52, - 0x41, 0x43, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, - 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x12, - 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x55, 0x50, 0x52, 0x4f, 0x42, 0x45, - 0x10, 0x0c, 0x12, 0x0a, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, 0xc0, 0xb8, 0x02, 0x12, 0x15, - 0x0a, 0x0f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x49, 0x4e, 0x46, - 0x4f, 0x10, 0xc1, 0xb8, 0x02, 0x2a, 0x2d, 0x0a, 0x11, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, - 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x43, 0x4c, 0x55, - 0x44, 0x45, 0x10, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x73, 0x22, 0x55, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xf3, 0x05, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x65, 0x63, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x48, 0x00, 0x52, + 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x0c, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x4c, 0x0a, 0x12, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, + 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x46, 0x0a, 0x10, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x65, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0xc0, 0xb8, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x54, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x0f, + 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0xc1, 0xb8, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x48, 0x00, 0x52, 0x0d, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0xe8, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x2f, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, + 0x12, 0x45, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x2a, 0xc7, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, + 0x0a, 0x05, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, + 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, + 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x10, 0x05, 0x12, 0x12, 0x0a, + 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, + 0x09, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x52, 0x41, + 0x43, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, + 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x12, 0x0a, + 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x55, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, + 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, 0x52, + 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x1b, 0x12, 0x0a, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, + 0xc0, 0xb8, 0x02, 0x12, 0x15, 0x0a, 0x0f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, + 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0xc1, 0xb8, 0x02, 0x2a, 0x2d, 0x0a, 0x11, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, + 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x01, 0x2a, 0x4b, 0x0a, 0x0c, 0x54, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x48, 0x52, + 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, + 0x12, 0x0a, 0x0e, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, + 0x54, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, + 0x53, 0x54, 0x4f, 0x50, 0x10, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1218,70 +1357,74 @@ func file_tetragon_events_proto_rawDescGZIP() []byte { return file_tetragon_events_proto_rawDescData } -var file_tetragon_events_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_tetragon_events_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_tetragon_events_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_tetragon_events_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_tetragon_events_proto_goTypes = []interface{}{ (EventType)(0), // 0: tetragon.EventType (FieldFilterAction)(0), // 1: tetragon.FieldFilterAction - (*Filter)(nil), // 2: tetragon.Filter - (*CapFilter)(nil), // 3: tetragon.CapFilter - (*CapFilterSet)(nil), // 4: tetragon.CapFilterSet - (*RedactionFilter)(nil), // 5: tetragon.RedactionFilter - (*FieldFilter)(nil), // 6: tetragon.FieldFilter - (*GetEventsRequest)(nil), // 7: tetragon.GetEventsRequest - (*AggregationOptions)(nil), // 8: tetragon.AggregationOptions - (*AggregationInfo)(nil), // 9: tetragon.AggregationInfo - (*RateLimitInfo)(nil), // 10: tetragon.RateLimitInfo - (*GetEventsResponse)(nil), // 11: tetragon.GetEventsResponse - (*wrapperspb.BoolValue)(nil), // 12: google.protobuf.BoolValue - (CapabilitiesType)(0), // 13: tetragon.CapabilitiesType - (*fieldmaskpb.FieldMask)(nil), // 14: google.protobuf.FieldMask - (*durationpb.Duration)(nil), // 15: google.protobuf.Duration - (*ProcessExec)(nil), // 16: tetragon.ProcessExec - (*ProcessExit)(nil), // 17: tetragon.ProcessExit - (*ProcessKprobe)(nil), // 18: tetragon.ProcessKprobe - (*ProcessTracepoint)(nil), // 19: tetragon.ProcessTracepoint - (*ProcessLoader)(nil), // 20: tetragon.ProcessLoader - (*ProcessUprobe)(nil), // 21: tetragon.ProcessUprobe - (*Test)(nil), // 22: tetragon.Test - (*timestamppb.Timestamp)(nil), // 23: google.protobuf.Timestamp + (ThrottleType)(0), // 2: tetragon.ThrottleType + (*Filter)(nil), // 3: tetragon.Filter + (*CapFilter)(nil), // 4: tetragon.CapFilter + (*CapFilterSet)(nil), // 5: tetragon.CapFilterSet + (*RedactionFilter)(nil), // 6: tetragon.RedactionFilter + (*FieldFilter)(nil), // 7: tetragon.FieldFilter + (*GetEventsRequest)(nil), // 8: tetragon.GetEventsRequest + (*AggregationOptions)(nil), // 9: tetragon.AggregationOptions + (*AggregationInfo)(nil), // 10: tetragon.AggregationInfo + (*RateLimitInfo)(nil), // 11: tetragon.RateLimitInfo + (*ProcessThrottle)(nil), // 12: tetragon.ProcessThrottle + (*GetEventsResponse)(nil), // 13: tetragon.GetEventsResponse + (*wrapperspb.BoolValue)(nil), // 14: google.protobuf.BoolValue + (CapabilitiesType)(0), // 15: tetragon.CapabilitiesType + (*fieldmaskpb.FieldMask)(nil), // 16: google.protobuf.FieldMask + (*durationpb.Duration)(nil), // 17: google.protobuf.Duration + (*ProcessExec)(nil), // 18: tetragon.ProcessExec + (*ProcessExit)(nil), // 19: tetragon.ProcessExit + (*ProcessKprobe)(nil), // 20: tetragon.ProcessKprobe + (*ProcessTracepoint)(nil), // 21: tetragon.ProcessTracepoint + (*ProcessLoader)(nil), // 22: tetragon.ProcessLoader + (*ProcessUprobe)(nil), // 23: tetragon.ProcessUprobe + (*Test)(nil), // 24: tetragon.Test + (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp } var file_tetragon_events_proto_depIdxs = []int32{ - 12, // 0: tetragon.Filter.health_check:type_name -> google.protobuf.BoolValue + 14, // 0: tetragon.Filter.health_check:type_name -> google.protobuf.BoolValue 0, // 1: tetragon.Filter.event_set:type_name -> tetragon.EventType - 3, // 2: tetragon.Filter.capabilities:type_name -> tetragon.CapFilter - 4, // 3: tetragon.CapFilter.permitted:type_name -> tetragon.CapFilterSet - 4, // 4: tetragon.CapFilter.effective:type_name -> tetragon.CapFilterSet - 4, // 5: tetragon.CapFilter.inheritable:type_name -> tetragon.CapFilterSet - 13, // 6: tetragon.CapFilterSet.any:type_name -> tetragon.CapabilitiesType - 13, // 7: tetragon.CapFilterSet.all:type_name -> tetragon.CapabilitiesType - 13, // 8: tetragon.CapFilterSet.exactly:type_name -> tetragon.CapabilitiesType - 13, // 9: tetragon.CapFilterSet.none:type_name -> tetragon.CapabilitiesType - 2, // 10: tetragon.RedactionFilter.match:type_name -> tetragon.Filter + 4, // 2: tetragon.Filter.capabilities:type_name -> tetragon.CapFilter + 5, // 3: tetragon.CapFilter.permitted:type_name -> tetragon.CapFilterSet + 5, // 4: tetragon.CapFilter.effective:type_name -> tetragon.CapFilterSet + 5, // 5: tetragon.CapFilter.inheritable:type_name -> tetragon.CapFilterSet + 15, // 6: tetragon.CapFilterSet.any:type_name -> tetragon.CapabilitiesType + 15, // 7: tetragon.CapFilterSet.all:type_name -> tetragon.CapabilitiesType + 15, // 8: tetragon.CapFilterSet.exactly:type_name -> tetragon.CapabilitiesType + 15, // 9: tetragon.CapFilterSet.none:type_name -> tetragon.CapabilitiesType + 3, // 10: tetragon.RedactionFilter.match:type_name -> tetragon.Filter 0, // 11: tetragon.FieldFilter.event_set:type_name -> tetragon.EventType - 14, // 12: tetragon.FieldFilter.fields:type_name -> google.protobuf.FieldMask + 16, // 12: tetragon.FieldFilter.fields:type_name -> google.protobuf.FieldMask 1, // 13: tetragon.FieldFilter.action:type_name -> tetragon.FieldFilterAction - 12, // 14: tetragon.FieldFilter.invert_event_set:type_name -> google.protobuf.BoolValue - 2, // 15: tetragon.GetEventsRequest.allow_list:type_name -> tetragon.Filter - 2, // 16: tetragon.GetEventsRequest.deny_list:type_name -> tetragon.Filter - 8, // 17: tetragon.GetEventsRequest.aggregation_options:type_name -> tetragon.AggregationOptions - 6, // 18: tetragon.GetEventsRequest.field_filters:type_name -> tetragon.FieldFilter - 15, // 19: tetragon.AggregationOptions.window_size:type_name -> google.protobuf.Duration - 16, // 20: tetragon.GetEventsResponse.process_exec:type_name -> tetragon.ProcessExec - 17, // 21: tetragon.GetEventsResponse.process_exit:type_name -> tetragon.ProcessExit - 18, // 22: tetragon.GetEventsResponse.process_kprobe:type_name -> tetragon.ProcessKprobe - 19, // 23: tetragon.GetEventsResponse.process_tracepoint:type_name -> tetragon.ProcessTracepoint - 20, // 24: tetragon.GetEventsResponse.process_loader:type_name -> tetragon.ProcessLoader - 21, // 25: tetragon.GetEventsResponse.process_uprobe:type_name -> tetragon.ProcessUprobe - 22, // 26: tetragon.GetEventsResponse.test:type_name -> tetragon.Test - 10, // 27: tetragon.GetEventsResponse.rate_limit_info:type_name -> tetragon.RateLimitInfo - 23, // 28: tetragon.GetEventsResponse.time:type_name -> google.protobuf.Timestamp - 9, // 29: tetragon.GetEventsResponse.aggregation_info:type_name -> tetragon.AggregationInfo - 30, // [30:30] is the sub-list for method output_type - 30, // [30:30] is the sub-list for method input_type - 30, // [30:30] is the sub-list for extension type_name - 30, // [30:30] is the sub-list for extension extendee - 0, // [0:30] is the sub-list for field type_name + 14, // 14: tetragon.FieldFilter.invert_event_set:type_name -> google.protobuf.BoolValue + 3, // 15: tetragon.GetEventsRequest.allow_list:type_name -> tetragon.Filter + 3, // 16: tetragon.GetEventsRequest.deny_list:type_name -> tetragon.Filter + 9, // 17: tetragon.GetEventsRequest.aggregation_options:type_name -> tetragon.AggregationOptions + 7, // 18: tetragon.GetEventsRequest.field_filters:type_name -> tetragon.FieldFilter + 17, // 19: tetragon.AggregationOptions.window_size:type_name -> google.protobuf.Duration + 2, // 20: tetragon.ProcessThrottle.type:type_name -> tetragon.ThrottleType + 18, // 21: tetragon.GetEventsResponse.process_exec:type_name -> tetragon.ProcessExec + 19, // 22: tetragon.GetEventsResponse.process_exit:type_name -> tetragon.ProcessExit + 20, // 23: tetragon.GetEventsResponse.process_kprobe:type_name -> tetragon.ProcessKprobe + 21, // 24: tetragon.GetEventsResponse.process_tracepoint:type_name -> tetragon.ProcessTracepoint + 22, // 25: tetragon.GetEventsResponse.process_loader:type_name -> tetragon.ProcessLoader + 23, // 26: tetragon.GetEventsResponse.process_uprobe:type_name -> tetragon.ProcessUprobe + 12, // 27: tetragon.GetEventsResponse.process_throttle:type_name -> tetragon.ProcessThrottle + 24, // 28: tetragon.GetEventsResponse.test:type_name -> tetragon.Test + 11, // 29: tetragon.GetEventsResponse.rate_limit_info:type_name -> tetragon.RateLimitInfo + 25, // 30: tetragon.GetEventsResponse.time:type_name -> google.protobuf.Timestamp + 10, // 31: tetragon.GetEventsResponse.aggregation_info:type_name -> tetragon.AggregationInfo + 32, // [32:32] is the sub-list for method output_type + 32, // [32:32] is the sub-list for method input_type + 32, // [32:32] is the sub-list for extension type_name + 32, // [32:32] is the sub-list for extension extendee + 0, // [0:32] is the sub-list for field type_name } func init() { file_tetragon_events_proto_init() } @@ -1401,6 +1544,18 @@ func file_tetragon_events_proto_init() { } } file_tetragon_events_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProcessThrottle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tetragon_events_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetEventsResponse); i { case 0: return &v.state @@ -1413,13 +1568,14 @@ func file_tetragon_events_proto_init() { } } } - file_tetragon_events_proto_msgTypes[9].OneofWrappers = []interface{}{ + file_tetragon_events_proto_msgTypes[10].OneofWrappers = []interface{}{ (*GetEventsResponse_ProcessExec)(nil), (*GetEventsResponse_ProcessExit)(nil), (*GetEventsResponse_ProcessKprobe)(nil), (*GetEventsResponse_ProcessTracepoint)(nil), (*GetEventsResponse_ProcessLoader)(nil), (*GetEventsResponse_ProcessUprobe)(nil), + (*GetEventsResponse_ProcessThrottle)(nil), (*GetEventsResponse_Test)(nil), (*GetEventsResponse_RateLimitInfo)(nil), } @@ -1428,8 +1584,8 @@ func file_tetragon_events_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tetragon_events_proto_rawDesc, - NumEnums: 2, - NumMessages: 10, + NumEnums: 3, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.json.go b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.json.go index 44af480b37a..589d91748f7 100644 --- a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.json.go +++ b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.json.go @@ -151,6 +151,22 @@ func (msg *RateLimitInfo) UnmarshalJSON(b []byte) error { }.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *ProcessThrottle) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseEnumNumbers: false, + EmitUnpopulated: false, + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *ProcessThrottle) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{ + DiscardUnknown: false, + }.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *GetEventsResponse) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ diff --git a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto index 86ec34ce66f..f2bd554645f 100644 --- a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto +++ b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto @@ -25,6 +25,7 @@ enum EventType { PROCESS_TRACEPOINT = 10; PROCESS_LOADER = 11; PROCESS_UPROBE = 12; + PROCESS_THROTTLE = 27; TEST = 40000; RATE_LIMIT_INFO = 40001; @@ -151,6 +152,19 @@ message RateLimitInfo { uint64 number_of_dropped_process_events = 1; } +enum ThrottleType { + THROTTLE_UNKNOWN = 0; + THROTTLE_START = 1; + THROTTLE_STOP = 2; +} + +message ProcessThrottle { + // Throttle type + ThrottleType type = 1; + // Cgroup name + string cgroup = 2; +} + message GetEventsResponse { // The type-specific fields of an event. // @@ -169,6 +183,7 @@ message GetEventsResponse { ProcessTracepoint process_tracepoint = 10; ProcessLoader process_loader = 11; ProcessUprobe process_uprobe = 12; + ProcessThrottle process_throttle = 27; Test test = 40000; RateLimitInfo rate_limit_info = 40001; diff --git a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go index d414b79f26c..f418b3eaca8 100644 --- a/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go +++ b/contrib/rthooks/tetragon-oci-hook/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go @@ -159,6 +159,14 @@ func (event *RateLimitInfo) Encapsulate() IsGetEventsResponse_Event { } } +// Encapsulate implements the Event interface. +// Returns the event wrapped by its GetEventsResponse_* type. +func (event *ProcessThrottle) Encapsulate() IsGetEventsResponse_Event { + return &GetEventsResponse_ProcessThrottle{ + ProcessThrottle: event, + } +} + // UnwrapGetEventsResponse gets the inner event type from a GetEventsResponse func UnwrapGetEventsResponse(response *GetEventsResponse) interface{} { event := response.GetEvent() @@ -182,6 +190,8 @@ func UnwrapGetEventsResponse(response *GetEventsResponse) interface{} { return ev.ProcessLoader case *GetEventsResponse_RateLimitInfo: return ev.RateLimitInfo + case *GetEventsResponse_ProcessThrottle: + return ev.ProcessThrottle } return nil } diff --git a/docs/content/en/docs/reference/grpc-api.md b/docs/content/en/docs/reference/grpc-api.md index a0bdbab0553..fa32fc48147 100644 --- a/docs/content/en/docs/reference/grpc-api.md +++ b/docs/content/en/docs/reference/grpc-api.md @@ -782,12 +782,22 @@ Capability set to filter over. NOTE: you may specify only ONE set here. | process_tracepoint | [ProcessTracepoint](#tetragon-ProcessTracepoint) | | ProcessTracepoint contains information about the pre-defined tracepoint and the process that invoked them. | | process_loader | [ProcessLoader](#tetragon-ProcessLoader) | | | | process_uprobe | [ProcessUprobe](#tetragon-ProcessUprobe) | | | +| process_throttle | [ProcessThrottle](#tetragon-ProcessThrottle) | | | | test | [Test](#tetragon-Test) | | | | rate_limit_info | [RateLimitInfo](#tetragon-RateLimitInfo) | | | | node_name | [string](#string) | | Name of the node where this event was observed. | | time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Timestamp at which this event was observed. For an aggregated response, this field to set to the timestamp at which the event was observed for the first time in a given aggregation time window. | | aggregation_info | [AggregationInfo](#tetragon-AggregationInfo) | | aggregation_info contains information about aggregation results. This field is set only for aggregated responses. | + + +### ProcessThrottle + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| type | [ThrottleType](#tetragon-ThrottleType) | | Throttle type | +| cgroup | [string](#string) | | Cgroup name | + ### RateLimitInfo @@ -823,6 +833,7 @@ GetEventsResponse event oneof. | PROCESS_TRACEPOINT | 10 | | | PROCESS_LOADER | 11 | | | PROCESS_UPROBE | 12 | | +| PROCESS_THROTTLE | 27 | | | TEST | 40000 | | | RATE_LIMIT_INFO | 40001 | | @@ -836,6 +847,16 @@ Determines the behavior of a field filter | INCLUDE | 0 | | | EXCLUDE | 1 | | + + +### ThrottleType + +| Name | Number | Description | +| ---- | ------ | ----------- | +| THROTTLE_UNKNOWN | 0 | | +| THROTTLE_START | 1 | | +| THROTTLE_STOP | 2 | | + ## tetragon/stack.proto diff --git a/docs/content/en/docs/reference/metrics.md b/docs/content/en/docs/reference/metrics.md index 59419fe6901..ff0ee4cc92c 100644 --- a/docs/content/en/docs/reference/metrics.md +++ b/docs/content/en/docs/reference/metrics.md @@ -59,7 +59,7 @@ The total of errors encountered while fetching process exec information from the | label | values | | ----- | ------ | | `error` | `nil_process_pid` | -| `event_type` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | +| `event_type` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_THROTTLE, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | ### `tetragon_event_cache_parent_info_errors_total` @@ -67,7 +67,7 @@ The total of times we failed to fetch cached parent info for a given event type. | label | values | | ----- | ------ | -| `event_type` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | +| `event_type` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_THROTTLE, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | ### `tetragon_event_cache_pod_info_errors_total` @@ -75,7 +75,7 @@ The total of times we failed to fetch cached pod info for a given event type. | label | values | | ----- | ------ | -| `event_type` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | +| `event_type` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_THROTTLE, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | ### `tetragon_event_cache_process_info_errors_total` @@ -83,7 +83,7 @@ The total of times we failed to fetch cached process info for a given event type | label | values | | ----- | ------ | -| `event_type` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | +| `event_type` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_THROTTLE, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | ### `tetragon_event_cache_retries_total` @@ -425,7 +425,7 @@ The total number of Tetragon events | `binary` | `example-binary` | | `namespace` | `example-namespace` | | `pod ` | `example-pod` | -| `type ` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | +| `type ` | `PROCESS_EXEC, PROCESS_EXIT, PROCESS_KPROBE, PROCESS_LOADER, PROCESS_THROTTLE, PROCESS_TRACEPOINT, PROCESS_UPROBE, RATE_LIMIT_INFO` | | `workload` | `example-workload` | ### `tetragon_policy_events_total` diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go index 2213e2449d2..64c0f66c8b7 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go @@ -280,6 +280,8 @@ func CheckerFromEvent(event Event) (EventChecker, error) { return NewProcessLoaderChecker("").FromProcessLoader(ev), nil case *tetragon.RateLimitInfo: return NewRateLimitInfoChecker("").FromRateLimitInfo(ev), nil + case *tetragon.ProcessThrottle: + return NewProcessThrottleChecker("").FromProcessThrottle(ev), nil default: return nil, fmt.Errorf("Unhandled event type %T", event) @@ -340,6 +342,8 @@ func EventFromResponse(response *tetragon.GetEventsResponse) (Event, error) { return ev.ProcessLoader, nil case *tetragon.GetEventsResponse_RateLimitInfo: return ev.RateLimitInfo, nil + case *tetragon.GetEventsResponse_ProcessThrottle: + return ev.ProcessThrottle, nil default: return nil, fmt.Errorf("Unknown event type %T", response.Event) @@ -1959,6 +1963,93 @@ func (checker *RateLimitInfoChecker) FromRateLimitInfo(event *tetragon.RateLimit return checker } +// ProcessThrottleChecker implements a checker struct to check a ProcessThrottle event +type ProcessThrottleChecker struct { + CheckerName string `json:"checkerName"` + Type *ThrottleTypeChecker `json:"type,omitempty"` + Cgroup *stringmatcher.StringMatcher `json:"cgroup,omitempty"` +} + +// CheckEvent checks a single event and implements the EventChecker interface +func (checker *ProcessThrottleChecker) CheckEvent(event Event) error { + if ev, ok := event.(*tetragon.ProcessThrottle); ok { + return checker.Check(ev) + } + return fmt.Errorf("%s: %T is not a ProcessThrottle event", CheckerLogPrefix(checker), event) +} + +// CheckResponse checks a single gRPC response and implements the EventChecker interface +func (checker *ProcessThrottleChecker) CheckResponse(response *tetragon.GetEventsResponse) error { + event, err := EventFromResponse(response) + if err != nil { + return err + } + return checker.CheckEvent(event) +} + +// NewProcessThrottleChecker creates a new ProcessThrottleChecker +func NewProcessThrottleChecker(name string) *ProcessThrottleChecker { + return &ProcessThrottleChecker{CheckerName: name} +} + +// Get the name associated with the checker +func (checker *ProcessThrottleChecker) GetCheckerName() string { + return checker.CheckerName +} + +// Get the type of the checker as a string +func (checker *ProcessThrottleChecker) GetCheckerType() string { + return "ProcessThrottleChecker" +} + +// Check checks a ProcessThrottle event +func (checker *ProcessThrottleChecker) Check(event *tetragon.ProcessThrottle) error { + if event == nil { + return fmt.Errorf("%s: ProcessThrottle event is nil", CheckerLogPrefix(checker)) + } + + fieldChecks := func() error { + if checker.Type != nil { + if err := checker.Type.Check(&event.Type); err != nil { + return fmt.Errorf("Type check failed: %w", err) + } + } + if checker.Cgroup != nil { + if err := checker.Cgroup.Match(event.Cgroup); err != nil { + return fmt.Errorf("Cgroup check failed: %w", err) + } + } + return nil + } + if err := fieldChecks(); err != nil { + return fmt.Errorf("%s: %w", CheckerLogPrefix(checker), err) + } + return nil +} + +// WithType adds a Type check to the ProcessThrottleChecker +func (checker *ProcessThrottleChecker) WithType(check tetragon.ThrottleType) *ProcessThrottleChecker { + wrappedCheck := ThrottleTypeChecker(check) + checker.Type = &wrappedCheck + return checker +} + +// WithCgroup adds a Cgroup check to the ProcessThrottleChecker +func (checker *ProcessThrottleChecker) WithCgroup(check *stringmatcher.StringMatcher) *ProcessThrottleChecker { + checker.Cgroup = check + return checker +} + +//FromProcessThrottle populates the ProcessThrottleChecker using data from a ProcessThrottle event +func (checker *ProcessThrottleChecker) FromProcessThrottle(event *tetragon.ProcessThrottle) *ProcessThrottleChecker { + if event == nil { + return checker + } + checker.Type = NewThrottleTypeChecker(event.Type) + checker.Cgroup = stringmatcher.Full(event.Cgroup) + return checker +} + // ImageChecker implements a checker struct to check a Image field type ImageChecker struct { Id *stringmatcher.StringMatcher `json:"id,omitempty"` @@ -6411,3 +6502,55 @@ func (enum *TaintedBitsTypeChecker) Check(val *tetragon.TaintedBitsType) error { } return nil } + +// ThrottleTypeChecker checks a tetragon.ThrottleType +type ThrottleTypeChecker tetragon.ThrottleType + +// MarshalJSON implements json.Marshaler interface +func (enum ThrottleTypeChecker) MarshalJSON() ([]byte, error) { + if name, ok := tetragon.ThrottleType_name[int32(enum)]; ok { + name = strings.TrimPrefix(name, "THROTTLE_") + return json.Marshal(name) + } + + return nil, fmt.Errorf("Unknown ThrottleType %d", enum) +} + +// UnmarshalJSON implements json.Unmarshaler interface +func (enum *ThrottleTypeChecker) UnmarshalJSON(b []byte) error { + var str string + if err := yaml.UnmarshalStrict(b, &str); err != nil { + return err + } + + // Convert to uppercase if not already + str = strings.ToUpper(str) + + // Look up the value from the enum values map + if n, ok := tetragon.ThrottleType_value[str]; ok { + *enum = ThrottleTypeChecker(n) + } else if n, ok := tetragon.ThrottleType_value["THROTTLE_"+str]; ok { + *enum = ThrottleTypeChecker(n) + } else { + return fmt.Errorf("Unknown ThrottleType %s", str) + } + + return nil +} + +// NewThrottleTypeChecker creates a new ThrottleTypeChecker +func NewThrottleTypeChecker(val tetragon.ThrottleType) *ThrottleTypeChecker { + enum := ThrottleTypeChecker(val) + return &enum +} + +// Check checks a ThrottleType against the checker +func (enum *ThrottleTypeChecker) Check(val *tetragon.ThrottleType) error { + if val == nil { + return fmt.Errorf("ThrottleTypeChecker: ThrottleType is nil and does not match expected value %s", tetragon.ThrottleType(*enum)) + } + if *enum != ThrottleTypeChecker(*val) { + return fmt.Errorf("ThrottleTypeChecker: ThrottleType has value %s which does not match expected value %s", (*val), tetragon.ThrottleType(*enum)) + } + return nil +} diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/yaml/yaml.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/yaml/yaml.pb.go index 81f7e977b93..f3ff5347a95 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/yaml/yaml.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/yaml/yaml.pb.go @@ -148,6 +148,7 @@ type eventCheckerHelper struct { Test *eventchecker.TestChecker `json:"test,omitempty"` ProcessLoader *eventchecker.ProcessLoaderChecker `json:"loader,omitempty"` RateLimitInfo *eventchecker.RateLimitInfoChecker `json:"rateLimitInfo,omitempty"` + ProcessThrottle *eventchecker.ProcessThrottleChecker `json:"throttle,omitempty"` } // EventChecker is a wrapper around the EventChecker interface to help unmarshaling @@ -210,6 +211,12 @@ func (checker *EventChecker) UnmarshalJSON(b []byte) error { } eventChecker = helper.RateLimitInfo } + if helper.ProcessThrottle != nil { + if eventChecker != nil { + return fmt.Errorf("EventChecker: cannot define more than one checker, got %T but already had %T", helper.ProcessThrottle, eventChecker) + } + eventChecker = helper.ProcessThrottle + } checker.EventChecker = eventChecker return nil } @@ -234,6 +241,8 @@ func (checker EventChecker) MarshalJSON() ([]byte, error) { helper.ProcessLoader = c case *eventchecker.RateLimitInfoChecker: helper.RateLimitInfo = c + case *eventchecker.ProcessThrottleChecker: + helper.ProcessThrottle = c default: return nil, fmt.Errorf("EventChecker: unknown checker type %T", c) } diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers/helpers.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers/helpers.pb.go index 4c51ffae860..55f80b413ef 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers/helpers.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers/helpers.pb.go @@ -34,6 +34,8 @@ func ResponseTypeString(response *tetragon.GetEventsResponse) (string, error) { return tetragon.EventType_PROCESS_LOADER.String(), nil case *tetragon.GetEventsResponse_ProcessUprobe: return tetragon.EventType_PROCESS_UPROBE.String(), nil + case *tetragon.GetEventsResponse_ProcessThrottle: + return tetragon.EventType_PROCESS_THROTTLE.String(), nil case *tetragon.GetEventsResponse_Test: return tetragon.EventType_TEST.String(), nil case *tetragon.GetEventsResponse_RateLimitInfo: diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go index d0755844e13..f11dc36ba6c 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go @@ -41,6 +41,7 @@ const ( EventType_PROCESS_TRACEPOINT EventType = 10 EventType_PROCESS_LOADER EventType = 11 EventType_PROCESS_UPROBE EventType = 12 + EventType_PROCESS_THROTTLE EventType = 27 EventType_TEST EventType = 40000 EventType_RATE_LIMIT_INFO EventType = 40001 ) @@ -55,6 +56,7 @@ var ( 10: "PROCESS_TRACEPOINT", 11: "PROCESS_LOADER", 12: "PROCESS_UPROBE", + 27: "PROCESS_THROTTLE", 40000: "TEST", 40001: "RATE_LIMIT_INFO", } @@ -66,6 +68,7 @@ var ( "PROCESS_TRACEPOINT": 10, "PROCESS_LOADER": 11, "PROCESS_UPROBE": 12, + "PROCESS_THROTTLE": 27, "TEST": 40000, "RATE_LIMIT_INFO": 40001, } @@ -145,6 +148,55 @@ func (FieldFilterAction) EnumDescriptor() ([]byte, []int) { return file_tetragon_events_proto_rawDescGZIP(), []int{1} } +type ThrottleType int32 + +const ( + ThrottleType_THROTTLE_UNKNOWN ThrottleType = 0 + ThrottleType_THROTTLE_START ThrottleType = 1 + ThrottleType_THROTTLE_STOP ThrottleType = 2 +) + +// Enum value maps for ThrottleType. +var ( + ThrottleType_name = map[int32]string{ + 0: "THROTTLE_UNKNOWN", + 1: "THROTTLE_START", + 2: "THROTTLE_STOP", + } + ThrottleType_value = map[string]int32{ + "THROTTLE_UNKNOWN": 0, + "THROTTLE_START": 1, + "THROTTLE_STOP": 2, + } +) + +func (x ThrottleType) Enum() *ThrottleType { + p := new(ThrottleType) + *p = x + return p +} + +func (x ThrottleType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ThrottleType) Descriptor() protoreflect.EnumDescriptor { + return file_tetragon_events_proto_enumTypes[2].Descriptor() +} + +func (ThrottleType) Type() protoreflect.EnumType { + return &file_tetragon_events_proto_enumTypes[2] +} + +func (x ThrottleType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ThrottleType.Descriptor instead. +func (ThrottleType) EnumDescriptor() ([]byte, []int) { + return file_tetragon_events_proto_rawDescGZIP(), []int{2} +} + type Filter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -818,6 +870,63 @@ func (x *RateLimitInfo) GetNumberOfDroppedProcessEvents() uint64 { return 0 } +type ProcessThrottle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Throttle type + Type ThrottleType `protobuf:"varint,1,opt,name=type,proto3,enum=tetragon.ThrottleType" json:"type,omitempty"` + // Cgroup name + Cgroup string `protobuf:"bytes,2,opt,name=cgroup,proto3" json:"cgroup,omitempty"` +} + +func (x *ProcessThrottle) Reset() { + *x = ProcessThrottle{} + if protoimpl.UnsafeEnabled { + mi := &file_tetragon_events_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProcessThrottle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcessThrottle) ProtoMessage() {} + +func (x *ProcessThrottle) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_events_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProcessThrottle.ProtoReflect.Descriptor instead. +func (*ProcessThrottle) Descriptor() ([]byte, []int) { + return file_tetragon_events_proto_rawDescGZIP(), []int{9} +} + +func (x *ProcessThrottle) GetType() ThrottleType { + if x != nil { + return x.Type + } + return ThrottleType_THROTTLE_UNKNOWN +} + +func (x *ProcessThrottle) GetCgroup() string { + if x != nil { + return x.Cgroup + } + return "" +} + type GetEventsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -835,6 +944,7 @@ type GetEventsResponse struct { // *GetEventsResponse_ProcessTracepoint // *GetEventsResponse_ProcessLoader // *GetEventsResponse_ProcessUprobe + // *GetEventsResponse_ProcessThrottle // *GetEventsResponse_Test // *GetEventsResponse_RateLimitInfo Event isGetEventsResponse_Event `protobuf_oneof:"event"` @@ -852,7 +962,7 @@ type GetEventsResponse struct { func (x *GetEventsResponse) Reset() { *x = GetEventsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_tetragon_events_proto_msgTypes[9] + mi := &file_tetragon_events_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -865,7 +975,7 @@ func (x *GetEventsResponse) String() string { func (*GetEventsResponse) ProtoMessage() {} func (x *GetEventsResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_events_proto_msgTypes[9] + mi := &file_tetragon_events_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -878,7 +988,7 @@ func (x *GetEventsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetEventsResponse.ProtoReflect.Descriptor instead. func (*GetEventsResponse) Descriptor() ([]byte, []int) { - return file_tetragon_events_proto_rawDescGZIP(), []int{9} + return file_tetragon_events_proto_rawDescGZIP(), []int{10} } func (m *GetEventsResponse) GetEvent() isGetEventsResponse_Event { @@ -930,6 +1040,13 @@ func (x *GetEventsResponse) GetProcessUprobe() *ProcessUprobe { return nil } +func (x *GetEventsResponse) GetProcessThrottle() *ProcessThrottle { + if x, ok := x.GetEvent().(*GetEventsResponse_ProcessThrottle); ok { + return x.ProcessThrottle + } + return nil +} + func (x *GetEventsResponse) GetTest() *Test { if x, ok := x.GetEvent().(*GetEventsResponse_Test); ok { return x.Test @@ -1000,6 +1117,10 @@ type GetEventsResponse_ProcessUprobe struct { ProcessUprobe *ProcessUprobe `protobuf:"bytes,12,opt,name=process_uprobe,json=processUprobe,proto3,oneof"` } +type GetEventsResponse_ProcessThrottle struct { + ProcessThrottle *ProcessThrottle `protobuf:"bytes,27,opt,name=process_throttle,json=processThrottle,proto3,oneof"` +} + type GetEventsResponse_Test struct { Test *Test `protobuf:"bytes,40000,opt,name=test,proto3,oneof"` } @@ -1020,6 +1141,8 @@ func (*GetEventsResponse_ProcessLoader) isGetEventsResponse_Event() {} func (*GetEventsResponse_ProcessUprobe) isGetEventsResponse_Event() {} +func (*GetEventsResponse_ProcessThrottle) isGetEventsResponse_Event() {} + func (*GetEventsResponse_Test) isGetEventsResponse_Event() {} func (*GetEventsResponse_RateLimitInfo) isGetEventsResponse_Event() {} @@ -1146,64 +1269,80 @@ var file_tetragon_events_proto_rawDesc = []byte{ 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1c, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x22, 0xab, 0x05, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, - 0x69, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, - 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x12, 0x4c, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x61, - 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, - 0x65, 0x72, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, - 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0xc0, 0xb8, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x54, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, - 0x0f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0xc1, 0xb8, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0xe8, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x2f, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, - 0x65, 0x12, 0x45, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x2a, 0xb1, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, - 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, - 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x10, 0x05, 0x12, 0x12, - 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, - 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x52, - 0x41, 0x43, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, - 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x12, - 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x55, 0x50, 0x52, 0x4f, 0x42, 0x45, - 0x10, 0x0c, 0x12, 0x0a, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, 0xc0, 0xb8, 0x02, 0x12, 0x15, - 0x0a, 0x0f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x49, 0x4e, 0x46, - 0x4f, 0x10, 0xc1, 0xb8, 0x02, 0x2a, 0x2d, 0x0a, 0x11, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, - 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x43, 0x4c, 0x55, - 0x44, 0x45, 0x10, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x73, 0x22, 0x55, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xf3, 0x05, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x65, 0x63, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x48, 0x00, 0x52, + 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x0c, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x4c, 0x0a, 0x12, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, + 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x46, 0x0a, 0x10, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x65, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0xc0, 0xb8, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x54, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x0f, + 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0xc1, 0xb8, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x48, 0x00, 0x52, 0x0d, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0xe8, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x2f, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, + 0x12, 0x45, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x2a, 0xc7, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, + 0x0a, 0x05, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, + 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, + 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x10, 0x05, 0x12, 0x12, 0x0a, + 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, + 0x09, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x52, 0x41, + 0x43, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, + 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x12, 0x0a, + 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x55, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, + 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, 0x52, + 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x1b, 0x12, 0x0a, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, + 0xc0, 0xb8, 0x02, 0x12, 0x15, 0x0a, 0x0f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, + 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0xc1, 0xb8, 0x02, 0x2a, 0x2d, 0x0a, 0x11, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, + 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x01, 0x2a, 0x4b, 0x0a, 0x0c, 0x54, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x48, 0x52, + 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, + 0x12, 0x0a, 0x0e, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, + 0x54, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, + 0x53, 0x54, 0x4f, 0x50, 0x10, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1218,70 +1357,74 @@ func file_tetragon_events_proto_rawDescGZIP() []byte { return file_tetragon_events_proto_rawDescData } -var file_tetragon_events_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_tetragon_events_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_tetragon_events_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_tetragon_events_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_tetragon_events_proto_goTypes = []interface{}{ (EventType)(0), // 0: tetragon.EventType (FieldFilterAction)(0), // 1: tetragon.FieldFilterAction - (*Filter)(nil), // 2: tetragon.Filter - (*CapFilter)(nil), // 3: tetragon.CapFilter - (*CapFilterSet)(nil), // 4: tetragon.CapFilterSet - (*RedactionFilter)(nil), // 5: tetragon.RedactionFilter - (*FieldFilter)(nil), // 6: tetragon.FieldFilter - (*GetEventsRequest)(nil), // 7: tetragon.GetEventsRequest - (*AggregationOptions)(nil), // 8: tetragon.AggregationOptions - (*AggregationInfo)(nil), // 9: tetragon.AggregationInfo - (*RateLimitInfo)(nil), // 10: tetragon.RateLimitInfo - (*GetEventsResponse)(nil), // 11: tetragon.GetEventsResponse - (*wrapperspb.BoolValue)(nil), // 12: google.protobuf.BoolValue - (CapabilitiesType)(0), // 13: tetragon.CapabilitiesType - (*fieldmaskpb.FieldMask)(nil), // 14: google.protobuf.FieldMask - (*durationpb.Duration)(nil), // 15: google.protobuf.Duration - (*ProcessExec)(nil), // 16: tetragon.ProcessExec - (*ProcessExit)(nil), // 17: tetragon.ProcessExit - (*ProcessKprobe)(nil), // 18: tetragon.ProcessKprobe - (*ProcessTracepoint)(nil), // 19: tetragon.ProcessTracepoint - (*ProcessLoader)(nil), // 20: tetragon.ProcessLoader - (*ProcessUprobe)(nil), // 21: tetragon.ProcessUprobe - (*Test)(nil), // 22: tetragon.Test - (*timestamppb.Timestamp)(nil), // 23: google.protobuf.Timestamp + (ThrottleType)(0), // 2: tetragon.ThrottleType + (*Filter)(nil), // 3: tetragon.Filter + (*CapFilter)(nil), // 4: tetragon.CapFilter + (*CapFilterSet)(nil), // 5: tetragon.CapFilterSet + (*RedactionFilter)(nil), // 6: tetragon.RedactionFilter + (*FieldFilter)(nil), // 7: tetragon.FieldFilter + (*GetEventsRequest)(nil), // 8: tetragon.GetEventsRequest + (*AggregationOptions)(nil), // 9: tetragon.AggregationOptions + (*AggregationInfo)(nil), // 10: tetragon.AggregationInfo + (*RateLimitInfo)(nil), // 11: tetragon.RateLimitInfo + (*ProcessThrottle)(nil), // 12: tetragon.ProcessThrottle + (*GetEventsResponse)(nil), // 13: tetragon.GetEventsResponse + (*wrapperspb.BoolValue)(nil), // 14: google.protobuf.BoolValue + (CapabilitiesType)(0), // 15: tetragon.CapabilitiesType + (*fieldmaskpb.FieldMask)(nil), // 16: google.protobuf.FieldMask + (*durationpb.Duration)(nil), // 17: google.protobuf.Duration + (*ProcessExec)(nil), // 18: tetragon.ProcessExec + (*ProcessExit)(nil), // 19: tetragon.ProcessExit + (*ProcessKprobe)(nil), // 20: tetragon.ProcessKprobe + (*ProcessTracepoint)(nil), // 21: tetragon.ProcessTracepoint + (*ProcessLoader)(nil), // 22: tetragon.ProcessLoader + (*ProcessUprobe)(nil), // 23: tetragon.ProcessUprobe + (*Test)(nil), // 24: tetragon.Test + (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp } var file_tetragon_events_proto_depIdxs = []int32{ - 12, // 0: tetragon.Filter.health_check:type_name -> google.protobuf.BoolValue + 14, // 0: tetragon.Filter.health_check:type_name -> google.protobuf.BoolValue 0, // 1: tetragon.Filter.event_set:type_name -> tetragon.EventType - 3, // 2: tetragon.Filter.capabilities:type_name -> tetragon.CapFilter - 4, // 3: tetragon.CapFilter.permitted:type_name -> tetragon.CapFilterSet - 4, // 4: tetragon.CapFilter.effective:type_name -> tetragon.CapFilterSet - 4, // 5: tetragon.CapFilter.inheritable:type_name -> tetragon.CapFilterSet - 13, // 6: tetragon.CapFilterSet.any:type_name -> tetragon.CapabilitiesType - 13, // 7: tetragon.CapFilterSet.all:type_name -> tetragon.CapabilitiesType - 13, // 8: tetragon.CapFilterSet.exactly:type_name -> tetragon.CapabilitiesType - 13, // 9: tetragon.CapFilterSet.none:type_name -> tetragon.CapabilitiesType - 2, // 10: tetragon.RedactionFilter.match:type_name -> tetragon.Filter + 4, // 2: tetragon.Filter.capabilities:type_name -> tetragon.CapFilter + 5, // 3: tetragon.CapFilter.permitted:type_name -> tetragon.CapFilterSet + 5, // 4: tetragon.CapFilter.effective:type_name -> tetragon.CapFilterSet + 5, // 5: tetragon.CapFilter.inheritable:type_name -> tetragon.CapFilterSet + 15, // 6: tetragon.CapFilterSet.any:type_name -> tetragon.CapabilitiesType + 15, // 7: tetragon.CapFilterSet.all:type_name -> tetragon.CapabilitiesType + 15, // 8: tetragon.CapFilterSet.exactly:type_name -> tetragon.CapabilitiesType + 15, // 9: tetragon.CapFilterSet.none:type_name -> tetragon.CapabilitiesType + 3, // 10: tetragon.RedactionFilter.match:type_name -> tetragon.Filter 0, // 11: tetragon.FieldFilter.event_set:type_name -> tetragon.EventType - 14, // 12: tetragon.FieldFilter.fields:type_name -> google.protobuf.FieldMask + 16, // 12: tetragon.FieldFilter.fields:type_name -> google.protobuf.FieldMask 1, // 13: tetragon.FieldFilter.action:type_name -> tetragon.FieldFilterAction - 12, // 14: tetragon.FieldFilter.invert_event_set:type_name -> google.protobuf.BoolValue - 2, // 15: tetragon.GetEventsRequest.allow_list:type_name -> tetragon.Filter - 2, // 16: tetragon.GetEventsRequest.deny_list:type_name -> tetragon.Filter - 8, // 17: tetragon.GetEventsRequest.aggregation_options:type_name -> tetragon.AggregationOptions - 6, // 18: tetragon.GetEventsRequest.field_filters:type_name -> tetragon.FieldFilter - 15, // 19: tetragon.AggregationOptions.window_size:type_name -> google.protobuf.Duration - 16, // 20: tetragon.GetEventsResponse.process_exec:type_name -> tetragon.ProcessExec - 17, // 21: tetragon.GetEventsResponse.process_exit:type_name -> tetragon.ProcessExit - 18, // 22: tetragon.GetEventsResponse.process_kprobe:type_name -> tetragon.ProcessKprobe - 19, // 23: tetragon.GetEventsResponse.process_tracepoint:type_name -> tetragon.ProcessTracepoint - 20, // 24: tetragon.GetEventsResponse.process_loader:type_name -> tetragon.ProcessLoader - 21, // 25: tetragon.GetEventsResponse.process_uprobe:type_name -> tetragon.ProcessUprobe - 22, // 26: tetragon.GetEventsResponse.test:type_name -> tetragon.Test - 10, // 27: tetragon.GetEventsResponse.rate_limit_info:type_name -> tetragon.RateLimitInfo - 23, // 28: tetragon.GetEventsResponse.time:type_name -> google.protobuf.Timestamp - 9, // 29: tetragon.GetEventsResponse.aggregation_info:type_name -> tetragon.AggregationInfo - 30, // [30:30] is the sub-list for method output_type - 30, // [30:30] is the sub-list for method input_type - 30, // [30:30] is the sub-list for extension type_name - 30, // [30:30] is the sub-list for extension extendee - 0, // [0:30] is the sub-list for field type_name + 14, // 14: tetragon.FieldFilter.invert_event_set:type_name -> google.protobuf.BoolValue + 3, // 15: tetragon.GetEventsRequest.allow_list:type_name -> tetragon.Filter + 3, // 16: tetragon.GetEventsRequest.deny_list:type_name -> tetragon.Filter + 9, // 17: tetragon.GetEventsRequest.aggregation_options:type_name -> tetragon.AggregationOptions + 7, // 18: tetragon.GetEventsRequest.field_filters:type_name -> tetragon.FieldFilter + 17, // 19: tetragon.AggregationOptions.window_size:type_name -> google.protobuf.Duration + 2, // 20: tetragon.ProcessThrottle.type:type_name -> tetragon.ThrottleType + 18, // 21: tetragon.GetEventsResponse.process_exec:type_name -> tetragon.ProcessExec + 19, // 22: tetragon.GetEventsResponse.process_exit:type_name -> tetragon.ProcessExit + 20, // 23: tetragon.GetEventsResponse.process_kprobe:type_name -> tetragon.ProcessKprobe + 21, // 24: tetragon.GetEventsResponse.process_tracepoint:type_name -> tetragon.ProcessTracepoint + 22, // 25: tetragon.GetEventsResponse.process_loader:type_name -> tetragon.ProcessLoader + 23, // 26: tetragon.GetEventsResponse.process_uprobe:type_name -> tetragon.ProcessUprobe + 12, // 27: tetragon.GetEventsResponse.process_throttle:type_name -> tetragon.ProcessThrottle + 24, // 28: tetragon.GetEventsResponse.test:type_name -> tetragon.Test + 11, // 29: tetragon.GetEventsResponse.rate_limit_info:type_name -> tetragon.RateLimitInfo + 25, // 30: tetragon.GetEventsResponse.time:type_name -> google.protobuf.Timestamp + 10, // 31: tetragon.GetEventsResponse.aggregation_info:type_name -> tetragon.AggregationInfo + 32, // [32:32] is the sub-list for method output_type + 32, // [32:32] is the sub-list for method input_type + 32, // [32:32] is the sub-list for extension type_name + 32, // [32:32] is the sub-list for extension extendee + 0, // [0:32] is the sub-list for field type_name } func init() { file_tetragon_events_proto_init() } @@ -1401,6 +1544,18 @@ func file_tetragon_events_proto_init() { } } file_tetragon_events_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProcessThrottle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tetragon_events_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetEventsResponse); i { case 0: return &v.state @@ -1413,13 +1568,14 @@ func file_tetragon_events_proto_init() { } } } - file_tetragon_events_proto_msgTypes[9].OneofWrappers = []interface{}{ + file_tetragon_events_proto_msgTypes[10].OneofWrappers = []interface{}{ (*GetEventsResponse_ProcessExec)(nil), (*GetEventsResponse_ProcessExit)(nil), (*GetEventsResponse_ProcessKprobe)(nil), (*GetEventsResponse_ProcessTracepoint)(nil), (*GetEventsResponse_ProcessLoader)(nil), (*GetEventsResponse_ProcessUprobe)(nil), + (*GetEventsResponse_ProcessThrottle)(nil), (*GetEventsResponse_Test)(nil), (*GetEventsResponse_RateLimitInfo)(nil), } @@ -1428,8 +1584,8 @@ func file_tetragon_events_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tetragon_events_proto_rawDesc, - NumEnums: 2, - NumMessages: 10, + NumEnums: 3, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.json.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.json.go index 44af480b37a..589d91748f7 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.json.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.json.go @@ -151,6 +151,22 @@ func (msg *RateLimitInfo) UnmarshalJSON(b []byte) error { }.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *ProcessThrottle) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseEnumNumbers: false, + EmitUnpopulated: false, + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *ProcessThrottle) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{ + DiscardUnknown: false, + }.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *GetEventsResponse) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto index 86ec34ce66f..f2bd554645f 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto @@ -25,6 +25,7 @@ enum EventType { PROCESS_TRACEPOINT = 10; PROCESS_LOADER = 11; PROCESS_UPROBE = 12; + PROCESS_THROTTLE = 27; TEST = 40000; RATE_LIMIT_INFO = 40001; @@ -151,6 +152,19 @@ message RateLimitInfo { uint64 number_of_dropped_process_events = 1; } +enum ThrottleType { + THROTTLE_UNKNOWN = 0; + THROTTLE_START = 1; + THROTTLE_STOP = 2; +} + +message ProcessThrottle { + // Throttle type + ThrottleType type = 1; + // Cgroup name + string cgroup = 2; +} + message GetEventsResponse { // The type-specific fields of an event. // @@ -169,6 +183,7 @@ message GetEventsResponse { ProcessTracepoint process_tracepoint = 10; ProcessLoader process_loader = 11; ProcessUprobe process_uprobe = 12; + ProcessThrottle process_throttle = 27; Test test = 40000; RateLimitInfo rate_limit_info = 40001; diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go index d414b79f26c..f418b3eaca8 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go @@ -159,6 +159,14 @@ func (event *RateLimitInfo) Encapsulate() IsGetEventsResponse_Event { } } +// Encapsulate implements the Event interface. +// Returns the event wrapped by its GetEventsResponse_* type. +func (event *ProcessThrottle) Encapsulate() IsGetEventsResponse_Event { + return &GetEventsResponse_ProcessThrottle{ + ProcessThrottle: event, + } +} + // UnwrapGetEventsResponse gets the inner event type from a GetEventsResponse func UnwrapGetEventsResponse(response *GetEventsResponse) interface{} { event := response.GetEvent() @@ -182,6 +190,8 @@ func UnwrapGetEventsResponse(response *GetEventsResponse) interface{} { return ev.ProcessLoader case *GetEventsResponse_RateLimitInfo: return ev.RateLimitInfo + case *GetEventsResponse_ProcessThrottle: + return ev.ProcessThrottle } return nil } From 0bf25ffddb6eba4f5b517586f2be8047415377b6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 27 Feb 2024 12:41:32 +0000 Subject: [PATCH 02/17] tetragon: Add cgroup rate ebpf logic Adding cgrouprate ebpf code that keeps track of cgroup rate in per cpu hash. We keep track of received events in 2 intervals and compute slide window rate based on current time. If the limit is crossed we throttle the cgroup and in following changes we will also send an event to user space. Signed-off-by: Jiri Olsa --- bpf/process/bpf_rate.h | 117 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 bpf/process/bpf_rate.h diff --git a/bpf/process/bpf_rate.h b/bpf/process/bpf_rate.h new file mode 100644 index 00000000000..9eb75f3dbe3 --- /dev/null +++ b/bpf/process/bpf_rate.h @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* Copyright Authors of Cilium */ + +#ifndef __RATE_H__ +#define __RATE_H__ + +#include "bpf_tracing.h" +#include "bpf_helpers.h" + +struct cgroup_rate_key { + __u64 id; +}; + +struct cgroup_rate_value { + __u64 curr; + __u64 prev; + __u64 time; + __u64 rate; + __u64 throttled; +}; + +struct cgroup_rate_options { + __u64 events; + __u64 interval; +}; + +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_HASH); + __uint(max_entries, 32768); + __type(key, struct cgroup_rate_key); + __type(value, struct cgroup_rate_value); +} cgroup_rate_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 1); + __type(key, __u32); + __type(value, struct cgroup_rate_options); +} cgroup_rate_options_map SEC(".maps"); + +static inline __attribute__((always_inline)) bool +cgroup_rate(void *ctx, struct msg_k8s *kube, __u64 time) +{ + struct cgroup_rate_options *opt; + struct cgroup_rate_key key = { + .id = kube->cgrpid, + }; + struct cgroup_rate_value *val; + __u64 delta, interval, slide; + __u32 zero = 0; + + opt = map_lookup_elem(&cgroup_rate_options_map, &zero); + if (!opt) + return true; + + interval = opt->interval; + if (!interval) + return true; + + val = map_lookup_elem(&cgroup_rate_map, &key); + if (!val) { + struct cgroup_rate_value new_value = { + .time = (time / interval) * interval, + .curr = 1, + }; + + map_update_elem(&cgroup_rate_map, &key, &new_value, 0); + return true; + } + + /* + * We split the time in interval windows and keep track of events + * of events count in current (val->curr) and previous (val->prev) + * intervals. + */ + + delta = time - val->time; + if (delta > interval) { + if (delta > 2 * interval) { + val->prev = 0; + val->time = (time / interval) * interval; + } else { + val->prev = val->curr; + val->time += interval; + } + val->curr = 0; + } + + val->curr++; + + /* + * We compute the size of the slide window in previous interval and + * based on that we compute partial amount of events from previous + * interval window. Then we add current interval count and we have + * rate value. + * + * val->time + * | + * <--- interval ----->|<--- interval ----->| + * | + * val->prev | val->curr + * |-------------------|----------- + * val->rate + * |-------------------| + * time + */ + + slide = interval - (time - val->time); + val->rate = (slide * val->prev) / interval + val->curr; + + if (!val->throttled && val->rate >= opt->events) + val->throttled = time; + + return !val->throttled; +} + +#endif /* __RATE_H__ */ From 23697bb6c99b129b0a3b89c1c54c9fd56af5c6ee Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 20 Mar 2024 13:09:01 +0000 Subject: [PATCH 03/17] tetragon: Add cgroup rate config option Adding --cgroup-rate=options to configure exec/fork/exit allowed cgroup rates. The option is in following format: 'events,interval' Example: --cgroup-rate="1000,1s" # 1000/second rate --cgroup-rate="10000,5s" # 10000/5 seconds rate Signed-off-by: Jiri Olsa --- docs/data/tetragon_flags.yaml | 3 +++ pkg/option/config.go | 2 ++ pkg/option/flags.go | 50 +++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/docs/data/tetragon_flags.yaml b/docs/data/tetragon_flags.yaml index 8cc5363d843..19c54e2e65d 100644 --- a/docs/data/tetragon_flags.yaml +++ b/docs/data/tetragon_flags.yaml @@ -8,6 +8,9 @@ options: usage: Location of Tetragon libs (btf and bpf files) - name: btf usage: Location of btf + - name: cgroup-rate + usage: | + Base sensor events cgroup rate disabled by default ('1000/1s' means rate 1000 events per second - name: config-dir usage: Configuration directory that contains a file for each option - name: cpuprofile diff --git a/pkg/option/config.go b/pkg/option/config.go index 2dd63d1ffde..562e7474c3e 100644 --- a/pkg/option/config.go +++ b/pkg/option/config.go @@ -86,6 +86,8 @@ type config struct { EnableTracingPolicyCRD bool ExposeStackAddresses bool + + CgroupRate CgroupRate } var ( diff --git a/pkg/option/flags.go b/pkg/option/flags.go index bd6160638d4..e904d53b25f 100644 --- a/pkg/option/flags.go +++ b/pkg/option/flags.go @@ -5,6 +5,8 @@ package option import ( "fmt" + "strconv" + "strings" "time" "github.com/cilium/tetragon/pkg/defaults" @@ -94,6 +96,8 @@ const ( KeyExposeKernelAddresses = "expose-kernel-addresses" KeyGenerateDocs = "generate-docs" + + KeyCgroupRate = "cgroup-rate" ) func ReadAndSetFlags() error { @@ -182,9 +186,54 @@ func ReadAndSetFlags() error { Config.ExposeStackAddresses = viper.GetBool(KeyExposeStackAddresses) } + Config.CgroupRate = ParseCgroupRate(viper.GetString(KeyCgroupRate)) return nil } +type CgroupRate struct { + Events uint64 + Interval uint64 +} + +func ParseCgroupRate(rate string) CgroupRate { + empty := CgroupRate{} + + if rate == "" { + return empty + } + + s := strings.Split(rate, ",") + if len(s) != 2 { + logger.GetLogger().Warnf("failed to parse cgroup rate '%s'", rate) + return empty + } + + var interval time.Duration + var events int + var err error + + if len(s[0]) > 0 { + events, err = strconv.Atoi(s[0]) + if err != nil { + logger.GetLogger().Warnf("failed to parse cgroup rate '%s' : %s", rate, err) + return empty + } + } + + if len(s[1]) > 0 { + interval, err = time.ParseDuration(s[1]) + if err != nil { + logger.GetLogger().Warnf("failed to parse cgroup rate '%s' : %s", rate, err) + return empty + } + } + + return CgroupRate{ + Events: uint64(events), + Interval: uint64(interval), + } +} + func AddFlags(flags *pflag.FlagSet) { flags.String(KeyConfigDir, "", "Configuration directory that contains a file for each option") flags.BoolP(KeyDebug, "d", false, "Enable debug messages. Equivalent to '--log-level=debug'") @@ -286,4 +335,5 @@ func AddFlags(flags *pflag.FlagSet) { flags.Bool(KeyGenerateDocs, false, "Generate documentation in YAML format to stdout") + flags.String(KeyCgroupRate, "", "Base sensor events cgroup rate disabled by default ('1000/1s' means rate 1000 events per second") } From 5d11a35133712bde6c01dfe4b3497d349053b4f6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 20 Mar 2024 09:22:03 +0000 Subject: [PATCH 04/17] tetragon: Add cgroup rate rmdir sensor Adding cgroup rate rmdir sensor to clean up cgroup_rate_map entries. At the moment it's only removal of the cgroup_rate_map entry, so doing it unconditionally, because the overhead is negligent. Signed-off-by: Jiri Olsa --- bpf/Makefile | 1 + bpf/process/bpf_cgroup.c | 17 +++++++++++++++++ bpf/process/bpf_rate.h | 6 ++++++ pkg/option/config.go | 4 ++++ pkg/sensors/base/base.go | 12 ++++++++++++ pkg/testutils/sensors/load.go | 9 +++++++++ 6 files changed, 49 insertions(+) create mode 100644 bpf/process/bpf_cgroup.c diff --git a/bpf/Makefile b/bpf/Makefile index cdf4cd56401..c4477849604 100644 --- a/bpf/Makefile +++ b/bpf/Makefile @@ -27,6 +27,7 @@ PROCESS = bpf_execve_event.o bpf_execve_event_v53.o bpf_fork.o bpf_exit.o bpf_ge bpf_multi_kprobe_v511.o bpf_multi_retkprobe_v511.o \ bpf_generic_uprobe_v511.o \ bpf_loader.o \ + bpf_cgroup.o \ bpf_enforcer.o bpf_multi_enforcer.o bpf_fmodret_enforcer.o CGROUP = bpf_cgroup_mkdir.o bpf_cgroup_rmdir.o bpf_cgroup_release.o diff --git a/bpf/process/bpf_cgroup.c b/bpf/process/bpf_cgroup.c new file mode 100644 index 00000000000..5583909160c --- /dev/null +++ b/bpf/process/bpf_cgroup.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* Copyright Authors of Cilium */ + +#include "vmlinux.h" +#include "bpf_cgroup.h" +#include "bpf_rate.h" + +char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; + +__attribute__((section(("raw_tracepoint/cgroup_rmdir")), used)) int +tg_cgroup_rmdir(struct bpf_raw_tracepoint_args *ctx) +{ + struct cgroup *cgrp = (struct cgroup *)ctx->args[0]; + + cgroup_rate_del(get_cgroup_id(cgrp)); + return 0; +} diff --git a/bpf/process/bpf_rate.h b/bpf/process/bpf_rate.h index 9eb75f3dbe3..277f4b75f4c 100644 --- a/bpf/process/bpf_rate.h +++ b/bpf/process/bpf_rate.h @@ -114,4 +114,10 @@ cgroup_rate(void *ctx, struct msg_k8s *kube, __u64 time) return !val->throttled; } +static inline __attribute__((always_inline)) void +cgroup_rate_del(__u64 cgroupid) +{ + map_delete_elem(&cgroup_rate_map, &cgroupid); +} + #endif /* __RATE_H__ */ diff --git a/pkg/option/config.go b/pkg/option/config.go index 562e7474c3e..b5ca5062016 100644 --- a/pkg/option/config.go +++ b/pkg/option/config.go @@ -108,6 +108,10 @@ var ( } ) +func CgroupRateEnabled() bool { + return Config.CgroupRate.Events != 0 && Config.CgroupRate.Interval != 0 +} + // ReadDirConfig reads the given directory and returns a map that maps the // filename to the contents of that file. func ReadDirConfig(dirName string) (map[string]interface{}, error) { diff --git a/pkg/sensors/base/base.go b/pkg/sensors/base/base.go index d6afd579b54..5f1d08bab6d 100644 --- a/pkg/sensors/base/base.go +++ b/pkg/sensors/base/base.go @@ -10,6 +10,7 @@ import ( "github.com/cilium/tetragon/pkg/kernels" "github.com/cilium/tetragon/pkg/ksyms" "github.com/cilium/tetragon/pkg/logger" + "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/sensors" "github.com/cilium/tetragon/pkg/sensors/program" ) @@ -47,6 +48,14 @@ var ( "kprobe", ) + CgroupRmdir = program.Builder( + "bpf_cgroup.o", + "cgroup/cgroup_rmdir", + "raw_tracepoint/cgroup_rmdir", + "tg_cgroup_rmdir", + "raw_tracepoint", + ) + /* Event Ring map */ TCPMonMap = program.MapBuilder("tcpmon_map", Execve) /* Networking and Process Monitoring maps */ @@ -108,6 +117,9 @@ func GetDefaultPrograms() []*program.Program { Execve, ExecveBprmCommit, } + if option.CgroupRateEnabled() { + progs = append(progs, CgroupRmdir) + } return progs } diff --git a/pkg/testutils/sensors/load.go b/pkg/testutils/sensors/load.go index 2d34ef05adb..3e4056d41f3 100644 --- a/pkg/testutils/sensors/load.go +++ b/pkg/testutils/sensors/load.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/cilium/ebpf" + "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/sensors" "github.com/cilium/tetragon/pkg/sensors/program" ) @@ -156,6 +157,14 @@ func mergeInBaseSensorMaps(t *testing.T, sensorMaps []SensorMap, sensorProgs []S SensorMap{Name: "tg_execve_joined_info_map_stats", Progs: []uint{0, 4}}, } + if option.CgroupRateEnabled() { + /* 5: tg_cgroup_rmdir */ + sensorProgs = append(sensorProgs, SensorProg{Name: "tg_cgroup_rmdir", Type: ebpf.RawTracepoint}) + + /* cgroup_rate_map */ + baseMaps = append(baseMaps, SensorMap{Name: "cgroup_rate_map", Progs: []uint{1, 2, 5}}) + } + return mergeSensorMaps(t, sensorMaps, baseMaps, sensorProgs, baseProgs) } From 91bbef39053fc01c661903cd3a49572de7401706 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 23 Mar 2024 14:17:42 +0000 Subject: [PATCH 05/17] tetragon: Add cgroup rate object Adding base cgrouprate object which will be updated in following changes Signed-off-by: Jiri Olsa --- pkg/cgrouprate/cgrouprate.go | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 pkg/cgrouprate/cgrouprate.go diff --git a/pkg/cgrouprate/cgrouprate.go b/pkg/cgrouprate/cgrouprate.go new file mode 100644 index 00000000000..99369cddedf --- /dev/null +++ b/pkg/cgrouprate/cgrouprate.go @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package cgrouprate + +import ( + "context" + "sync" + + "github.com/cilium/tetragon/pkg/logger" + "github.com/cilium/tetragon/pkg/observer" + "github.com/cilium/tetragon/pkg/reader/notify" + "github.com/sirupsen/logrus" +) + +var ( + handle *CgroupRate + handleLock sync.RWMutex +) + +type CgroupRate struct { + listener observer.Listener + log logrus.FieldLogger +} + +func newCgroupRate(listener observer.Listener) *CgroupRate { + return &CgroupRate{ + listener: listener, + log: logger.GetLogger(), + } +} + +func NewCgroupRate(ctx context.Context, + listener observer.Listener) { + + handleLock.Lock() + defer handleLock.Unlock() + + handle = newCgroupRate(listener) + go handle.process(ctx) +} + +func (r *CgroupRate) notify(msg notify.Message) { + if err := r.listener.Notify(msg); err != nil { + r.log.WithError(err).Warn("failed to notify listener") + } +} + +func (r *CgroupRate) process(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + } + } +} From fc326d371c8a6c1deb229019d4aa1944300d5fe4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 23 Mar 2024 15:22:44 +0000 Subject: [PATCH 06/17] tetragon: Add cgroup rate logic Adding cgrouprate logic for checking on cgroup rate limit. - cgrouprate channel is fed with cgroups that crossed the rate limit through Check function - cgrouprate keeps list of active (throttled) cgroups and periodically checks if the cgroup rate dropped down - throttle stop event is sent if the rate drops down under the limit or the cgroup has no traffic for more than 5 seconds Signed-off-by: Jiri Olsa --- pkg/api/processapi/processapi.go | 17 +++ pkg/cgrouprate/cgrouprate.go | 193 ++++++++++++++++++++++++++++++- 2 files changed, 207 insertions(+), 3 deletions(-) diff --git a/pkg/api/processapi/processapi.go b/pkg/api/processapi/processapi.go index 6c2753ef52f..a91704fb6ce 100644 --- a/pkg/api/processapi/processapi.go +++ b/pkg/api/processapi/processapi.go @@ -220,3 +220,20 @@ type MsgCgroupEvent struct { type KernelStats struct { SentFailed [256]uint64 `align:"sent_failed"` } + +type CgroupRateKey struct { + Id uint64 +} + +type CgroupRateValue struct { + Curr uint64 + Prev uint64 + Time uint64 + Rate uint64 + Throttled uint64 +} + +type CgroupRateOptions struct { + Events uint64 + Interval uint64 +} diff --git a/pkg/cgrouprate/cgrouprate.go b/pkg/cgrouprate/cgrouprate.go index 99369cddedf..df56b7c4070 100644 --- a/pkg/cgrouprate/cgrouprate.go +++ b/pkg/cgrouprate/cgrouprate.go @@ -1,42 +1,96 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Authors of Tetragon +// cgrouprate - user space part of cgroup rate monitoring +// +// In nutshell we compute/monitor the rate per cpu via ebpf cgroup_rate +// function (bpf/process/bpf_rate.h) that sends throttle event to user +// space when the rate for cgroup crosses limit on the given cpu. +// +// At the moment we monitor cgroup rate for exec/fork/exit events. +// +// The user space (cgrouprate object) then triggers throttle start event +// and starts timer to periodically check on the cgroup rate. When the +// rate goes down or the cpu gets idle (and all other cpus rates are ok) +// we send throttle stop event. +// +// Having throttle start event means that one or more cpus that execute +// cgroup code crossed the limit and are throttled (paused). +// Having throttle stop events means that all previously throttled cpus +// are now below allowed limit rate and sends events. + package cgrouprate import ( "context" "sync" + "time" + "github.com/cilium/tetragon/pkg/api/processapi" + "github.com/cilium/tetragon/pkg/bpf" + "github.com/cilium/tetragon/pkg/ktime" "github.com/cilium/tetragon/pkg/logger" "github.com/cilium/tetragon/pkg/observer" + "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/reader/notify" + "github.com/cilium/tetragon/pkg/sensors/program" "github.com/sirupsen/logrus" ) +const ( + aliveCnt = 5 +) + var ( handle *CgroupRate handleLock sync.RWMutex ) +type cgroupQueue struct { + id uint64 + ktime uint64 + name string +} + type CgroupRate struct { listener observer.Listener log logrus.FieldLogger + ch chan *cgroupQueue + opts *option.CgroupRate + hash *program.Map + cgroups map[uint64]string } -func newCgroupRate(listener observer.Listener) *CgroupRate { +func newCgroupRate( + listener observer.Listener, + hash *program.Map, + opts *option.CgroupRate) *CgroupRate { + return &CgroupRate{ listener: listener, log: logger.GetLogger(), + cgroups: make(map[uint64]string), + ch: make(chan *cgroupQueue), + hash: hash, + opts: opts, } } func NewCgroupRate(ctx context.Context, - listener observer.Listener) { + listener observer.Listener, + hash *program.Map, + opts *option.CgroupRate) { + + if opts.Events == 0 || opts.Interval == 0 { + logger.GetLogger().Infof("Cgroup rate disabled (%d/%s)", + opts.Events, time.Duration(opts.Interval).String()) + return + } handleLock.Lock() defer handleLock.Unlock() - handle = newCgroupRate(listener) + handle = newCgroupRate(listener, hash, opts) go handle.process(ctx) } @@ -47,10 +101,143 @@ func (r *CgroupRate) notify(msg notify.Message) { } func (r *CgroupRate) process(ctx context.Context) { + ticker := time.NewTicker(time.Second) + r.log.Infof("Cgroup rate started (%d/%s)", + r.opts.Events, time.Duration(r.opts.Interval).String()) + for { select { case <-ctx.Done(): + ticker.Stop() return + case cq := <-r.ch: + r.updateCgroups(cq) + case <-ticker.C: + r.processCgroups() + } + } +} + +func (r *CgroupRate) updateCgroups(cq *cgroupQueue) { + if _, ok := r.cgroups[cq.id]; ok { + // the group is guaranteed to be checked on next timer + return + } + + r.cgroups[cq.id] = cq.name + + // start throttle event +} + +func (r *CgroupRate) processCgroups() { + var remove []uint64 + + if r.hash.MapHandle == nil { + return + } + + last, err := ktime.Monotonic() + if err != nil { + return + } + + for id, cgroup := range r.cgroups { + if r.processCgroup(id, cgroup, uint64(last)) { + remove = append(remove, id) } } + + for _, id := range remove { + delete(r.cgroups, id) + } +} + +func (r *CgroupRate) processCgroup(id uint64, cgroup string, last uint64) bool { + key := processapi.CgroupRateKey{ + Id: id, + } + values := make([]processapi.CgroupRateValue, bpf.GetNumPossibleCPUs()) + + hash := r.hash.MapHandle + + if err := hash.Lookup(key, &values); err != nil { + // cgroup got likely removed, remove it as well + return true + } + + stop := true + + for _, val := range values { + // cpu is silent long enough + if last > val.Time+uint64(aliveCnt*time.Second) { + continue + } + // cpu rate is ok and we did pause for aliveCnt seconds + if val.Rate < r.opts.Events && last > val.Throttled+uint64(aliveCnt*time.Second) { + continue + } + stop = false + } + + if stop { + // We do race with ebpf cgroup_rate code in here. But in case + // there's enough events to cross the limit, the cgroup will get + // throttled with the next event and in opposite case where the + // rate does not cross the limit we do nothing. + for idx := range values { + // pending throttle stop + values[idx].Throttled = 0 + } + if err := hash.Put(key, values); err != nil { + handle.log.WithError(err).Warn("failed to update cgroup rate values") + } + // stop throttle event + return true + } + + return false +} + +// Called from event handlers to kick off the cgroup rate +// periodical check for event's cgroup. +func Check(kube *processapi.MsgK8s, ktime uint64) { + if handle == nil { + return + } + + handleLock.RLock() + defer handleLock.RUnlock() + + if handle == nil { + return + } + + cq := &cgroupQueue{ + id: kube.Cgrpid, + ktime: ktime, + name: string(kube.Docker[:]), + } + + handle.ch <- cq +} + +func Config(optsMap *program.Map) { + if handle == nil { + return + } + + if optsMap.MapHandle == nil { + handle.log.Warn("failed to update cgroup rate options map") + return + } + + key := uint32(0) + opts := processapi.CgroupRateOptions{ + Events: handle.opts.Events, + Interval: handle.opts.Interval, + } + + if err := optsMap.MapHandle.Put(key, opts); err != nil { + handle.log.WithError(err).Warn("failed to update cgroup rate options map") + } } From 8a40cd975f7e6efd265ea8c8887f1eb3c56f8533 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Apr 2024 21:24:10 +0000 Subject: [PATCH 07/17] tetragon: Add cgroup rate throttle event Adding throttle event that is sent from cgroup_rate function when the rate limit is crossed and the cgroup is not throttled. Signed-off-by: Jiri Olsa --- bpf/lib/msg_types.h | 2 ++ bpf/process/bpf_rate.h | 38 +++++++++++++++++++++++++++++++- pkg/api/ops/ops.go | 2 ++ pkg/api/processapi/processapi.go | 5 +++++ pkg/cgrouprate/cgrouprate.go | 12 ++++++++++ pkg/grpc/tracing/tracing.go | 35 +++++++++++++++++++++++++++++ pkg/sensors/exec/exec.go | 12 ++++++++++ 7 files changed, 105 insertions(+), 1 deletion(-) diff --git a/bpf/lib/msg_types.h b/bpf/lib/msg_types.h index 30e41e7e4ae..4dd54b39440 100644 --- a/bpf/lib/msg_types.h +++ b/bpf/lib/msg_types.h @@ -31,6 +31,8 @@ enum msg_ops { MSG_OP_LOADER = 26, + MSG_OP_THROTTLE = 27, + MSG_OP_MAX, }; diff --git a/bpf/process/bpf_rate.h b/bpf/process/bpf_rate.h index 277f4b75f4c..9395500487a 100644 --- a/bpf/process/bpf_rate.h +++ b/bpf/process/bpf_rate.h @@ -6,6 +6,7 @@ #include "bpf_tracing.h" #include "bpf_helpers.h" +#include "msg_types.h" struct cgroup_rate_key { __u64 id; @@ -38,6 +39,39 @@ struct { __type(value, struct cgroup_rate_options); } cgroup_rate_options_map SEC(".maps"); +struct msg_throttle { + struct msg_common common; + struct msg_k8s kube; +}; + +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __uint(max_entries, 1); + __type(key, __u32); + __type(value, struct msg_throttle); +} throttle_heap_map SEC(".maps"); + +static inline __attribute__((always_inline)) void +send_throttle(void *ctx, struct msg_k8s *kube, __u64 time) +{ + struct msg_throttle *msg; + size_t size = sizeof(*msg); + + msg = map_lookup_elem(&throttle_heap_map, &(__u32){ 0 }); + if (!msg) + return; + + msg->common.size = size; + msg->common.ktime = time; + msg->common.op = MSG_OP_THROTTLE; + msg->common.flags = 0; + + __builtin_memcpy(&msg->kube, kube, sizeof(*kube)); + + perf_event_output_metric(ctx, MSG_OP_THROTTLE, &tcpmon_map, + BPF_F_CURRENT_CPU, msg, size); +} + static inline __attribute__((always_inline)) bool cgroup_rate(void *ctx, struct msg_k8s *kube, __u64 time) { @@ -108,8 +142,10 @@ cgroup_rate(void *ctx, struct msg_k8s *kube, __u64 time) slide = interval - (time - val->time); val->rate = (slide * val->prev) / interval + val->curr; - if (!val->throttled && val->rate >= opt->events) + if (!val->throttled && val->rate >= opt->events) { val->throttled = time; + send_throttle(ctx, kube, time); + } return !val->throttled; } diff --git a/pkg/api/ops/ops.go b/pkg/api/ops/ops.go index 29d681dafa8..d62111ed9a0 100644 --- a/pkg/api/ops/ops.go +++ b/pkg/api/ops/ops.go @@ -33,6 +33,8 @@ const ( MSG_OP_LOADER = 26 + MSG_OP_THROTTLE = 27 + // just for testing MSG_OP_TEST = 254 ) diff --git a/pkg/api/processapi/processapi.go b/pkg/api/processapi/processapi.go index a91704fb6ce..6004b5a9f9d 100644 --- a/pkg/api/processapi/processapi.go +++ b/pkg/api/processapi/processapi.go @@ -217,6 +217,11 @@ type MsgCgroupEvent struct { Path [CGROUP_PATH_LENGTH]byte `align:"path"` // Full path of the cgroup on fs } +type MsgThrottleEvent struct { + Common MsgCommon + Kube MsgK8s +} + type KernelStats struct { SentFailed [256]uint64 `align:"sent_failed"` } diff --git a/pkg/cgrouprate/cgrouprate.go b/pkg/cgrouprate/cgrouprate.go index df56b7c4070..1a98b23f281 100644 --- a/pkg/cgrouprate/cgrouprate.go +++ b/pkg/cgrouprate/cgrouprate.go @@ -26,8 +26,10 @@ import ( "sync" "time" + "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/api/processapi" "github.com/cilium/tetragon/pkg/bpf" + "github.com/cilium/tetragon/pkg/grpc/tracing" "github.com/cilium/tetragon/pkg/ktime" "github.com/cilium/tetragon/pkg/logger" "github.com/cilium/tetragon/pkg/observer" @@ -127,6 +129,11 @@ func (r *CgroupRate) updateCgroups(cq *cgroupQueue) { r.cgroups[cq.id] = cq.name // start throttle event + r.notify(&tracing.MsgProcessThrottleUnix{ + Type: tetragon.ThrottleType_THROTTLE_START, + Cgroup: cq.name, + Ktime: cq.ktime, + }) } func (r *CgroupRate) processCgroups() { @@ -192,6 +199,11 @@ func (r *CgroupRate) processCgroup(id uint64, cgroup string, last uint64) bool { handle.log.WithError(err).Warn("failed to update cgroup rate values") } // stop throttle event + r.notify(&tracing.MsgProcessThrottleUnix{ + Type: tetragon.ThrottleType_THROTTLE_STOP, + Cgroup: cgroup, + Ktime: last, + }) return true } diff --git a/pkg/grpc/tracing/tracing.go b/pkg/grpc/tracing/tracing.go index e3a36e01714..1b35fdba258 100644 --- a/pkg/grpc/tracing/tracing.go +++ b/pkg/grpc/tracing/tracing.go @@ -814,3 +814,38 @@ func (msg *MsgGenericUprobeUnix) Cast(o interface{}) notify.Message { t := o.(MsgGenericUprobeUnix) return &t } + +type MsgProcessThrottleUnix struct { + Type tetragon.ThrottleType + Cgroup string + Ktime uint64 +} + +func (msg *MsgProcessThrottleUnix) Notify() bool { + return true +} + +func (msg *MsgProcessThrottleUnix) RetryInternal(_ notify.Event, _ uint64) (*process.ProcessInternal, error) { + return nil, fmt.Errorf("Unreachable state: MsgProcessThrottleUnix RetryInternal() was called") +} + +func (msg *MsgProcessThrottleUnix) Retry(_ *process.ProcessInternal, _ notify.Event) error { + return fmt.Errorf("Unreachable state: MsgProcessThrottleUnix Retry() was called") +} + +func (msg *MsgProcessThrottleUnix) HandleMessage() *tetragon.GetEventsResponse { + event := &tetragon.ProcessThrottle{ + Type: msg.Type, + Cgroup: msg.Cgroup, + } + return &tetragon.GetEventsResponse{ + Event: &tetragon.GetEventsResponse_ProcessThrottle{ProcessThrottle: event}, + NodeName: nodeName, + Time: ktime.ToProto(msg.Ktime), + } +} + +func (msg *MsgProcessThrottleUnix) Cast(o interface{}) notify.Message { + t := o.(MsgProcessThrottleUnix) + return &t +} diff --git a/pkg/sensors/exec/exec.go b/pkg/sensors/exec/exec.go index 561743d8790..dbca3f3dd8f 100644 --- a/pkg/sensors/exec/exec.go +++ b/pkg/sensors/exec/exec.go @@ -13,6 +13,7 @@ import ( "github.com/cilium/tetragon/pkg/api/dataapi" "github.com/cilium/tetragon/pkg/api/ops" "github.com/cilium/tetragon/pkg/api/processapi" + "github.com/cilium/tetragon/pkg/cgrouprate" "github.com/cilium/tetragon/pkg/cgroups" exec "github.com/cilium/tetragon/pkg/grpc/exec" "github.com/cilium/tetragon/pkg/logger" @@ -224,6 +225,16 @@ func handleCgroupEvent(r *bytes.Reader) ([]observer.Event, error) { return []observer.Event{msgUnix}, nil } +func handleThrottleEvent(r *bytes.Reader) ([]observer.Event, error) { + m := processapi.MsgThrottleEvent{} + err := binary.Read(r, binary.LittleEndian, &m) + if err != nil { + return nil, err + } + cgrouprate.Check(&m.Kube, m.Common.Ktime) + return nil, nil +} + type execProbe struct{} func (e *execProbe) LoadProbe(args sensors.LoadProbeArgs) error { @@ -245,4 +256,5 @@ func AddExec() { observer.RegisterEventHandlerAtInit(ops.MSG_OP_EXIT, handleExit) observer.RegisterEventHandlerAtInit(ops.MSG_OP_CLONE, handleClone) observer.RegisterEventHandlerAtInit(ops.MSG_OP_CGROUP, handleCgroupEvent) + observer.RegisterEventHandlerAtInit(ops.MSG_OP_THROTTLE, handleThrottleEvent) } From 672f758347a079074790febe2c7a36b6fa869109 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 14 Apr 2024 09:48:24 +0000 Subject: [PATCH 08/17] tetragon: Add cgroup rate metrics Adding several metrics to help debug/diagnose the cgrouprate code. Signed-off-by: Jiri Olsa --- pkg/cgrouprate/cgrouprate.go | 10 +++- .../cgroupratemetrics/cgroupratemetrics.go | 56 +++++++++++++++++++ pkg/metrics/metricsconfig/initmetrics.go | 2 + 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 pkg/metrics/cgroupratemetrics/cgroupratemetrics.go diff --git a/pkg/cgrouprate/cgrouprate.go b/pkg/cgrouprate/cgrouprate.go index 1a98b23f281..7ae516f2a4a 100644 --- a/pkg/cgrouprate/cgrouprate.go +++ b/pkg/cgrouprate/cgrouprate.go @@ -32,6 +32,7 @@ import ( "github.com/cilium/tetragon/pkg/grpc/tracing" "github.com/cilium/tetragon/pkg/ktime" "github.com/cilium/tetragon/pkg/logger" + "github.com/cilium/tetragon/pkg/metrics/cgroupratemetrics" "github.com/cilium/tetragon/pkg/observer" "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/reader/notify" @@ -134,6 +135,7 @@ func (r *CgroupRate) updateCgroups(cq *cgroupQueue) { Cgroup: cq.name, Ktime: cq.ktime, }) + cgroupratemetrics.CgroupRateTotalInc(cgroupratemetrics.ThrottleStart) } func (r *CgroupRate) processCgroups() { @@ -166,8 +168,10 @@ func (r *CgroupRate) processCgroup(id uint64, cgroup string, last uint64) bool { values := make([]processapi.CgroupRateValue, bpf.GetNumPossibleCPUs()) hash := r.hash.MapHandle + cgroupratemetrics.CgroupRateTotalInc(cgroupratemetrics.Process) if err := hash.Lookup(key, &values); err != nil { + cgroupratemetrics.CgroupRateTotalInc(cgroupratemetrics.LookupFail) // cgroup got likely removed, remove it as well return true } @@ -196,7 +200,7 @@ func (r *CgroupRate) processCgroup(id uint64, cgroup string, last uint64) bool { values[idx].Throttled = 0 } if err := hash.Put(key, values); err != nil { - handle.log.WithError(err).Warn("failed to update cgroup rate values") + cgroupratemetrics.CgroupRateTotalInc(cgroupratemetrics.UpdateFail) } // stop throttle event r.notify(&tracing.MsgProcessThrottleUnix{ @@ -204,6 +208,7 @@ func (r *CgroupRate) processCgroup(id uint64, cgroup string, last uint64) bool { Cgroup: cgroup, Ktime: last, }) + cgroupratemetrics.CgroupRateTotalInc(cgroupratemetrics.ThrottleStop) return true } @@ -231,6 +236,7 @@ func Check(kube *processapi.MsgK8s, ktime uint64) { } handle.ch <- cq + cgroupratemetrics.CgroupRateTotalInc(cgroupratemetrics.Check) } func Config(optsMap *program.Map) { @@ -250,6 +256,6 @@ func Config(optsMap *program.Map) { } if err := optsMap.MapHandle.Put(key, opts); err != nil { - handle.log.WithError(err).Warn("failed to update cgroup rate options map") + cgroupratemetrics.CgroupRateTotalInc(cgroupratemetrics.UpdateFail) } } diff --git a/pkg/metrics/cgroupratemetrics/cgroupratemetrics.go b/pkg/metrics/cgroupratemetrics/cgroupratemetrics.go new file mode 100644 index 00000000000..1d502281cd8 --- /dev/null +++ b/pkg/metrics/cgroupratemetrics/cgroupratemetrics.go @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package cgroupratemetrics + +import ( + "github.com/cilium/tetragon/pkg/metrics/consts" + "github.com/prometheus/client_golang/prometheus" +) + +type CgroupRateType int + +const ( + ThrottleStart CgroupRateType = iota + ThrottleStop + LookupFail + UpdateFail + Check + Process +) + +var totalLabelValues = map[CgroupRateType]string{ + ThrottleStart: "throttle_start", + ThrottleStop: "throttle_stop", + LookupFail: "lookup_fail", + UpdateFail: "update_fail", + Check: "check", + Process: "process", +} + +func (e CgroupRateType) String() string { + return totalLabelValues[e] +} + +var ( + CgroupRateTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: consts.MetricsNamespace, + Name: "cgroup_rate_total", + Help: "The total number of Tetragon cgroup rate counters. For internal use only.", + ConstLabels: nil, + }, []string{"type"}) +) + +func InitMetrics(registry *prometheus.Registry) { + registry.MustRegister(CgroupRateTotal) +} + +// Get a new handle on an ErrorTotal metric for an ErrorType +func GetCgroupRateTotal(cr CgroupRateType) prometheus.Counter { + return CgroupRateTotal.WithLabelValues(cr.String()) +} + +// Increment an CgroupRateTotal for an CgroupRateType +func CgroupRateTotalInc(er CgroupRateType) { + GetCgroupRateTotal(er).Inc() +} diff --git a/pkg/metrics/metricsconfig/initmetrics.go b/pkg/metrics/metricsconfig/initmetrics.go index a64f8b2c786..9157b8b8b45 100644 --- a/pkg/metrics/metricsconfig/initmetrics.go +++ b/pkg/metrics/metricsconfig/initmetrics.go @@ -7,6 +7,7 @@ import ( "github.com/cilium/tetragon/pkg/eventcache" "github.com/cilium/tetragon/pkg/exporter" "github.com/cilium/tetragon/pkg/grpc/tracing" + "github.com/cilium/tetragon/pkg/metrics/cgroupratemetrics" "github.com/cilium/tetragon/pkg/metrics/errormetrics" "github.com/cilium/tetragon/pkg/metrics/eventcachemetrics" "github.com/cilium/tetragon/pkg/metrics/eventmetrics" @@ -45,6 +46,7 @@ func initHealthMetrics(registry *prometheus.Registry) { tracing.InitMetrics(registry) ratelimitmetrics.InitMetrics(registry) exporter.InitMetrics(registry) + cgroupratemetrics.InitMetrics(registry) // register common third-party collectors registry.MustRegister(grpcmetrics.NewServerMetrics()) From 5637911392b186d934ca4ebc183077d7127c6d63 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 27 Mar 2024 13:39:14 +0000 Subject: [PATCH 09/17] tetragon: Add cgrouprate instance for tetragon and tests Create cgrouprate instance for tetragon and for observer test helper plus adding and configuring related maps in base sensor. Signed-off-by: Jiri Olsa --- cmd/tetragon/main.go | 4 ++++ pkg/observer/observertesthelper/observer_test_helper.go | 5 +++++ pkg/sensors/base/base.go | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/cmd/tetragon/main.go b/cmd/tetragon/main.go index 1467aa34b56..1071c891662 100644 --- a/cmd/tetragon/main.go +++ b/cmd/tetragon/main.go @@ -26,6 +26,7 @@ import ( "github.com/cilium/tetragon/pkg/bpf" "github.com/cilium/tetragon/pkg/btf" "github.com/cilium/tetragon/pkg/bugtool" + "github.com/cilium/tetragon/pkg/cgrouprate" "github.com/cilium/tetragon/pkg/checkprocfs" "github.com/cilium/tetragon/pkg/cilium" "github.com/cilium/tetragon/pkg/defaults" @@ -457,6 +458,9 @@ func tetragonExecute() error { initialSensor.Unload() }() + cgrouprate.NewCgroupRate(ctx, pm, base.CgroupRateMap, &option.Config.CgroupRate) + cgrouprate.Config(base.CgroupRateOptionsMap) + // now that the base sensor was loaded, we can start the sensor manager close(sensorMgWait) sensorMgWait = nil diff --git a/pkg/observer/observertesthelper/observer_test_helper.go b/pkg/observer/observertesthelper/observer_test_helper.go index 27285bf140d..43a03a11be8 100644 --- a/pkg/observer/observertesthelper/observer_test_helper.go +++ b/pkg/observer/observertesthelper/observer_test_helper.go @@ -19,6 +19,7 @@ import ( "testing" "time" + "github.com/cilium/tetragon/pkg/cgrouprate" "github.com/cilium/tetragon/pkg/encoder" "github.com/cilium/tetragon/pkg/metrics" "github.com/cilium/tetragon/pkg/metrics/metricsconfig" @@ -247,6 +248,8 @@ func getDefaultObserver(tb testing.TB, ctx context.Context, initialSensor *senso return nil, err } + cgrouprate.Config(base.CgroupRateOptionsMap) + exportFname, err := testutils.GetExportFilename(tb) if err != nil { return nil, err @@ -430,6 +433,8 @@ func loadExporter(tb testing.TB, ctx context.Context, obs *observer.Observer, op tb.Cleanup(func() { obs.RemoveListener(processManager) }) + + cgrouprate.NewCgroupRate(ctx, processManager, base.CgroupRateMap, &option.Config.CgroupRate) return nil } diff --git a/pkg/sensors/base/base.go b/pkg/sensors/base/base.go index 5f1d08bab6d..46bac04bd37 100644 --- a/pkg/sensors/base/base.go +++ b/pkg/sensors/base/base.go @@ -72,6 +72,10 @@ var ( ExecveJoinMapStats = program.MapBuilder("tg_execve_joined_info_map_stats", ExecveBprmCommit) StatsMap = program.MapBuilder("tg_stats_map", Execve) + /* Cgroup rate data, attached to execve sensor */ + CgroupRateMap = program.MapBuilder("cgroup_rate_map", Execve) + CgroupRateOptionsMap = program.MapBuilder("cgroup_rate_options_map", Execve) + sensor = sensors.Sensor{ Name: "__base__", } @@ -134,6 +138,9 @@ func GetDefaultMaps() []*program.Map { TetragonConfMap, StatsMap, } + if option.CgroupRateEnabled() { + maps = append(maps, CgroupRateMap, CgroupRateOptionsMap) + } return maps } From fad1885896e8bc8cd0a8c5a4b3e0eec54e90baf1 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Apr 2024 12:42:04 +0000 Subject: [PATCH 10/17] tetragon: Add cgroup rate support for execve Adding support to control cgroup rate for execve events. Signed-off-by: Jiri Olsa --- bpf/process/bpf_execve_event.c | 20 ++++++++++++++++++-- pkg/testutils/sensors/load.go | 7 ++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/bpf/process/bpf_execve_event.c b/bpf/process/bpf_execve_event.c index 59612148bba..61d5c7e8c49 100644 --- a/bpf/process/bpf_execve_event.c +++ b/bpf/process/bpf_execve_event.c @@ -8,12 +8,13 @@ #include "bpf_task.h" #include "bpf_process_event.h" #include "bpf_helpers.h" +#include "bpf_rate.h" char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); - __uint(max_entries, 1); + __uint(max_entries, 2); __uint(key_size, sizeof(__u32)); __uint(value_size, sizeof(__u32)); } execve_calls SEC(".maps"); @@ -233,6 +234,21 @@ event_execve(struct trace_event_raw_sched_process_exec *ctx) return 0; } +__attribute__((section("tracepoint/0"), used)) int +execve_rate(void *ctx) +{ + struct msg_execve_event *msg; + __u32 zero = 0; + + msg = map_lookup_elem(&execve_msg_heap_map, &zero); + if (!msg) + return 0; + + if (cgroup_rate(ctx, &msg->kube, msg->common.ktime)) + tail_call(ctx, &execve_calls, 1); + return 0; +} + /** * execve_send() sends the collected execve event data. * @@ -240,7 +256,7 @@ event_execve(struct trace_event_raw_sched_process_exec *ctx) * is to update the pid execve_map entry to reflect the new execve event that * has already been collected, then send it to the perf buffer. */ -__attribute__((section("tracepoint/0"), used)) int +__attribute__((section("tracepoint/1"), used)) int execve_send(void *ctx) { struct msg_execve_event *event; diff --git a/pkg/testutils/sensors/load.go b/pkg/testutils/sensors/load.go index 3e4056d41f3..2fee681dab9 100644 --- a/pkg/testutils/sensors/load.go +++ b/pkg/testutils/sensors/load.go @@ -136,12 +136,13 @@ func mergeInBaseSensorMaps(t *testing.T, sensorMaps []SensorMap, sensorProgs []S 2: SensorProg{Name: "event_wake_up_new_task", Type: ebpf.Kprobe}, 3: SensorProg{Name: "execve_send", Type: ebpf.TracePoint}, 4: SensorProg{Name: "tg_kp_bprm_committing_creds", Type: ebpf.Kprobe}, + 5: SensorProg{Name: "execve_rate", Type: ebpf.TracePoint}, } var baseMaps = []SensorMap{ // all programs SensorMap{Name: "execve_map", Progs: []uint{0, 1, 2, 3, 4}}, - SensorMap{Name: "tcpmon_map", Progs: []uint{0, 1, 2, 3}}, + SensorMap{Name: "tcpmon_map", Progs: []uint{0, 1, 2, 3, 5}}, // all but event_execve SensorMap{Name: "execve_map_stats", Progs: []uint{1, 2}}, @@ -158,11 +159,11 @@ func mergeInBaseSensorMaps(t *testing.T, sensorMaps []SensorMap, sensorProgs []S } if option.CgroupRateEnabled() { - /* 5: tg_cgroup_rmdir */ + /* 6: tg_cgroup_rmdir */ sensorProgs = append(sensorProgs, SensorProg{Name: "tg_cgroup_rmdir", Type: ebpf.RawTracepoint}) /* cgroup_rate_map */ - baseMaps = append(baseMaps, SensorMap{Name: "cgroup_rate_map", Progs: []uint{1, 2, 5}}) + baseMaps = append(baseMaps, SensorMap{Name: "cgroup_rate_map", Progs: []uint{1, 2, 5, 6}}) } return mergeSensorMaps(t, sensorMaps, baseMaps, sensorProgs, baseProgs) From dd6608c10252074064fa3f6f174576f139a7330c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 24 Mar 2024 20:15:01 +0000 Subject: [PATCH 11/17] tetragon: Add cgroup rate support for clone Adding support to control cgroup rate for clone events. Signed-off-by: Jiri Olsa --- bpf/process/bpf_fork.c | 10 +++++++++- pkg/testutils/sensors/load.go | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/bpf/process/bpf_fork.c b/bpf/process/bpf_fork.c index 32c274504ac..db202297c59 100644 --- a/bpf/process/bpf_fork.c +++ b/bpf/process/bpf_fork.c @@ -10,6 +10,8 @@ #include "bpf_task.h" #include "environ_conf.h" #include "bpf_process_event.h" +#include "process.h" +#include "bpf_rate.h" char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; #ifdef VMLINUX_KERNEL_VERSION @@ -24,6 +26,7 @@ BPF_KPROBE(event_wake_up_new_task, struct task_struct *task) struct msg_clone_event msg; struct msg_capabilities caps; u64 msg_size = sizeof(struct msg_clone_event); + struct msg_k8s kube; u32 tgid = 0; if (!task) @@ -82,7 +85,12 @@ BPF_KPROBE(event_wake_up_new_task, struct task_struct *task) msg.nspid = curr->nspid; msg.flags = curr->flags; - perf_event_output_metric(ctx, MSG_OP_CLONE, &tcpmon_map, BPF_F_CURRENT_CPU, &msg, msg_size); + __event_get_cgroup_info(task, &kube); + + if (cgroup_rate(ctx, &kube, msg.ktime)) { + perf_event_output_metric(ctx, MSG_OP_CLONE, &tcpmon_map, + BPF_F_CURRENT_CPU, &msg, msg_size); + } return 0; } diff --git a/pkg/testutils/sensors/load.go b/pkg/testutils/sensors/load.go index 2fee681dab9..a805b2560a9 100644 --- a/pkg/testutils/sensors/load.go +++ b/pkg/testutils/sensors/load.go @@ -148,7 +148,7 @@ func mergeInBaseSensorMaps(t *testing.T, sensorMaps []SensorMap, sensorProgs []S SensorMap{Name: "execve_map_stats", Progs: []uint{1, 2}}, // event_execve - SensorMap{Name: "tg_conf_map", Progs: []uint{0}}, + SensorMap{Name: "tg_conf_map", Progs: []uint{0, 2}}, // event_wake_up_new_task SensorMap{Name: "execve_val", Progs: []uint{2}}, From 34a041ced8b98463eb3f29982b99979f5ebe03eb Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 24 Mar 2024 20:21:00 +0000 Subject: [PATCH 12/17] tetragon: Add cgroup rate support for exit Adding support to control cgroup rate for exit events. Signed-off-by: Jiri Olsa --- bpf/process/bpf_exit.h | 11 ++++++++++- pkg/testutils/sensors/load.go | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bpf/process/bpf_exit.h b/bpf/process/bpf_exit.h index b683bac7a5d..23674eea59b 100644 --- a/bpf/process/bpf_exit.h +++ b/bpf/process/bpf_exit.h @@ -9,6 +9,9 @@ #include "bpf_event.h" #include "bpf_task.h" +#include "bpf_rate.h" +#include "process.h" +#include "bpf_process_event.h" struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); @@ -36,6 +39,7 @@ static inline __attribute__((always_inline)) void event_exit_send(void *ctx, __u struct task_struct *task = (struct task_struct *)get_current_task(); size_t size = sizeof(struct msg_exit); struct msg_exit *exit; + struct msg_k8s kube; int zero = 0; exit = map_lookup_elem(&exit_heap_map, &zero); @@ -66,7 +70,12 @@ static inline __attribute__((always_inline)) void event_exit_send(void *ctx, __u probe_read(&exit->info.code, sizeof(exit->info.code), _(&task->exit_code)); - perf_event_output_metric(ctx, MSG_OP_EXIT, &tcpmon_map, BPF_F_CURRENT_CPU, exit, size); + __event_get_cgroup_info(task, &kube); + + if (cgroup_rate(ctx, &kube, exit->common.ktime)) { + perf_event_output_metric(ctx, MSG_OP_EXIT, &tcpmon_map, + BPF_F_CURRENT_CPU, exit, size); + } } execve_map_delete(tgid); } diff --git a/pkg/testutils/sensors/load.go b/pkg/testutils/sensors/load.go index a805b2560a9..93c8d7cd833 100644 --- a/pkg/testutils/sensors/load.go +++ b/pkg/testutils/sensors/load.go @@ -148,7 +148,7 @@ func mergeInBaseSensorMaps(t *testing.T, sensorMaps []SensorMap, sensorProgs []S SensorMap{Name: "execve_map_stats", Progs: []uint{1, 2}}, // event_execve - SensorMap{Name: "tg_conf_map", Progs: []uint{0, 2}}, + SensorMap{Name: "tg_conf_map", Progs: []uint{0, 1, 2}}, // event_wake_up_new_task SensorMap{Name: "execve_val", Progs: []uint{2}}, From c0e56096273f6bc172245d6481425067c0531ac5 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Apr 2024 17:04:17 +0000 Subject: [PATCH 13/17] tetragon: Add GetInitialSensorTest function The base sensor now depends on config options, but the option can be enabled for specific test and base sensor is not recalculated. Adding base sensor for observer (sensorTest) which contains all possible programs and maps. Signed-off-by: Jiri Olsa --- .../observer_test_helper.go | 2 +- pkg/sensors/base/base.go | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/pkg/observer/observertesthelper/observer_test_helper.go b/pkg/observer/observertesthelper/observer_test_helper.go index 43a03a11be8..92ffb696045 100644 --- a/pkg/observer/observertesthelper/observer_test_helper.go +++ b/pkg/observer/observertesthelper/observer_test_helper.go @@ -624,7 +624,7 @@ func WriteConfigFile(fileName, config string) error { } func GetDefaultObserver(tb testing.TB, ctx context.Context, lib string, opts ...TestOption) (*observer.Observer, error) { - b := base.GetInitialSensor() + b := base.GetInitialSensorTest() opts = append(opts, WithLib(lib)) diff --git a/pkg/sensors/base/base.go b/pkg/sensors/base/base.go index 46bac04bd37..36fae85eed1 100644 --- a/pkg/sensors/base/base.go +++ b/pkg/sensors/base/base.go @@ -80,6 +80,11 @@ var ( Name: "__base__", } sensorInit sync.Once + + sensorTest = sensors.Sensor{ + Name: "__base__", + } + sensorTestInit sync.Once ) func setupExitProgram() { @@ -114,20 +119,20 @@ func GetTetragonConfMap() *program.Map { return TetragonConfMap } -func GetDefaultPrograms() []*program.Program { +func GetDefaultPrograms(cgroupRate bool) []*program.Program { progs := []*program.Program{ Exit, Fork, Execve, ExecveBprmCommit, } - if option.CgroupRateEnabled() { + if cgroupRate { progs = append(progs, CgroupRmdir) } return progs } -func GetDefaultMaps() []*program.Map { +func GetDefaultMaps(cgroupRate bool) []*program.Map { maps := []*program.Map{ ExecveMap, ExecveJoinMap, @@ -138,7 +143,7 @@ func GetDefaultMaps() []*program.Map { TetragonConfMap, StatsMap, } - if option.CgroupRateEnabled() { + if cgroupRate { maps = append(maps, CgroupRateMap, CgroupRateOptionsMap) } return maps @@ -149,12 +154,21 @@ func GetDefaultMaps() []*program.Map { func GetInitialSensor() *sensors.Sensor { sensorInit.Do(func() { setupExitProgram() - sensor.Progs = GetDefaultPrograms() - sensor.Maps = GetDefaultMaps() + sensor.Progs = GetDefaultPrograms(option.CgroupRateEnabled()) + sensor.Maps = GetDefaultMaps(option.CgroupRateEnabled()) }) return &sensor } +func GetInitialSensorTest() *sensors.Sensor { + sensorTestInit.Do(func() { + setupExitProgram() + sensorTest.Progs = GetDefaultPrograms(true) + sensorTest.Maps = GetDefaultMaps(true) + }) + return &sensorTest +} + // ExecObj returns the exec object based on the kernel version func ExecObj() string { if kernels.EnableV61Progs() { From 6b0fae6e1a1757e20a6b8475be83fcf226e301cf Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Apr 2024 11:34:38 +0000 Subject: [PATCH 14/17] tetragon: Add throttle exec/fork event test Adding throttle exec/fork event test that sets cgroup rate limit and spawns bit more processes per second and triggers throttle start event, then wait for throttle stop event. Signed-off-by: Jiri Olsa --- pkg/sensors/exec/exec_test.go | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/pkg/sensors/exec/exec_test.go b/pkg/sensors/exec/exec_test.go index bd581ec0013..9a07b782aba 100644 --- a/pkg/sensors/exec/exec_test.go +++ b/pkg/sensors/exec/exec_test.go @@ -1449,3 +1449,55 @@ func TestExecDeletedBinary(t *testing.T) { err = jsonchecker.JsonTestCheck(t, checker) assert.NoError(t, err) } + +func testThrottle(t *testing.T) { + var doneWG, readyWG sync.WaitGroup + defer doneWG.Wait() + + throttleStartChecker := ec.NewProcessThrottleChecker("THROTTLE"). + WithType(tetragon.ThrottleType_THROTTLE_START) + + throttleStopChecker := ec.NewProcessThrottleChecker("THROTTLE"). + WithType(tetragon.ThrottleType_THROTTLE_STOP) + + checker := ec.NewUnorderedEventChecker(throttleStartChecker, throttleStopChecker) + + ctx, cancel := context.WithTimeout(context.Background(), tus.Conf().CmdWaitTime) + defer cancel() + + option.Config.CgroupRate = option.ParseCgroupRate("10,2s") + t.Cleanup(func() { + option.Config.CgroupRate = option.CgroupRate{} + }) + + obs, err := observertesthelper.GetDefaultObserver(t, ctx, tus.Conf().TetragonLib) + if err != nil { + t.Fatalf("Failed to run observer: %s", err) + } + + observertesthelper.LoopEvents(ctx, t, &doneWG, &readyWG, obs) + readyWG.Wait() + + // create the load 40 fork/exec per sec for 4 seconds + // to get THROTTLE START + for cnt := 0; cnt < 40; cnt++ { + if err := exec.Command("taskset", "-c", "1", "sleep", "0.1s").Run(); err != nil { + t.Fatalf("Failed to execute test binary: %s\n", err) + } + } + + // and calm down to get THROTTLE STOP + time.Sleep(8 * time.Second) + + err = jsonchecker.JsonTestCheck(t, checker) + assert.NoError(t, err) +} + +func TestThrottle1(t *testing.T) { + testThrottle(t) +} + +// Run throttle twice to test the CgroupRate setup code +func TestThrottle2(t *testing.T) { + testThrottle(t) +} From 0d2b62e05c11070de8aeb41a47efb003521c8575 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 25 Mar 2024 23:22:48 +0000 Subject: [PATCH 15/17] tetragon: Add cgrouprate processCgroup test Adding throttle processCgroup test that models possible cases and checks the throttle stop event is properly sent or not. Signed-off-by: Jiri Olsa --- pkg/cgrouprate/cgrouprate.go | 7 + pkg/cgrouprate/cgrouprate_test.go | 259 ++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 pkg/cgrouprate/cgrouprate_test.go diff --git a/pkg/cgrouprate/cgrouprate.go b/pkg/cgrouprate/cgrouprate.go index 7ae516f2a4a..5be78c9edb7 100644 --- a/pkg/cgrouprate/cgrouprate.go +++ b/pkg/cgrouprate/cgrouprate.go @@ -97,6 +97,13 @@ func NewCgroupRate(ctx context.Context, go handle.process(ctx) } +func NewTestCgroupRate(listener observer.Listener, + hash *program.Map, + opts *option.CgroupRate) { + + handle = newCgroupRate(listener, hash, opts) +} + func (r *CgroupRate) notify(msg notify.Message) { if err := r.listener.Notify(msg); err != nil { r.log.WithError(err).Warn("failed to notify listener") diff --git a/pkg/cgrouprate/cgrouprate_test.go b/pkg/cgrouprate/cgrouprate_test.go new file mode 100644 index 00000000000..0d1c8835677 --- /dev/null +++ b/pkg/cgrouprate/cgrouprate_test.go @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package cgrouprate + +import ( + "os" + "testing" + "time" + "unsafe" + + "github.com/cilium/ebpf" + "github.com/cilium/tetragon/api/v1/tetragon" + "github.com/cilium/tetragon/pkg/api/processapi" + "github.com/cilium/tetragon/pkg/bpf" + "github.com/cilium/tetragon/pkg/option" + "github.com/cilium/tetragon/pkg/reader/notify" + "github.com/cilium/tetragon/pkg/sensors/program" + tus "github.com/cilium/tetragon/pkg/testutils/sensors" + "github.com/stretchr/testify/assert" +) + +func TestMain(m *testing.M) { + ec := tus.TestSensorsRun(m, "SensorExec") + os.Exit(ec) +} + +type listener struct { + throttle tetragon.ThrottleType + cgroup string +} + +func (l *listener) Notify(msg notify.Message) error { + response := msg.HandleMessage() + switch response.Event.(type) { + case *tetragon.GetEventsResponse_ProcessThrottle: + ev := response.GetProcessThrottle() + l.throttle = ev.Type + l.cgroup = ev.Cgroup + } + return nil +} + +func (l *listener) Close() error { + return nil +} + +type testData struct { + opts option.CgroupRate + values [2]processapi.CgroupRateValue + last uint64 + throttle tetragon.ThrottleType + ret bool +} + +func TestProcessCgroup(t *testing.T) { + key := processapi.CgroupRateKey{ + Id: 123, + } + + cgroup := "cgroup" + + // Test that we get (or not) STOP throttle event, which depends on + // wether the cgroup is alive and the rate is below the limit. + + data := []testData{ + // 0: both rate and last time update are beyond limit on both + // cpus - expecting STOP + { + opts: option.CgroupRate{ + Events: 10, + Interval: uint64(time.Second), + }, + values: [2]processapi.CgroupRateValue{ + { + Rate: 1, + Time: uint64(time.Second), + Throttled: uint64(time.Second), + }, + { + Rate: 2, + Time: uint64(time.Second), + Throttled: uint64(time.Second), + }, + }, + last: uint64(time.Second) * 8, + + // expecting: + throttle: tetragon.ThrottleType_THROTTLE_STOP, + ret: true, + }, + // 1: rate is above limit and last time update is recent enough from + // rate time - no event + { + opts: option.CgroupRate{ + Events: 10, + Interval: uint64(time.Second), + }, + values: [2]processapi.CgroupRateValue{ + { + Rate: 1, + Time: uint64(time.Second), + Throttled: uint64(time.Second), + }, + { + Rate: 2, + Time: uint64(time.Second), + Throttled: uint64(time.Second), + }, + }, + last: uint64(time.Second), + + // expecting: + throttle: tetragon.ThrottleType_THROTTLE_UNKNOWN, + ret: false, + }, + // 2: rate is below limit but last time update is recent enough from + // throttle time - expecting no event + { + opts: option.CgroupRate{ + Events: 10, + Interval: uint64(time.Second), + }, + values: [2]processapi.CgroupRateValue{ + { + Rate: 1, + Time: uint64(time.Second * 3), + Throttled: uint64(time.Second), + }, + { + Rate: 2, + Time: uint64(time.Second * 3), + Throttled: uint64(time.Second), + }, + }, + last: uint64(time.Second * 3), + + // expecting: + throttle: tetragon.ThrottleType_THROTTLE_UNKNOWN, + ret: false, + }, + // 3: rate is below limit but last time update is recent enough from + // throttle time on one cpu, the other one is dead - expecting no event + { + opts: option.CgroupRate{ + Events: 10, + Interval: uint64(time.Second), + }, + values: [2]processapi.CgroupRateValue{ + { + Rate: 0, + Time: uint64(time.Second), + Throttled: uint64(time.Second), + }, + { + Rate: 2, + Time: uint64(time.Second * 10), + Throttled: uint64(time.Second * 5), + }, + }, + last: uint64(time.Second * 7), + + // expecting: + throttle: tetragon.ThrottleType_THROTTLE_UNKNOWN, + ret: false, + }, + // 4: rate is above limit, but the last time update is beyond limit on + // both cpus - expecting STOP + { + opts: option.CgroupRate{ + Events: 10, + Interval: uint64(time.Second), + }, + values: [2]processapi.CgroupRateValue{ + { + Rate: 20, + Time: uint64(time.Second), + Throttled: uint64(time.Second), + }, + { + Rate: 20, + Time: uint64(time.Second), + Throttled: uint64(time.Second), + }, + }, + last: uint64(time.Second) * 8, + + // expecting: + throttle: tetragon.ThrottleType_THROTTLE_STOP, + ret: true, + }, + // 5: rate is below limit and the last time is recent enough on + // both cpus - expecting STOP + { + opts: option.CgroupRate{ + Events: 10, + Interval: uint64(time.Second), + }, + values: [2]processapi.CgroupRateValue{ + { + Rate: 2, + Time: uint64(time.Second * 8), + Throttled: uint64(time.Second), + }, + { + Rate: 3, + Time: uint64(time.Second * 8), + Throttled: uint64(time.Second), + }, + }, + last: uint64(time.Second * 9), + + // expecting: + throttle: tetragon.ThrottleType_THROTTLE_STOP, + ret: true, + }, + } + + values := make([]processapi.CgroupRateValue, bpf.GetNumPossibleCPUs()) + + spec := &ebpf.MapSpec{ + Type: ebpf.PerCPUHash, + KeySize: uint32(unsafe.Sizeof(key)), + ValueSize: uint32(unsafe.Sizeof(values[0])), + MaxEntries: 32768, + } + + hash := program.MapBuilder("hash", nil) + err := hash.New(spec) + if err != nil { + t.Fatal(err) + } + defer hash.Close() + + for idx, d := range data { + l := &listener{ + throttle: tetragon.ThrottleType_THROTTLE_UNKNOWN, + } + NewTestCgroupRate(l, hash, &d.opts) + + // setup cgrouprate cgroup + handle.cgroups[key.Id] = cgroup + assert.NotEqual(t, nil, handle) + + // store hash values + values[0] = d.values[0] + values[1] = d.values[1] + + if err := hash.MapHandle.Put(key, values); err != nil { + t.Fatal("Can't put:", err) + } + + t.Logf("Test %d", idx) + ret := handle.processCgroup(key.Id, cgroup, d.last) + + assert.Equal(t, d.ret, ret) + assert.Equal(t, d.throttle, l.throttle) + } +} From cdf108f4c76429133cf747c7abc216d66622a019 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 4 Apr 2024 14:16:22 +0000 Subject: [PATCH 16/17] tetragon: Add ParseCgroupRate test Adding test for ParseCgroupRate function. Signed-off-by: Jiri Olsa --- pkg/cgrouprate/cgrouprate_test.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pkg/cgrouprate/cgrouprate_test.go b/pkg/cgrouprate/cgrouprate_test.go index 0d1c8835677..d86c6992dec 100644 --- a/pkg/cgrouprate/cgrouprate_test.go +++ b/pkg/cgrouprate/cgrouprate_test.go @@ -257,3 +257,26 @@ func TestProcessCgroup(t *testing.T) { assert.Equal(t, d.throttle, l.throttle) } } + +func TestParseCgroupRate(t *testing.T) { + var opt option.CgroupRate + + // ok + opt = option.ParseCgroupRate("1,1s") + assert.Equal(t, option.CgroupRate{Events: 1, Interval: 1000000000}, opt) + + opt = option.ParseCgroupRate("1,1m") + assert.Equal(t, option.CgroupRate{Events: 1, Interval: 60000000000}, opt) + + // fail + empty := option.CgroupRate{Events: 0, Interval: 0} + + opt = option.ParseCgroupRate("10") + assert.Equal(t, empty, opt) + + opt = option.ParseCgroupRate("sure,1s") + assert.Equal(t, empty, opt) + + opt = option.ParseCgroupRate("1,nope") + assert.Equal(t, empty, opt) +} From 35dcbb897917e3017b1c2e66b311a0c9e0576670 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 1 Mar 2024 15:18:33 +0000 Subject: [PATCH 17/17] tetra: Add support to display throttle events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding support to display throttle events in getevents like: 💥 exit ubuntu-22 /usr/bin/sleep 0.1s 0 🚀 process ubuntu-22 /usr/bin/sleep 0.1s 🧬 throttle START session-130.scope-10741 🧬 throttle STOP session-130.scope-10741 🚀 process ubuntu-22 /usr/bin/git diff 🚀 process ubuntu-22 /usr/bin/pager Signed-off-by: Jiri Olsa --- pkg/encoder/encoder.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/encoder/encoder.go b/pkg/encoder/encoder.go index a2663d69646..6d000debbc7 100644 --- a/pkg/encoder/encoder.go +++ b/pkg/encoder/encoder.go @@ -250,6 +250,17 @@ func (p *CompactEncoder) EventToString(response *tetragon.GetEventsResponse) (st status = p.Colorer.Red.Sprint(exit.Status) } return CapTrailorPrinter(fmt.Sprintf("%s %s %s %s", event, processInfo, args, status), caps), nil + case *tetragon.GetEventsResponse_ProcessThrottle: + throttle := response.GetProcessThrottle() + event := p.Colorer.Red.Sprintf("🧬 %-7s", "throttle") + var typ string + switch throttle.Type { + case tetragon.ThrottleType_THROTTLE_START: + typ = p.Colorer.Red.Sprint("START") + case tetragon.ThrottleType_THROTTLE_STOP: + typ = p.Colorer.Green.Sprint("STOP ") + } + return fmt.Sprintf("%s %s %s", event, typ, throttle.Cgroup), nil case *tetragon.GetEventsResponse_ProcessLoader: loader := response.GetProcessLoader() if loader.Process == nil {