diff --git a/agent-manager/agent/agent.pb.go b/agent-manager/agent/agent.pb.go index 54e54fa1d..cce8657d5 100644 --- a/agent-manager/agent/agent.pb.go +++ b/agent-manager/agent/agent.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v5.29.3 +// protoc-gen-go v1.36.12 +// protoc v7.35.1 // source: agent.proto package agent @@ -520,6 +520,7 @@ type BidirectionalStream struct { // // *BidirectionalStream_Command // *BidirectionalStream_Result + // *BidirectionalStream_Heartbeat StreamMessage isBidirectionalStream_StreamMessage `protobuf_oneof:"stream_message"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -580,6 +581,15 @@ func (x *BidirectionalStream) GetResult() *CommandResult { return nil } +func (x *BidirectionalStream) GetHeartbeat() *Heartbeat { + if x != nil { + if x, ok := x.StreamMessage.(*BidirectionalStream_Heartbeat); ok { + return x.Heartbeat + } + } + return nil +} + type isBidirectionalStream_StreamMessage interface { isBidirectionalStream_StreamMessage() } @@ -592,10 +602,52 @@ type BidirectionalStream_Result struct { Result *CommandResult `protobuf:"bytes,2,opt,name=result,proto3,oneof"` } +type BidirectionalStream_Heartbeat struct { + Heartbeat *Heartbeat `protobuf:"bytes,3,opt,name=heartbeat,proto3,oneof"` +} + func (*BidirectionalStream_Command) isBidirectionalStream_StreamMessage() {} func (*BidirectionalStream_Result) isBidirectionalStream_StreamMessage() {} +func (*BidirectionalStream_Heartbeat) isBidirectionalStream_StreamMessage() {} + +type Heartbeat struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Heartbeat) Reset() { + *x = Heartbeat{} + mi := &file_agent_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Heartbeat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Heartbeat) ProtoMessage() {} + +func (x *Heartbeat) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Heartbeat.ProtoReflect.Descriptor instead. +func (*Heartbeat) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{6} +} + type UtmCommand struct { state protoimpl.MessageState `protogen:"open.v1"` AgentId string `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` @@ -612,7 +664,7 @@ type UtmCommand struct { func (x *UtmCommand) Reset() { *x = UtmCommand{} - mi := &file_agent_proto_msgTypes[6] + mi := &file_agent_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -624,7 +676,7 @@ func (x *UtmCommand) String() string { func (*UtmCommand) ProtoMessage() {} func (x *UtmCommand) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[6] + mi := &file_agent_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -637,7 +689,7 @@ func (x *UtmCommand) ProtoReflect() protoreflect.Message { // Deprecated: Use UtmCommand.ProtoReflect.Descriptor instead. func (*UtmCommand) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{6} + return file_agent_proto_rawDescGZIP(), []int{7} } func (x *UtmCommand) GetAgentId() string { @@ -708,7 +760,7 @@ type CommandResult struct { func (x *CommandResult) Reset() { *x = CommandResult{} - mi := &file_agent_proto_msgTypes[7] + mi := &file_agent_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -720,7 +772,7 @@ func (x *CommandResult) String() string { func (*CommandResult) ProtoMessage() {} func (x *CommandResult) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[7] + mi := &file_agent_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -733,7 +785,7 @@ func (x *CommandResult) ProtoReflect() protoreflect.Message { // Deprecated: Use CommandResult.ProtoReflect.Descriptor instead. func (*CommandResult) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{7} + return file_agent_proto_rawDescGZIP(), []int{8} } func (x *CommandResult) GetAgentId() string { @@ -774,7 +826,7 @@ type ListAgentsCommandsResponse struct { func (x *ListAgentsCommandsResponse) Reset() { *x = ListAgentsCommandsResponse{} - mi := &file_agent_proto_msgTypes[8] + mi := &file_agent_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -786,7 +838,7 @@ func (x *ListAgentsCommandsResponse) String() string { func (*ListAgentsCommandsResponse) ProtoMessage() {} func (x *ListAgentsCommandsResponse) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[8] + mi := &file_agent_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -799,7 +851,7 @@ func (x *ListAgentsCommandsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAgentsCommandsResponse.ProtoReflect.Descriptor instead. func (*ListAgentsCommandsResponse) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{8} + return file_agent_proto_rawDescGZIP(), []int{9} } func (x *ListAgentsCommandsResponse) GetRows() []*AgentCommand { @@ -835,7 +887,7 @@ type AgentCommand struct { func (x *AgentCommand) Reset() { *x = AgentCommand{} - mi := &file_agent_proto_msgTypes[9] + mi := &file_agent_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -847,7 +899,7 @@ func (x *AgentCommand) String() string { func (*AgentCommand) ProtoMessage() {} func (x *AgentCommand) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[9] + mi := &file_agent_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -860,7 +912,7 @@ func (x *AgentCommand) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentCommand.ProtoReflect.Descriptor instead. func (*AgentCommand) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{9} + return file_agent_proto_rawDescGZIP(), []int{10} } func (x *AgentCommand) GetCreatedAt() *timestamppb.Timestamp { @@ -984,11 +1036,13 @@ const file_agent_proto_rawDesc = "" + "\aaliases\x18\r \x01(\tR\aaliases\x12\x1c\n" + "\taddresses\x18\x0e \x01(\tR\taddresses\x12\x1b\n" + "\ttenant_id\x18\x0f \x01(\tR\btenantId\x12*\n" + - "\x11no_remote_control\x18\x10 \x01(\bR\x0fnoRemoteControl\"\x86\x01\n" + + "\x11no_remote_control\x18\x10 \x01(\bR\x0fnoRemoteControl\"\xb8\x01\n" + "\x13BidirectionalStream\x12-\n" + "\acommand\x18\x01 \x01(\v2\x11.agent.UtmCommandH\x00R\acommand\x12.\n" + - "\x06result\x18\x02 \x01(\v2\x14.agent.CommandResultH\x00R\x06resultB\x10\n" + - "\x0estream_message\"\xe5\x01\n" + + "\x06result\x18\x02 \x01(\v2\x14.agent.CommandResultH\x00R\x06result\x120\n" + + "\theartbeat\x18\x03 \x01(\v2\x10.agent.HeartbeatH\x00R\theartbeatB\x10\n" + + "\x0estream_message\"\v\n" + + "\tHeartbeat\"\xe5\x01\n" + "\n" + "UtmCommand\x12\x19\n" + "\bagent_id\x18\x01 \x01(\tR\aagentId\x12\x18\n" + @@ -1060,7 +1114,7 @@ func file_agent_proto_rawDescGZIP() []byte { } var file_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_agent_proto_goTypes = []any{ (AgentCommandStatus)(0), // 0: agent.AgentCommandStatus (*ConnectionKeyRequest)(nil), // 1: agent.ConnectionKeyRequest @@ -1069,53 +1123,55 @@ var file_agent_proto_goTypes = []any{ (*ListAgentsResponse)(nil), // 4: agent.ListAgentsResponse (*Agent)(nil), // 5: agent.Agent (*BidirectionalStream)(nil), // 6: agent.BidirectionalStream - (*UtmCommand)(nil), // 7: agent.UtmCommand - (*CommandResult)(nil), // 8: agent.CommandResult - (*ListAgentsCommandsResponse)(nil), // 9: agent.ListAgentsCommandsResponse - (*AgentCommand)(nil), // 10: agent.AgentCommand - (Status)(0), // 11: agent.Status - (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp - (*DeleteRequest)(nil), // 13: agent.DeleteRequest - (*ListRequest)(nil), // 14: agent.ListRequest - (*ConnectorAuthRequest)(nil), // 15: agent.ConnectorAuthRequest - (*AuthResponse)(nil), // 16: agent.AuthResponse - (*ConnectorAuthResponse)(nil), // 17: agent.ConnectorAuthResponse + (*Heartbeat)(nil), // 7: agent.Heartbeat + (*UtmCommand)(nil), // 8: agent.UtmCommand + (*CommandResult)(nil), // 9: agent.CommandResult + (*ListAgentsCommandsResponse)(nil), // 10: agent.ListAgentsCommandsResponse + (*AgentCommand)(nil), // 11: agent.AgentCommand + (Status)(0), // 12: agent.Status + (*timestamppb.Timestamp)(nil), // 13: google.protobuf.Timestamp + (*DeleteRequest)(nil), // 14: agent.DeleteRequest + (*ListRequest)(nil), // 15: agent.ListRequest + (*ConnectorAuthRequest)(nil), // 16: agent.ConnectorAuthRequest + (*AuthResponse)(nil), // 17: agent.AuthResponse + (*ConnectorAuthResponse)(nil), // 18: agent.ConnectorAuthResponse } var file_agent_proto_depIdxs = []int32{ 5, // 0: agent.ListAgentsResponse.rows:type_name -> agent.Agent - 11, // 1: agent.Agent.status:type_name -> agent.Status - 7, // 2: agent.BidirectionalStream.command:type_name -> agent.UtmCommand - 8, // 3: agent.BidirectionalStream.result:type_name -> agent.CommandResult - 12, // 4: agent.CommandResult.executed_at:type_name -> google.protobuf.Timestamp - 10, // 5: agent.ListAgentsCommandsResponse.rows:type_name -> agent.AgentCommand - 12, // 6: agent.AgentCommand.created_at:type_name -> google.protobuf.Timestamp - 12, // 7: agent.AgentCommand.updated_at:type_name -> google.protobuf.Timestamp - 0, // 8: agent.AgentCommand.command_status:type_name -> agent.AgentCommandStatus - 3, // 9: agent.AgentService.RegisterAgent:input_type -> agent.AgentRequest - 3, // 10: agent.AgentService.UpdateAgent:input_type -> agent.AgentRequest - 13, // 11: agent.AgentService.DeleteAgent:input_type -> agent.DeleteRequest - 14, // 12: agent.AgentService.ListAgents:input_type -> agent.ListRequest - 15, // 13: agent.AgentService.GetAgentAuth:input_type -> agent.ConnectorAuthRequest - 6, // 14: agent.AgentService.AgentStream:input_type -> agent.BidirectionalStream - 14, // 15: agent.AgentService.ListAgentCommands:input_type -> agent.ListRequest - 7, // 16: agent.PanelService.ProcessCommand:input_type -> agent.UtmCommand - 1, // 17: agent.PanelService.GetConnectionKey:input_type -> agent.ConnectionKeyRequest - 1, // 18: agent.PanelService.RotateConnectionKey:input_type -> agent.ConnectionKeyRequest - 16, // 19: agent.AgentService.RegisterAgent:output_type -> agent.AuthResponse - 16, // 20: agent.AgentService.UpdateAgent:output_type -> agent.AuthResponse - 16, // 21: agent.AgentService.DeleteAgent:output_type -> agent.AuthResponse - 4, // 22: agent.AgentService.ListAgents:output_type -> agent.ListAgentsResponse - 17, // 23: agent.AgentService.GetAgentAuth:output_type -> agent.ConnectorAuthResponse - 6, // 24: agent.AgentService.AgentStream:output_type -> agent.BidirectionalStream - 9, // 25: agent.AgentService.ListAgentCommands:output_type -> agent.ListAgentsCommandsResponse - 8, // 26: agent.PanelService.ProcessCommand:output_type -> agent.CommandResult - 2, // 27: agent.PanelService.GetConnectionKey:output_type -> agent.ConnectionKeyResponse - 2, // 28: agent.PanelService.RotateConnectionKey:output_type -> agent.ConnectionKeyResponse - 19, // [19:29] is the sub-list for method output_type - 9, // [9:19] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 12, // 1: agent.Agent.status:type_name -> agent.Status + 8, // 2: agent.BidirectionalStream.command:type_name -> agent.UtmCommand + 9, // 3: agent.BidirectionalStream.result:type_name -> agent.CommandResult + 7, // 4: agent.BidirectionalStream.heartbeat:type_name -> agent.Heartbeat + 13, // 5: agent.CommandResult.executed_at:type_name -> google.protobuf.Timestamp + 11, // 6: agent.ListAgentsCommandsResponse.rows:type_name -> agent.AgentCommand + 13, // 7: agent.AgentCommand.created_at:type_name -> google.protobuf.Timestamp + 13, // 8: agent.AgentCommand.updated_at:type_name -> google.protobuf.Timestamp + 0, // 9: agent.AgentCommand.command_status:type_name -> agent.AgentCommandStatus + 3, // 10: agent.AgentService.RegisterAgent:input_type -> agent.AgentRequest + 3, // 11: agent.AgentService.UpdateAgent:input_type -> agent.AgentRequest + 14, // 12: agent.AgentService.DeleteAgent:input_type -> agent.DeleteRequest + 15, // 13: agent.AgentService.ListAgents:input_type -> agent.ListRequest + 16, // 14: agent.AgentService.GetAgentAuth:input_type -> agent.ConnectorAuthRequest + 6, // 15: agent.AgentService.AgentStream:input_type -> agent.BidirectionalStream + 15, // 16: agent.AgentService.ListAgentCommands:input_type -> agent.ListRequest + 8, // 17: agent.PanelService.ProcessCommand:input_type -> agent.UtmCommand + 1, // 18: agent.PanelService.GetConnectionKey:input_type -> agent.ConnectionKeyRequest + 1, // 19: agent.PanelService.RotateConnectionKey:input_type -> agent.ConnectionKeyRequest + 17, // 20: agent.AgentService.RegisterAgent:output_type -> agent.AuthResponse + 17, // 21: agent.AgentService.UpdateAgent:output_type -> agent.AuthResponse + 17, // 22: agent.AgentService.DeleteAgent:output_type -> agent.AuthResponse + 4, // 23: agent.AgentService.ListAgents:output_type -> agent.ListAgentsResponse + 18, // 24: agent.AgentService.GetAgentAuth:output_type -> agent.ConnectorAuthResponse + 6, // 25: agent.AgentService.AgentStream:output_type -> agent.BidirectionalStream + 10, // 26: agent.AgentService.ListAgentCommands:output_type -> agent.ListAgentsCommandsResponse + 9, // 27: agent.PanelService.ProcessCommand:output_type -> agent.CommandResult + 2, // 28: agent.PanelService.GetConnectionKey:output_type -> agent.ConnectionKeyResponse + 2, // 29: agent.PanelService.RotateConnectionKey:output_type -> agent.ConnectionKeyResponse + 20, // [20:30] is the sub-list for method output_type + 10, // [10:20] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_agent_proto_init() } @@ -1127,6 +1183,7 @@ func file_agent_proto_init() { file_agent_proto_msgTypes[5].OneofWrappers = []any{ (*BidirectionalStream_Command)(nil), (*BidirectionalStream_Result)(nil), + (*BidirectionalStream_Heartbeat)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1134,7 +1191,7 @@ func file_agent_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_agent_proto_rawDesc), len(file_agent_proto_rawDesc)), NumEnums: 1, - NumMessages: 10, + NumMessages: 11, NumExtensions: 0, NumServices: 2, }, diff --git a/agent-manager/agent/agent_grpc.pb.go b/agent-manager/agent/agent_grpc.pb.go index 30585f33d..fe94bf637 100644 --- a/agent-manager/agent/agent_grpc.pb.go +++ b/agent-manager/agent/agent_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc v5.29.3 +// - protoc-gen-go-grpc v1.6.2 +// - protoc v7.35.1 // source: agent.proto package agent @@ -144,25 +144,25 @@ type AgentServiceServer interface { type UnimplementedAgentServiceServer struct{} func (UnimplementedAgentServiceServer) RegisterAgent(context.Context, *AgentRequest) (*AuthResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RegisterAgent not implemented") + return nil, status.Error(codes.Unimplemented, "method RegisterAgent not implemented") } func (UnimplementedAgentServiceServer) UpdateAgent(context.Context, *AgentRequest) (*AuthResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateAgent not implemented") + return nil, status.Error(codes.Unimplemented, "method UpdateAgent not implemented") } func (UnimplementedAgentServiceServer) DeleteAgent(context.Context, *DeleteRequest) (*AuthResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteAgent not implemented") + return nil, status.Error(codes.Unimplemented, "method DeleteAgent not implemented") } func (UnimplementedAgentServiceServer) ListAgents(context.Context, *ListRequest) (*ListAgentsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListAgents not implemented") + return nil, status.Error(codes.Unimplemented, "method ListAgents not implemented") } func (UnimplementedAgentServiceServer) GetAgentAuth(context.Context, *ConnectorAuthRequest) (*ConnectorAuthResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetAgentAuth not implemented") + return nil, status.Error(codes.Unimplemented, "method GetAgentAuth not implemented") } func (UnimplementedAgentServiceServer) AgentStream(grpc.BidiStreamingServer[BidirectionalStream, BidirectionalStream]) error { - return status.Errorf(codes.Unimplemented, "method AgentStream not implemented") + return status.Error(codes.Unimplemented, "method AgentStream not implemented") } func (UnimplementedAgentServiceServer) ListAgentCommands(context.Context, *ListRequest) (*ListAgentsCommandsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListAgentCommands not implemented") + return nil, status.Error(codes.Unimplemented, "method ListAgentCommands not implemented") } func (UnimplementedAgentServiceServer) mustEmbedUnimplementedAgentServiceServer() {} func (UnimplementedAgentServiceServer) testEmbeddedByValue() {} @@ -175,7 +175,7 @@ type UnsafeAgentServiceServer interface { } func RegisterAgentServiceServer(s grpc.ServiceRegistrar, srv AgentServiceServer) { - // If the following call pancis, it indicates UnimplementedAgentServiceServer was + // If the following call panics, it indicates UnimplementedAgentServiceServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. @@ -417,13 +417,13 @@ type PanelServiceServer interface { type UnimplementedPanelServiceServer struct{} func (UnimplementedPanelServiceServer) ProcessCommand(grpc.BidiStreamingServer[UtmCommand, CommandResult]) error { - return status.Errorf(codes.Unimplemented, "method ProcessCommand not implemented") + return status.Error(codes.Unimplemented, "method ProcessCommand not implemented") } func (UnimplementedPanelServiceServer) GetConnectionKey(context.Context, *ConnectionKeyRequest) (*ConnectionKeyResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetConnectionKey not implemented") + return nil, status.Error(codes.Unimplemented, "method GetConnectionKey not implemented") } func (UnimplementedPanelServiceServer) RotateConnectionKey(context.Context, *ConnectionKeyRequest) (*ConnectionKeyResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RotateConnectionKey not implemented") + return nil, status.Error(codes.Unimplemented, "method RotateConnectionKey not implemented") } func (UnimplementedPanelServiceServer) mustEmbedUnimplementedPanelServiceServer() {} func (UnimplementedPanelServiceServer) testEmbeddedByValue() {} @@ -436,7 +436,7 @@ type UnsafePanelServiceServer interface { } func RegisterPanelServiceServer(s grpc.ServiceRegistrar, srv PanelServiceServer) { - // If the following call pancis, it indicates UnimplementedPanelServiceServer was + // If the following call panics, it indicates UnimplementedPanelServiceServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. diff --git a/agent-manager/agent/agent_imp.go b/agent-manager/agent/agent_imp.go index 6f57ed60b..d7b6a2885 100644 --- a/agent-manager/agent/agent_imp.go +++ b/agent-manager/agent/agent_imp.go @@ -21,6 +21,8 @@ import ( "gorm.io/gorm" ) +const agentHeartbeatInterval = 30 * time.Second + var ( AgentServ *AgentService agentServOnce sync.Once @@ -331,6 +333,8 @@ func (s *AgentService) AgentStream(stream AgentService_AgentStreamServer) error OnAgentConnectHook(stream.Context(), idUint) } + go serverHeartbeatLoop(stream.Context(), idUint, stream) + for { in, err := stream.Recv() if err == io.EOF { @@ -357,6 +361,37 @@ func (s *AgentService) AgentStream(stream AgentService_AgentStreamServer) error (OnCommandResultHook == nil || !OnCommandResultHook(msg.Result)) { catcher.Error("failed to find result channel for CmdID", nil, map[string]any{"cmdID": msg.Result.GetCmdId(), "process": "agent-manager"}) } + case *BidirectionalStream_Heartbeat: + } + } +} + +func serverHeartbeatLoop(ctx context.Context, agentID uint, stream AgentService_AgentStreamServer) { + t := time.NewTicker(agentHeartbeatInterval) + defer t.Stop() + msg := &BidirectionalStream{ + StreamMessage: &BidirectionalStream_Heartbeat{Heartbeat: &Heartbeat{}}, + } + for { + select { + case <-ctx.Done(): + return + case <-t.C: + var lock sync.Locker + if LockStreamHook != nil { + lock = LockStreamHook(agentID) + } + var err error + func() { + if lock != nil { + lock.Lock() + defer lock.Unlock() + } + err = stream.Send(msg) + }() + if err != nil { + return + } } } } diff --git a/agent-manager/protos/agent.proto b/agent-manager/protos/agent.proto index 8b22bf35f..7500ae3d7 100644 --- a/agent-manager/protos/agent.proto +++ b/agent-manager/protos/agent.proto @@ -83,9 +83,12 @@ message BidirectionalStream { oneof stream_message { UtmCommand command = 1; CommandResult result = 2; + Heartbeat heartbeat = 3; } } +message Heartbeat {} + message UtmCommand { string agent_id = 1; string command = 2; diff --git a/agent/agent/agent.pb.go b/agent/agent/agent.pb.go index 0a2ae82fc..3beb05262 100644 --- a/agent/agent/agent.pb.go +++ b/agent/agent/agent.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v5.29.3 +// protoc-gen-go v1.36.12 +// protoc v7.35.1 // source: agent.proto package agent @@ -77,120 +77,27 @@ func (AgentCommandStatus) EnumDescriptor() ([]byte, []int) { return file_agent_proto_rawDescGZIP(), []int{0} } -type ConnectionKeyRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Which tenant's enrolment key. Empty means the default tenant. - TenantId string `protobuf:"bytes,1,opt,name=tenantId,proto3" json:"tenantId,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ConnectionKeyRequest) Reset() { - *x = ConnectionKeyRequest{} - mi := &file_agent_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ConnectionKeyRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConnectionKeyRequest) ProtoMessage() {} - -func (x *ConnectionKeyRequest) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ConnectionKeyRequest.ProtoReflect.Descriptor instead. -func (*ConnectionKeyRequest) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{0} -} - -func (x *ConnectionKeyRequest) GetTenantId() string { - if x != nil { - return x.TenantId - } - return "" -} - -type ConnectionKeyResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ConnectionKey string `protobuf:"bytes,1,opt,name=connection_key,json=connectionKey,proto3" json:"connection_key,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ConnectionKeyResponse) Reset() { - *x = ConnectionKeyResponse{} - mi := &file_agent_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ConnectionKeyResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConnectionKeyResponse) ProtoMessage() {} - -func (x *ConnectionKeyResponse) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ConnectionKeyResponse.ProtoReflect.Descriptor instead. -func (*ConnectionKeyResponse) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{1} -} - -func (x *ConnectionKeyResponse) GetConnectionKey() string { - if x != nil { - return x.ConnectionKey - } - return "" -} - type AgentRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Ip string `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` - Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` - Os string `protobuf:"bytes,3,opt,name=os,proto3" json:"os,omitempty"` - Platform string `protobuf:"bytes,4,opt,name=platform,proto3" json:"platform,omitempty"` - Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"` - RegisterBy string `protobuf:"bytes,6,opt,name=register_by,json=registerBy,proto3" json:"register_by,omitempty"` - Mac string `protobuf:"bytes,7,opt,name=mac,proto3" json:"mac,omitempty"` - OsMajorVersion string `protobuf:"bytes,8,opt,name=os_major_version,json=osMajorVersion,proto3" json:"os_major_version,omitempty"` - OsMinorVersion string `protobuf:"bytes,9,opt,name=os_minor_version,json=osMinorVersion,proto3" json:"os_minor_version,omitempty"` - Aliases string `protobuf:"bytes,10,opt,name=aliases,proto3" json:"aliases,omitempty"` - Addresses string `protobuf:"bytes,11,opt,name=addresses,proto3" json:"addresses,omitempty"` - // Set at install and never changed from here. It is reported so the console - // can show that this machine refuses commands; the refusal itself happens in - // the agent, because a flag the server honours is worth nothing against a - // server that has been taken over. - NoRemoteControl bool `protobuf:"varint,12,opt,name=no_remote_control,json=noRemoteControl,proto3" json:"no_remote_control,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Ip string `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` + Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` + Os string `protobuf:"bytes,3,opt,name=os,proto3" json:"os,omitempty"` + Platform string `protobuf:"bytes,4,opt,name=platform,proto3" json:"platform,omitempty"` + Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"` + RegisterBy string `protobuf:"bytes,6,opt,name=register_by,json=registerBy,proto3" json:"register_by,omitempty"` + Mac string `protobuf:"bytes,7,opt,name=mac,proto3" json:"mac,omitempty"` + OsMajorVersion string `protobuf:"bytes,8,opt,name=os_major_version,json=osMajorVersion,proto3" json:"os_major_version,omitempty"` + OsMinorVersion string `protobuf:"bytes,9,opt,name=os_minor_version,json=osMinorVersion,proto3" json:"os_minor_version,omitempty"` + Aliases string `protobuf:"bytes,10,opt,name=aliases,proto3" json:"aliases,omitempty"` + Addresses string `protobuf:"bytes,11,opt,name=addresses,proto3" json:"addresses,omitempty"` + NoRemoteControl bool `protobuf:"varint,12,opt,name=no_remote_control,json=noRemoteControl,proto3" json:"no_remote_control,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *AgentRequest) Reset() { *x = AgentRequest{} - mi := &file_agent_proto_msgTypes[2] + mi := &file_agent_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -202,7 +109,7 @@ func (x *AgentRequest) String() string { func (*AgentRequest) ProtoMessage() {} func (x *AgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[2] + mi := &file_agent_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -215,7 +122,7 @@ func (x *AgentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentRequest.ProtoReflect.Descriptor instead. func (*AgentRequest) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{2} + return file_agent_proto_rawDescGZIP(), []int{0} } func (x *AgentRequest) GetIp() string { @@ -312,7 +219,7 @@ type ListAgentsResponse struct { func (x *ListAgentsResponse) Reset() { *x = ListAgentsResponse{} - mi := &file_agent_proto_msgTypes[3] + mi := &file_agent_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -324,7 +231,7 @@ func (x *ListAgentsResponse) String() string { func (*ListAgentsResponse) ProtoMessage() {} func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[3] + mi := &file_agent_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -337,7 +244,7 @@ func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAgentsResponse.ProtoReflect.Descriptor instead. func (*ListAgentsResponse) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{3} + return file_agent_proto_rawDescGZIP(), []int{1} } func (x *ListAgentsResponse) GetRows() []*Agent { @@ -355,30 +262,28 @@ func (x *ListAgentsResponse) GetTotal() int32 { } type Agent struct { - state protoimpl.MessageState `protogen:"open.v1"` - Ip string `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` - Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` - Os string `protobuf:"bytes,3,opt,name=os,proto3" json:"os,omitempty"` - Status Status `protobuf:"varint,4,opt,name=status,proto3,enum=agent.Status" json:"status,omitempty"` - Platform string `protobuf:"bytes,5,opt,name=platform,proto3" json:"platform,omitempty"` - Version string `protobuf:"bytes,6,opt,name=version,proto3" json:"version,omitempty"` - AgentKey string `protobuf:"bytes,7,opt,name=agent_key,json=agentKey,proto3" json:"agent_key,omitempty"` - Id uint32 `protobuf:"varint,8,opt,name=id,proto3" json:"id,omitempty"` - LastSeen string `protobuf:"bytes,9,opt,name=last_seen,json=lastSeen,proto3" json:"last_seen,omitempty"` - Mac string `protobuf:"bytes,10,opt,name=mac,proto3" json:"mac,omitempty"` - OsMajorVersion string `protobuf:"bytes,11,opt,name=os_major_version,json=osMajorVersion,proto3" json:"os_major_version,omitempty"` - OsMinorVersion string `protobuf:"bytes,12,opt,name=os_minor_version,json=osMinorVersion,proto3" json:"os_minor_version,omitempty"` - Aliases string `protobuf:"bytes,13,opt,name=aliases,proto3" json:"aliases,omitempty"` - Addresses string `protobuf:"bytes,14,opt,name=addresses,proto3" json:"addresses,omitempty"` - TenantId string `protobuf:"bytes,15,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` - NoRemoteControl bool `protobuf:"varint,16,opt,name=no_remote_control,json=noRemoteControl,proto3" json:"no_remote_control,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Ip string `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` + Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` + Os string `protobuf:"bytes,3,opt,name=os,proto3" json:"os,omitempty"` + Status Status `protobuf:"varint,4,opt,name=status,proto3,enum=agent.Status" json:"status,omitempty"` + Platform string `protobuf:"bytes,5,opt,name=platform,proto3" json:"platform,omitempty"` + Version string `protobuf:"bytes,6,opt,name=version,proto3" json:"version,omitempty"` + AgentKey string `protobuf:"bytes,7,opt,name=agent_key,json=agentKey,proto3" json:"agent_key,omitempty"` + Id uint32 `protobuf:"varint,8,opt,name=id,proto3" json:"id,omitempty"` + LastSeen string `protobuf:"bytes,9,opt,name=last_seen,json=lastSeen,proto3" json:"last_seen,omitempty"` + Mac string `protobuf:"bytes,10,opt,name=mac,proto3" json:"mac,omitempty"` + OsMajorVersion string `protobuf:"bytes,11,opt,name=os_major_version,json=osMajorVersion,proto3" json:"os_major_version,omitempty"` + OsMinorVersion string `protobuf:"bytes,12,opt,name=os_minor_version,json=osMinorVersion,proto3" json:"os_minor_version,omitempty"` + Aliases string `protobuf:"bytes,13,opt,name=aliases,proto3" json:"aliases,omitempty"` + Addresses string `protobuf:"bytes,14,opt,name=addresses,proto3" json:"addresses,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Agent) Reset() { *x = Agent{} - mi := &file_agent_proto_msgTypes[4] + mi := &file_agent_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -390,7 +295,7 @@ func (x *Agent) String() string { func (*Agent) ProtoMessage() {} func (x *Agent) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[4] + mi := &file_agent_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -403,7 +308,7 @@ func (x *Agent) ProtoReflect() protoreflect.Message { // Deprecated: Use Agent.ProtoReflect.Descriptor instead. func (*Agent) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{4} + return file_agent_proto_rawDescGZIP(), []int{2} } func (x *Agent) GetIp() string { @@ -504,26 +409,13 @@ func (x *Agent) GetAddresses() string { return "" } -func (x *Agent) GetTenantId() string { - if x != nil { - return x.TenantId - } - return "" -} - -func (x *Agent) GetNoRemoteControl() bool { - if x != nil { - return x.NoRemoteControl - } - return false -} - type BidirectionalStream struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to StreamMessage: // // *BidirectionalStream_Command // *BidirectionalStream_Result + // *BidirectionalStream_Heartbeat StreamMessage isBidirectionalStream_StreamMessage `protobuf_oneof:"stream_message"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -531,7 +423,7 @@ type BidirectionalStream struct { func (x *BidirectionalStream) Reset() { *x = BidirectionalStream{} - mi := &file_agent_proto_msgTypes[5] + mi := &file_agent_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -543,7 +435,7 @@ func (x *BidirectionalStream) String() string { func (*BidirectionalStream) ProtoMessage() {} func (x *BidirectionalStream) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[5] + mi := &file_agent_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -556,7 +448,7 @@ func (x *BidirectionalStream) ProtoReflect() protoreflect.Message { // Deprecated: Use BidirectionalStream.ProtoReflect.Descriptor instead. func (*BidirectionalStream) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{5} + return file_agent_proto_rawDescGZIP(), []int{3} } func (x *BidirectionalStream) GetStreamMessage() isBidirectionalStream_StreamMessage { @@ -584,6 +476,15 @@ func (x *BidirectionalStream) GetResult() *CommandResult { return nil } +func (x *BidirectionalStream) GetHeartbeat() *Heartbeat { + if x != nil { + if x, ok := x.StreamMessage.(*BidirectionalStream_Heartbeat); ok { + return x.Heartbeat + } + } + return nil +} + type isBidirectionalStream_StreamMessage interface { isBidirectionalStream_StreamMessage() } @@ -596,10 +497,52 @@ type BidirectionalStream_Result struct { Result *CommandResult `protobuf:"bytes,2,opt,name=result,proto3,oneof"` } +type BidirectionalStream_Heartbeat struct { + Heartbeat *Heartbeat `protobuf:"bytes,3,opt,name=heartbeat,proto3,oneof"` +} + func (*BidirectionalStream_Command) isBidirectionalStream_StreamMessage() {} func (*BidirectionalStream_Result) isBidirectionalStream_StreamMessage() {} +func (*BidirectionalStream_Heartbeat) isBidirectionalStream_StreamMessage() {} + +type Heartbeat struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Heartbeat) Reset() { + *x = Heartbeat{} + mi := &file_agent_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Heartbeat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Heartbeat) ProtoMessage() {} + +func (x *Heartbeat) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Heartbeat.ProtoReflect.Descriptor instead. +func (*Heartbeat) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{4} +} + type UtmCommand struct { state protoimpl.MessageState `protogen:"open.v1"` AgentId string `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` @@ -616,7 +559,7 @@ type UtmCommand struct { func (x *UtmCommand) Reset() { *x = UtmCommand{} - mi := &file_agent_proto_msgTypes[6] + mi := &file_agent_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -628,7 +571,7 @@ func (x *UtmCommand) String() string { func (*UtmCommand) ProtoMessage() {} func (x *UtmCommand) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[6] + mi := &file_agent_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -641,7 +584,7 @@ func (x *UtmCommand) ProtoReflect() protoreflect.Message { // Deprecated: Use UtmCommand.ProtoReflect.Descriptor instead. func (*UtmCommand) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{6} + return file_agent_proto_rawDescGZIP(), []int{5} } func (x *UtmCommand) GetAgentId() string { @@ -712,7 +655,7 @@ type CommandResult struct { func (x *CommandResult) Reset() { *x = CommandResult{} - mi := &file_agent_proto_msgTypes[7] + mi := &file_agent_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -724,7 +667,7 @@ func (x *CommandResult) String() string { func (*CommandResult) ProtoMessage() {} func (x *CommandResult) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[7] + mi := &file_agent_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -737,7 +680,7 @@ func (x *CommandResult) ProtoReflect() protoreflect.Message { // Deprecated: Use CommandResult.ProtoReflect.Descriptor instead. func (*CommandResult) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{7} + return file_agent_proto_rawDescGZIP(), []int{6} } func (x *CommandResult) GetAgentId() string { @@ -778,7 +721,7 @@ type ListAgentsCommandsResponse struct { func (x *ListAgentsCommandsResponse) Reset() { *x = ListAgentsCommandsResponse{} - mi := &file_agent_proto_msgTypes[8] + mi := &file_agent_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -790,7 +733,7 @@ func (x *ListAgentsCommandsResponse) String() string { func (*ListAgentsCommandsResponse) ProtoMessage() {} func (x *ListAgentsCommandsResponse) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[8] + mi := &file_agent_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -803,7 +746,7 @@ func (x *ListAgentsCommandsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAgentsCommandsResponse.ProtoReflect.Descriptor instead. func (*ListAgentsCommandsResponse) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{8} + return file_agent_proto_rawDescGZIP(), []int{7} } func (x *ListAgentsCommandsResponse) GetRows() []*AgentCommand { @@ -839,7 +782,7 @@ type AgentCommand struct { func (x *AgentCommand) Reset() { *x = AgentCommand{} - mi := &file_agent_proto_msgTypes[9] + mi := &file_agent_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -851,7 +794,7 @@ func (x *AgentCommand) String() string { func (*AgentCommand) ProtoMessage() {} func (x *AgentCommand) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[9] + mi := &file_agent_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -864,7 +807,7 @@ func (x *AgentCommand) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentCommand.ProtoReflect.Descriptor instead. func (*AgentCommand) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{9} + return file_agent_proto_rawDescGZIP(), []int{8} } func (x *AgentCommand) GetCreatedAt() *timestamppb.Timestamp { @@ -948,11 +891,7 @@ var File_agent_proto protoreflect.FileDescriptor const file_agent_proto_rawDesc = "" + "\n" + - "\vagent.proto\x12\x05agent\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\fcommon.proto\"2\n" + - "\x14ConnectionKeyRequest\x12\x1a\n" + - "\btenantId\x18\x01 \x01(\tR\btenantId\">\n" + - "\x15ConnectionKeyResponse\x12%\n" + - "\x0econnection_key\x18\x01 \x01(\tR\rconnectionKey\"\xeb\x02\n" + + "\vagent.proto\x12\x05agent\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\fcommon.proto\"\xeb\x02\n" + "\fAgentRequest\x12\x0e\n" + "\x02ip\x18\x01 \x01(\tR\x02ip\x12\x1a\n" + "\bhostname\x18\x02 \x01(\tR\bhostname\x12\x0e\n" + @@ -970,7 +909,7 @@ const file_agent_proto_rawDesc = "" + "\x11no_remote_control\x18\f \x01(\bR\x0fnoRemoteControl\"L\n" + "\x12ListAgentsResponse\x12 \n" + "\x04rows\x18\x01 \x03(\v2\f.agent.AgentR\x04rows\x12\x14\n" + - "\x05total\x18\x02 \x01(\x05R\x05total\"\xd1\x03\n" + + "\x05total\x18\x02 \x01(\x05R\x05total\"\x88\x03\n" + "\x05Agent\x12\x0e\n" + "\x02ip\x18\x01 \x01(\tR\x02ip\x12\x1a\n" + "\bhostname\x18\x02 \x01(\tR\bhostname\x12\x0e\n" + @@ -986,13 +925,13 @@ const file_agent_proto_rawDesc = "" + "\x10os_major_version\x18\v \x01(\tR\x0eosMajorVersion\x12(\n" + "\x10os_minor_version\x18\f \x01(\tR\x0eosMinorVersion\x12\x18\n" + "\aaliases\x18\r \x01(\tR\aaliases\x12\x1c\n" + - "\taddresses\x18\x0e \x01(\tR\taddresses\x12\x1b\n" + - "\ttenant_id\x18\x0f \x01(\tR\btenantId\x12*\n" + - "\x11no_remote_control\x18\x10 \x01(\bR\x0fnoRemoteControl\"\x86\x01\n" + + "\taddresses\x18\x0e \x01(\tR\taddresses\"\xb8\x01\n" + "\x13BidirectionalStream\x12-\n" + "\acommand\x18\x01 \x01(\v2\x11.agent.UtmCommandH\x00R\acommand\x12.\n" + - "\x06result\x18\x02 \x01(\v2\x14.agent.CommandResultH\x00R\x06resultB\x10\n" + - "\x0estream_message\"\xe5\x01\n" + + "\x06result\x18\x02 \x01(\v2\x14.agent.CommandResultH\x00R\x06result\x120\n" + + "\theartbeat\x18\x03 \x01(\v2\x10.agent.HeartbeatH\x00R\theartbeatB\x10\n" + + "\x0estream_message\"\v\n" + + "\tHeartbeat\"\xe5\x01\n" + "\n" + "UtmCommand\x12\x19\n" + "\bagent_id\x18\x01 \x01(\tR\aagentId\x12\x18\n" + @@ -1036,20 +975,17 @@ const file_agent_proto_rawDesc = "" + "\x05QUEUE\x10\x01\x12\v\n" + "\aPENDING\x10\x02\x12\f\n" + "\bEXECUTED\x10\x03\x12\t\n" + - "\x05ERROR\x10\x042\xe9\x03\n" + + "\x05ERROR\x10\x042\x9c\x03\n" + "\fAgentService\x12;\n" + "\rRegisterAgent\x12\x13.agent.AgentRequest\x1a\x13.agent.AuthResponse\"\x00\x129\n" + "\vUpdateAgent\x12\x13.agent.AgentRequest\x1a\x13.agent.AuthResponse\"\x00\x12:\n" + "\vDeleteAgent\x12\x14.agent.DeleteRequest\x1a\x13.agent.AuthResponse\"\x00\x12=\n" + "\n" + "ListAgents\x12\x12.agent.ListRequest\x1a\x19.agent.ListAgentsResponse\"\x00\x12K\n" + - "\fGetAgentAuth\x12\x1b.agent.ConnectorAuthRequest\x1a\x1c.agent.ConnectorAuthResponse\"\x00\x12K\n" + "\vAgentStream\x12\x1a.agent.BidirectionalStream\x1a\x1a.agent.BidirectionalStream\"\x00(\x010\x01\x12L\n" + - "\x11ListAgentCommands\x12\x12.agent.ListRequest\x1a!.agent.ListAgentsCommandsResponse\"\x002\xf4\x01\n" + + "\x11ListAgentCommands\x12\x12.agent.ListRequest\x1a!.agent.ListAgentsCommandsResponse\"\x002O\n" + "\fPanelService\x12?\n" + - "\x0eProcessCommand\x12\x11.agent.UtmCommand\x1a\x14.agent.CommandResult\"\x00(\x010\x01\x12O\n" + - "\x10GetConnectionKey\x12\x1b.agent.ConnectionKeyRequest\x1a\x1c.agent.ConnectionKeyResponse\"\x00\x12R\n" + - "\x13RotateConnectionKey\x12\x1b.agent.ConnectionKeyRequest\x1a\x1c.agent.ConnectionKeyResponse\"\x00B2Z0github.com/utmstack/UTMStack/agent-manager/agentb\x06proto3" + "\x0eProcessCommand\x12\x11.agent.UtmCommand\x1a\x14.agent.CommandResult\"\x00(\x010\x01B2Z0github.com/utmstack/UTMStack/agent-manager/agentb\x06proto3" var ( file_agent_proto_rawDescOnce sync.Once @@ -1064,62 +1000,54 @@ func file_agent_proto_rawDescGZIP() []byte { } var file_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_agent_proto_goTypes = []any{ (AgentCommandStatus)(0), // 0: agent.AgentCommandStatus - (*ConnectionKeyRequest)(nil), // 1: agent.ConnectionKeyRequest - (*ConnectionKeyResponse)(nil), // 2: agent.ConnectionKeyResponse - (*AgentRequest)(nil), // 3: agent.AgentRequest - (*ListAgentsResponse)(nil), // 4: agent.ListAgentsResponse - (*Agent)(nil), // 5: agent.Agent - (*BidirectionalStream)(nil), // 6: agent.BidirectionalStream - (*UtmCommand)(nil), // 7: agent.UtmCommand - (*CommandResult)(nil), // 8: agent.CommandResult - (*ListAgentsCommandsResponse)(nil), // 9: agent.ListAgentsCommandsResponse - (*AgentCommand)(nil), // 10: agent.AgentCommand - (Status)(0), // 11: agent.Status - (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp - (*DeleteRequest)(nil), // 13: agent.DeleteRequest - (*ListRequest)(nil), // 14: agent.ListRequest - (*ConnectorAuthRequest)(nil), // 15: agent.ConnectorAuthRequest - (*AuthResponse)(nil), // 16: agent.AuthResponse - (*ConnectorAuthResponse)(nil), // 17: agent.ConnectorAuthResponse + (*AgentRequest)(nil), // 1: agent.AgentRequest + (*ListAgentsResponse)(nil), // 2: agent.ListAgentsResponse + (*Agent)(nil), // 3: agent.Agent + (*BidirectionalStream)(nil), // 4: agent.BidirectionalStream + (*Heartbeat)(nil), // 5: agent.Heartbeat + (*UtmCommand)(nil), // 6: agent.UtmCommand + (*CommandResult)(nil), // 7: agent.CommandResult + (*ListAgentsCommandsResponse)(nil), // 8: agent.ListAgentsCommandsResponse + (*AgentCommand)(nil), // 9: agent.AgentCommand + (Status)(0), // 10: agent.Status + (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp + (*DeleteRequest)(nil), // 12: agent.DeleteRequest + (*ListRequest)(nil), // 13: agent.ListRequest + (*AuthResponse)(nil), // 14: agent.AuthResponse } var file_agent_proto_depIdxs = []int32{ - 5, // 0: agent.ListAgentsResponse.rows:type_name -> agent.Agent - 11, // 1: agent.Agent.status:type_name -> agent.Status - 7, // 2: agent.BidirectionalStream.command:type_name -> agent.UtmCommand - 8, // 3: agent.BidirectionalStream.result:type_name -> agent.CommandResult - 12, // 4: agent.CommandResult.executed_at:type_name -> google.protobuf.Timestamp - 10, // 5: agent.ListAgentsCommandsResponse.rows:type_name -> agent.AgentCommand - 12, // 6: agent.AgentCommand.created_at:type_name -> google.protobuf.Timestamp - 12, // 7: agent.AgentCommand.updated_at:type_name -> google.protobuf.Timestamp - 0, // 8: agent.AgentCommand.command_status:type_name -> agent.AgentCommandStatus - 3, // 9: agent.AgentService.RegisterAgent:input_type -> agent.AgentRequest - 3, // 10: agent.AgentService.UpdateAgent:input_type -> agent.AgentRequest - 13, // 11: agent.AgentService.DeleteAgent:input_type -> agent.DeleteRequest - 14, // 12: agent.AgentService.ListAgents:input_type -> agent.ListRequest - 15, // 13: agent.AgentService.GetAgentAuth:input_type -> agent.ConnectorAuthRequest - 6, // 14: agent.AgentService.AgentStream:input_type -> agent.BidirectionalStream - 14, // 15: agent.AgentService.ListAgentCommands:input_type -> agent.ListRequest - 7, // 16: agent.PanelService.ProcessCommand:input_type -> agent.UtmCommand - 1, // 17: agent.PanelService.GetConnectionKey:input_type -> agent.ConnectionKeyRequest - 1, // 18: agent.PanelService.RotateConnectionKey:input_type -> agent.ConnectionKeyRequest - 16, // 19: agent.AgentService.RegisterAgent:output_type -> agent.AuthResponse - 16, // 20: agent.AgentService.UpdateAgent:output_type -> agent.AuthResponse - 16, // 21: agent.AgentService.DeleteAgent:output_type -> agent.AuthResponse - 4, // 22: agent.AgentService.ListAgents:output_type -> agent.ListAgentsResponse - 17, // 23: agent.AgentService.GetAgentAuth:output_type -> agent.ConnectorAuthResponse - 6, // 24: agent.AgentService.AgentStream:output_type -> agent.BidirectionalStream - 9, // 25: agent.AgentService.ListAgentCommands:output_type -> agent.ListAgentsCommandsResponse - 8, // 26: agent.PanelService.ProcessCommand:output_type -> agent.CommandResult - 2, // 27: agent.PanelService.GetConnectionKey:output_type -> agent.ConnectionKeyResponse - 2, // 28: agent.PanelService.RotateConnectionKey:output_type -> agent.ConnectionKeyResponse - 19, // [19:29] is the sub-list for method output_type - 9, // [9:19] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 3, // 0: agent.ListAgentsResponse.rows:type_name -> agent.Agent + 10, // 1: agent.Agent.status:type_name -> agent.Status + 6, // 2: agent.BidirectionalStream.command:type_name -> agent.UtmCommand + 7, // 3: agent.BidirectionalStream.result:type_name -> agent.CommandResult + 5, // 4: agent.BidirectionalStream.heartbeat:type_name -> agent.Heartbeat + 11, // 5: agent.CommandResult.executed_at:type_name -> google.protobuf.Timestamp + 9, // 6: agent.ListAgentsCommandsResponse.rows:type_name -> agent.AgentCommand + 11, // 7: agent.AgentCommand.created_at:type_name -> google.protobuf.Timestamp + 11, // 8: agent.AgentCommand.updated_at:type_name -> google.protobuf.Timestamp + 0, // 9: agent.AgentCommand.command_status:type_name -> agent.AgentCommandStatus + 1, // 10: agent.AgentService.RegisterAgent:input_type -> agent.AgentRequest + 1, // 11: agent.AgentService.UpdateAgent:input_type -> agent.AgentRequest + 12, // 12: agent.AgentService.DeleteAgent:input_type -> agent.DeleteRequest + 13, // 13: agent.AgentService.ListAgents:input_type -> agent.ListRequest + 4, // 14: agent.AgentService.AgentStream:input_type -> agent.BidirectionalStream + 13, // 15: agent.AgentService.ListAgentCommands:input_type -> agent.ListRequest + 6, // 16: agent.PanelService.ProcessCommand:input_type -> agent.UtmCommand + 14, // 17: agent.AgentService.RegisterAgent:output_type -> agent.AuthResponse + 14, // 18: agent.AgentService.UpdateAgent:output_type -> agent.AuthResponse + 14, // 19: agent.AgentService.DeleteAgent:output_type -> agent.AuthResponse + 2, // 20: agent.AgentService.ListAgents:output_type -> agent.ListAgentsResponse + 4, // 21: agent.AgentService.AgentStream:output_type -> agent.BidirectionalStream + 8, // 22: agent.AgentService.ListAgentCommands:output_type -> agent.ListAgentsCommandsResponse + 7, // 23: agent.PanelService.ProcessCommand:output_type -> agent.CommandResult + 17, // [17:24] is the sub-list for method output_type + 10, // [10:17] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_agent_proto_init() } @@ -1128,9 +1056,10 @@ func file_agent_proto_init() { return } file_common_proto_init() - file_agent_proto_msgTypes[5].OneofWrappers = []any{ + file_agent_proto_msgTypes[3].OneofWrappers = []any{ (*BidirectionalStream_Command)(nil), (*BidirectionalStream_Result)(nil), + (*BidirectionalStream_Heartbeat)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1138,7 +1067,7 @@ func file_agent_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_agent_proto_rawDesc), len(file_agent_proto_rawDesc)), NumEnums: 1, - NumMessages: 10, + NumMessages: 9, NumExtensions: 0, NumServices: 2, }, diff --git a/agent/agent/agent_grpc.pb.go b/agent/agent/agent_grpc.pb.go index 30585f33d..d66954036 100644 --- a/agent/agent/agent_grpc.pb.go +++ b/agent/agent/agent_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc v5.29.3 +// - protoc-gen-go-grpc v1.6.2 +// - protoc v7.35.1 // source: agent.proto package agent @@ -23,7 +23,6 @@ const ( AgentService_UpdateAgent_FullMethodName = "/agent.AgentService/UpdateAgent" AgentService_DeleteAgent_FullMethodName = "/agent.AgentService/DeleteAgent" AgentService_ListAgents_FullMethodName = "/agent.AgentService/ListAgents" - AgentService_GetAgentAuth_FullMethodName = "/agent.AgentService/GetAgentAuth" AgentService_AgentStream_FullMethodName = "/agent.AgentService/AgentStream" AgentService_ListAgentCommands_FullMethodName = "/agent.AgentService/ListAgentCommands" ) @@ -36,7 +35,6 @@ type AgentServiceClient interface { UpdateAgent(ctx context.Context, in *AgentRequest, opts ...grpc.CallOption) (*AuthResponse, error) DeleteAgent(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*AuthResponse, error) ListAgents(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListAgentsResponse, error) - GetAgentAuth(ctx context.Context, in *ConnectorAuthRequest, opts ...grpc.CallOption) (*ConnectorAuthResponse, error) AgentStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[BidirectionalStream, BidirectionalStream], error) ListAgentCommands(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListAgentsCommandsResponse, error) } @@ -89,16 +87,6 @@ func (c *agentServiceClient) ListAgents(ctx context.Context, in *ListRequest, op return out, nil } -func (c *agentServiceClient) GetAgentAuth(ctx context.Context, in *ConnectorAuthRequest, opts ...grpc.CallOption) (*ConnectorAuthResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ConnectorAuthResponse) - err := c.cc.Invoke(ctx, AgentService_GetAgentAuth_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *agentServiceClient) AgentStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[BidirectionalStream, BidirectionalStream], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &AgentService_ServiceDesc.Streams[0], AgentService_AgentStream_FullMethodName, cOpts...) @@ -130,7 +118,6 @@ type AgentServiceServer interface { UpdateAgent(context.Context, *AgentRequest) (*AuthResponse, error) DeleteAgent(context.Context, *DeleteRequest) (*AuthResponse, error) ListAgents(context.Context, *ListRequest) (*ListAgentsResponse, error) - GetAgentAuth(context.Context, *ConnectorAuthRequest) (*ConnectorAuthResponse, error) AgentStream(grpc.BidiStreamingServer[BidirectionalStream, BidirectionalStream]) error ListAgentCommands(context.Context, *ListRequest) (*ListAgentsCommandsResponse, error) mustEmbedUnimplementedAgentServiceServer() @@ -144,25 +131,22 @@ type AgentServiceServer interface { type UnimplementedAgentServiceServer struct{} func (UnimplementedAgentServiceServer) RegisterAgent(context.Context, *AgentRequest) (*AuthResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RegisterAgent not implemented") + return nil, status.Error(codes.Unimplemented, "method RegisterAgent not implemented") } func (UnimplementedAgentServiceServer) UpdateAgent(context.Context, *AgentRequest) (*AuthResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateAgent not implemented") + return nil, status.Error(codes.Unimplemented, "method UpdateAgent not implemented") } func (UnimplementedAgentServiceServer) DeleteAgent(context.Context, *DeleteRequest) (*AuthResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteAgent not implemented") + return nil, status.Error(codes.Unimplemented, "method DeleteAgent not implemented") } func (UnimplementedAgentServiceServer) ListAgents(context.Context, *ListRequest) (*ListAgentsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListAgents not implemented") -} -func (UnimplementedAgentServiceServer) GetAgentAuth(context.Context, *ConnectorAuthRequest) (*ConnectorAuthResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetAgentAuth not implemented") + return nil, status.Error(codes.Unimplemented, "method ListAgents not implemented") } func (UnimplementedAgentServiceServer) AgentStream(grpc.BidiStreamingServer[BidirectionalStream, BidirectionalStream]) error { - return status.Errorf(codes.Unimplemented, "method AgentStream not implemented") + return status.Error(codes.Unimplemented, "method AgentStream not implemented") } func (UnimplementedAgentServiceServer) ListAgentCommands(context.Context, *ListRequest) (*ListAgentsCommandsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListAgentCommands not implemented") + return nil, status.Error(codes.Unimplemented, "method ListAgentCommands not implemented") } func (UnimplementedAgentServiceServer) mustEmbedUnimplementedAgentServiceServer() {} func (UnimplementedAgentServiceServer) testEmbeddedByValue() {} @@ -175,7 +159,7 @@ type UnsafeAgentServiceServer interface { } func RegisterAgentServiceServer(s grpc.ServiceRegistrar, srv AgentServiceServer) { - // If the following call pancis, it indicates UnimplementedAgentServiceServer was + // If the following call panics, it indicates UnimplementedAgentServiceServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. @@ -257,24 +241,6 @@ func _AgentService_ListAgents_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } -func _AgentService_GetAgentAuth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ConnectorAuthRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(AgentServiceServer).GetAgentAuth(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: AgentService_GetAgentAuth_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AgentServiceServer).GetAgentAuth(ctx, req.(*ConnectorAuthRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _AgentService_AgentStream_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(AgentServiceServer).AgentStream(&grpc.GenericServerStream[BidirectionalStream, BidirectionalStream]{ServerStream: stream}) } @@ -323,10 +289,6 @@ var AgentService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListAgents", Handler: _AgentService_ListAgents_Handler, }, - { - MethodName: "GetAgentAuth", - Handler: _AgentService_GetAgentAuth_Handler, - }, { MethodName: "ListAgentCommands", Handler: _AgentService_ListAgentCommands_Handler, @@ -344,9 +306,7 @@ var AgentService_ServiceDesc = grpc.ServiceDesc{ } const ( - PanelService_ProcessCommand_FullMethodName = "/agent.PanelService/ProcessCommand" - PanelService_GetConnectionKey_FullMethodName = "/agent.PanelService/GetConnectionKey" - PanelService_RotateConnectionKey_FullMethodName = "/agent.PanelService/RotateConnectionKey" + PanelService_ProcessCommand_FullMethodName = "/agent.PanelService/ProcessCommand" ) // PanelServiceClient is the client API for PanelService service. @@ -354,8 +314,6 @@ const ( // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type PanelServiceClient interface { ProcessCommand(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[UtmCommand, CommandResult], error) - GetConnectionKey(ctx context.Context, in *ConnectionKeyRequest, opts ...grpc.CallOption) (*ConnectionKeyResponse, error) - RotateConnectionKey(ctx context.Context, in *ConnectionKeyRequest, opts ...grpc.CallOption) (*ConnectionKeyResponse, error) } type panelServiceClient struct { @@ -379,33 +337,11 @@ func (c *panelServiceClient) ProcessCommand(ctx context.Context, opts ...grpc.Ca // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. type PanelService_ProcessCommandClient = grpc.BidiStreamingClient[UtmCommand, CommandResult] -func (c *panelServiceClient) GetConnectionKey(ctx context.Context, in *ConnectionKeyRequest, opts ...grpc.CallOption) (*ConnectionKeyResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ConnectionKeyResponse) - err := c.cc.Invoke(ctx, PanelService_GetConnectionKey_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *panelServiceClient) RotateConnectionKey(ctx context.Context, in *ConnectionKeyRequest, opts ...grpc.CallOption) (*ConnectionKeyResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ConnectionKeyResponse) - err := c.cc.Invoke(ctx, PanelService_RotateConnectionKey_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - // PanelServiceServer is the server API for PanelService service. // All implementations must embed UnimplementedPanelServiceServer // for forward compatibility. type PanelServiceServer interface { ProcessCommand(grpc.BidiStreamingServer[UtmCommand, CommandResult]) error - GetConnectionKey(context.Context, *ConnectionKeyRequest) (*ConnectionKeyResponse, error) - RotateConnectionKey(context.Context, *ConnectionKeyRequest) (*ConnectionKeyResponse, error) mustEmbedUnimplementedPanelServiceServer() } @@ -417,13 +353,7 @@ type PanelServiceServer interface { type UnimplementedPanelServiceServer struct{} func (UnimplementedPanelServiceServer) ProcessCommand(grpc.BidiStreamingServer[UtmCommand, CommandResult]) error { - return status.Errorf(codes.Unimplemented, "method ProcessCommand not implemented") -} -func (UnimplementedPanelServiceServer) GetConnectionKey(context.Context, *ConnectionKeyRequest) (*ConnectionKeyResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetConnectionKey not implemented") -} -func (UnimplementedPanelServiceServer) RotateConnectionKey(context.Context, *ConnectionKeyRequest) (*ConnectionKeyResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RotateConnectionKey not implemented") + return status.Error(codes.Unimplemented, "method ProcessCommand not implemented") } func (UnimplementedPanelServiceServer) mustEmbedUnimplementedPanelServiceServer() {} func (UnimplementedPanelServiceServer) testEmbeddedByValue() {} @@ -436,7 +366,7 @@ type UnsafePanelServiceServer interface { } func RegisterPanelServiceServer(s grpc.ServiceRegistrar, srv PanelServiceServer) { - // If the following call pancis, it indicates UnimplementedPanelServiceServer was + // If the following call panics, it indicates UnimplementedPanelServiceServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. @@ -453,58 +383,13 @@ func _PanelService_ProcessCommand_Handler(srv interface{}, stream grpc.ServerStr // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. type PanelService_ProcessCommandServer = grpc.BidiStreamingServer[UtmCommand, CommandResult] -func _PanelService_GetConnectionKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ConnectionKeyRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PanelServiceServer).GetConnectionKey(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PanelService_GetConnectionKey_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PanelServiceServer).GetConnectionKey(ctx, req.(*ConnectionKeyRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _PanelService_RotateConnectionKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ConnectionKeyRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PanelServiceServer).RotateConnectionKey(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PanelService_RotateConnectionKey_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PanelServiceServer).RotateConnectionKey(ctx, req.(*ConnectionKeyRequest)) - } - return interceptor(ctx, in, info, handler) -} - // PanelService_ServiceDesc is the grpc.ServiceDesc for PanelService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var PanelService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "agent.PanelService", HandlerType: (*PanelServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetConnectionKey", - Handler: _PanelService_GetConnectionKey_Handler, - }, - { - MethodName: "RotateConnectionKey", - Handler: _PanelService_RotateConnectionKey_Handler, - }, - }, + Methods: []grpc.MethodDesc{}, Streams: []grpc.StreamDesc{ { StreamName: "ProcessCommand", diff --git a/agent/agent/incident_response.go b/agent/agent/incident_response.go index 5841c44e8..e55876bad 100644 --- a/agent/agent/incident_response.go +++ b/agent/agent/incident_response.go @@ -5,6 +5,7 @@ import ( "fmt" "runtime" "strconv" + "sync" "time" "github.com/utmstack/UTMStack/agent/config" @@ -13,6 +14,8 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) +const heartbeatInterval = 30 * time.Second + func IncidentResponseStream(cnf *config.Config, ctx context.Context) { path := fs.GetExecutablePath() var connErrLogged, streamErrLogged bool @@ -35,6 +38,10 @@ func IncidentResponseStream(cnf *config.Config, ctx context.Context) { connErrLogged = false + var sendMu sync.Mutex + hbCtx, hbCancel := context.WithCancel(ctx) + go agentHeartbeatLoop(hbCtx, stream, &sendMu) + recvLoop: for { in, err := stream.Recv() @@ -48,7 +55,7 @@ func IncidentResponseStream(cnf *config.Config, ctx context.Context) { switch msg := in.StreamMessage.(type) { case *BidirectionalStream_Command: - err = commandProcessor(path, stream, cnf, msg.Command.Command, msg.Command.CmdId, msg.Command.Shell) + err = commandProcessor(path, stream, &sendMu, cnf, msg.Command.Command, msg.Command.CmdId, msg.Command.Shell) if err != nil { action := HandleGRPCStreamError(err, "error sending result to server", &streamErrLogged) if action == ActionReconnect { @@ -59,10 +66,34 @@ func IncidentResponseStream(cnf *config.Config, ctx context.Context) { } streamErrLogged = false } + hbCancel() + } +} + +func agentHeartbeatLoop(ctx context.Context, stream AgentService_AgentStreamClient, mu *sync.Mutex) { + t := time.NewTicker(heartbeatInterval) + defer t.Stop() + for { + select { + case <-ctx.Done(): + return + case <-t.C: + if err := sendLocked(stream, mu, &BidirectionalStream{ + StreamMessage: &BidirectionalStream_Heartbeat{Heartbeat: &Heartbeat{}}, + }); err != nil { + return + } + } } } -func commandProcessor(path string, stream AgentService_AgentStreamClient, cnf *config.Config, command, cmdId, shell string) error { +func sendLocked(stream AgentService_AgentStreamClient, mu *sync.Mutex, msg *BidirectionalStream) error { + mu.Lock() + defer mu.Unlock() + return stream.Send(msg) +} + +func commandProcessor(path string, stream AgentService_AgentStreamClient, sendMu *sync.Mutex, cnf *config.Config, command, cmdId, shell string) error { var result string var errB bool @@ -70,7 +101,7 @@ func commandProcessor(path string, stream AgentService_AgentStreamClient, cnf *c if cnf.NoRemoteControl { const refused = "refused: this agent was installed with no-remote-control" utils.Logger.ErrorF("%s (command: %s)", refused, command) - return stream.Send(&BidirectionalStream{ + return sendLocked(stream, sendMu, &BidirectionalStream{ StreamMessage: &BidirectionalStream_Result{ Result: &CommandResult{ Result: refused, @@ -108,7 +139,7 @@ func commandProcessor(path string, stream AgentService_AgentStreamClient, cnf *c utils.Logger.LogF(100, "Result when executing the command %s: %s", command, result) } - if err := stream.Send(&BidirectionalStream{ + if err := sendLocked(stream, sendMu, &BidirectionalStream{ StreamMessage: &BidirectionalStream_Result{ Result: &CommandResult{Result: result, AgentId: strconv.Itoa(int(cnf.AgentID)), ExecutedAt: timestamppb.Now(), CmdId: cmdId}, }, diff --git a/agent/protos/agent.proto b/agent/protos/agent.proto index 39d98fdd4..2fb4a5621 100644 --- a/agent/protos/agent.proto +++ b/agent/protos/agent.proto @@ -40,6 +40,7 @@ message AgentRequest { string os_minor_version = 9; string aliases = 10; string addresses = 11; + bool no_remote_control = 12; } message ListAgentsResponse { @@ -68,9 +69,12 @@ message BidirectionalStream { oneof stream_message { UtmCommand command = 1; CommandResult result = 2; + Heartbeat heartbeat = 3; } } +message Heartbeat {} + message UtmCommand { string agent_id = 1; string command = 2; diff --git a/backend/pkg/agentmanager/agent/agent.pb.go b/backend/pkg/agentmanager/agent/agent.pb.go index 54e54fa1d..cce8657d5 100644 --- a/backend/pkg/agentmanager/agent/agent.pb.go +++ b/backend/pkg/agentmanager/agent/agent.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v5.29.3 +// protoc-gen-go v1.36.12 +// protoc v7.35.1 // source: agent.proto package agent @@ -520,6 +520,7 @@ type BidirectionalStream struct { // // *BidirectionalStream_Command // *BidirectionalStream_Result + // *BidirectionalStream_Heartbeat StreamMessage isBidirectionalStream_StreamMessage `protobuf_oneof:"stream_message"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -580,6 +581,15 @@ func (x *BidirectionalStream) GetResult() *CommandResult { return nil } +func (x *BidirectionalStream) GetHeartbeat() *Heartbeat { + if x != nil { + if x, ok := x.StreamMessage.(*BidirectionalStream_Heartbeat); ok { + return x.Heartbeat + } + } + return nil +} + type isBidirectionalStream_StreamMessage interface { isBidirectionalStream_StreamMessage() } @@ -592,10 +602,52 @@ type BidirectionalStream_Result struct { Result *CommandResult `protobuf:"bytes,2,opt,name=result,proto3,oneof"` } +type BidirectionalStream_Heartbeat struct { + Heartbeat *Heartbeat `protobuf:"bytes,3,opt,name=heartbeat,proto3,oneof"` +} + func (*BidirectionalStream_Command) isBidirectionalStream_StreamMessage() {} func (*BidirectionalStream_Result) isBidirectionalStream_StreamMessage() {} +func (*BidirectionalStream_Heartbeat) isBidirectionalStream_StreamMessage() {} + +type Heartbeat struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Heartbeat) Reset() { + *x = Heartbeat{} + mi := &file_agent_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Heartbeat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Heartbeat) ProtoMessage() {} + +func (x *Heartbeat) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Heartbeat.ProtoReflect.Descriptor instead. +func (*Heartbeat) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{6} +} + type UtmCommand struct { state protoimpl.MessageState `protogen:"open.v1"` AgentId string `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` @@ -612,7 +664,7 @@ type UtmCommand struct { func (x *UtmCommand) Reset() { *x = UtmCommand{} - mi := &file_agent_proto_msgTypes[6] + mi := &file_agent_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -624,7 +676,7 @@ func (x *UtmCommand) String() string { func (*UtmCommand) ProtoMessage() {} func (x *UtmCommand) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[6] + mi := &file_agent_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -637,7 +689,7 @@ func (x *UtmCommand) ProtoReflect() protoreflect.Message { // Deprecated: Use UtmCommand.ProtoReflect.Descriptor instead. func (*UtmCommand) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{6} + return file_agent_proto_rawDescGZIP(), []int{7} } func (x *UtmCommand) GetAgentId() string { @@ -708,7 +760,7 @@ type CommandResult struct { func (x *CommandResult) Reset() { *x = CommandResult{} - mi := &file_agent_proto_msgTypes[7] + mi := &file_agent_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -720,7 +772,7 @@ func (x *CommandResult) String() string { func (*CommandResult) ProtoMessage() {} func (x *CommandResult) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[7] + mi := &file_agent_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -733,7 +785,7 @@ func (x *CommandResult) ProtoReflect() protoreflect.Message { // Deprecated: Use CommandResult.ProtoReflect.Descriptor instead. func (*CommandResult) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{7} + return file_agent_proto_rawDescGZIP(), []int{8} } func (x *CommandResult) GetAgentId() string { @@ -774,7 +826,7 @@ type ListAgentsCommandsResponse struct { func (x *ListAgentsCommandsResponse) Reset() { *x = ListAgentsCommandsResponse{} - mi := &file_agent_proto_msgTypes[8] + mi := &file_agent_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -786,7 +838,7 @@ func (x *ListAgentsCommandsResponse) String() string { func (*ListAgentsCommandsResponse) ProtoMessage() {} func (x *ListAgentsCommandsResponse) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[8] + mi := &file_agent_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -799,7 +851,7 @@ func (x *ListAgentsCommandsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAgentsCommandsResponse.ProtoReflect.Descriptor instead. func (*ListAgentsCommandsResponse) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{8} + return file_agent_proto_rawDescGZIP(), []int{9} } func (x *ListAgentsCommandsResponse) GetRows() []*AgentCommand { @@ -835,7 +887,7 @@ type AgentCommand struct { func (x *AgentCommand) Reset() { *x = AgentCommand{} - mi := &file_agent_proto_msgTypes[9] + mi := &file_agent_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -847,7 +899,7 @@ func (x *AgentCommand) String() string { func (*AgentCommand) ProtoMessage() {} func (x *AgentCommand) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[9] + mi := &file_agent_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -860,7 +912,7 @@ func (x *AgentCommand) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentCommand.ProtoReflect.Descriptor instead. func (*AgentCommand) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{9} + return file_agent_proto_rawDescGZIP(), []int{10} } func (x *AgentCommand) GetCreatedAt() *timestamppb.Timestamp { @@ -984,11 +1036,13 @@ const file_agent_proto_rawDesc = "" + "\aaliases\x18\r \x01(\tR\aaliases\x12\x1c\n" + "\taddresses\x18\x0e \x01(\tR\taddresses\x12\x1b\n" + "\ttenant_id\x18\x0f \x01(\tR\btenantId\x12*\n" + - "\x11no_remote_control\x18\x10 \x01(\bR\x0fnoRemoteControl\"\x86\x01\n" + + "\x11no_remote_control\x18\x10 \x01(\bR\x0fnoRemoteControl\"\xb8\x01\n" + "\x13BidirectionalStream\x12-\n" + "\acommand\x18\x01 \x01(\v2\x11.agent.UtmCommandH\x00R\acommand\x12.\n" + - "\x06result\x18\x02 \x01(\v2\x14.agent.CommandResultH\x00R\x06resultB\x10\n" + - "\x0estream_message\"\xe5\x01\n" + + "\x06result\x18\x02 \x01(\v2\x14.agent.CommandResultH\x00R\x06result\x120\n" + + "\theartbeat\x18\x03 \x01(\v2\x10.agent.HeartbeatH\x00R\theartbeatB\x10\n" + + "\x0estream_message\"\v\n" + + "\tHeartbeat\"\xe5\x01\n" + "\n" + "UtmCommand\x12\x19\n" + "\bagent_id\x18\x01 \x01(\tR\aagentId\x12\x18\n" + @@ -1060,7 +1114,7 @@ func file_agent_proto_rawDescGZIP() []byte { } var file_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_agent_proto_goTypes = []any{ (AgentCommandStatus)(0), // 0: agent.AgentCommandStatus (*ConnectionKeyRequest)(nil), // 1: agent.ConnectionKeyRequest @@ -1069,53 +1123,55 @@ var file_agent_proto_goTypes = []any{ (*ListAgentsResponse)(nil), // 4: agent.ListAgentsResponse (*Agent)(nil), // 5: agent.Agent (*BidirectionalStream)(nil), // 6: agent.BidirectionalStream - (*UtmCommand)(nil), // 7: agent.UtmCommand - (*CommandResult)(nil), // 8: agent.CommandResult - (*ListAgentsCommandsResponse)(nil), // 9: agent.ListAgentsCommandsResponse - (*AgentCommand)(nil), // 10: agent.AgentCommand - (Status)(0), // 11: agent.Status - (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp - (*DeleteRequest)(nil), // 13: agent.DeleteRequest - (*ListRequest)(nil), // 14: agent.ListRequest - (*ConnectorAuthRequest)(nil), // 15: agent.ConnectorAuthRequest - (*AuthResponse)(nil), // 16: agent.AuthResponse - (*ConnectorAuthResponse)(nil), // 17: agent.ConnectorAuthResponse + (*Heartbeat)(nil), // 7: agent.Heartbeat + (*UtmCommand)(nil), // 8: agent.UtmCommand + (*CommandResult)(nil), // 9: agent.CommandResult + (*ListAgentsCommandsResponse)(nil), // 10: agent.ListAgentsCommandsResponse + (*AgentCommand)(nil), // 11: agent.AgentCommand + (Status)(0), // 12: agent.Status + (*timestamppb.Timestamp)(nil), // 13: google.protobuf.Timestamp + (*DeleteRequest)(nil), // 14: agent.DeleteRequest + (*ListRequest)(nil), // 15: agent.ListRequest + (*ConnectorAuthRequest)(nil), // 16: agent.ConnectorAuthRequest + (*AuthResponse)(nil), // 17: agent.AuthResponse + (*ConnectorAuthResponse)(nil), // 18: agent.ConnectorAuthResponse } var file_agent_proto_depIdxs = []int32{ 5, // 0: agent.ListAgentsResponse.rows:type_name -> agent.Agent - 11, // 1: agent.Agent.status:type_name -> agent.Status - 7, // 2: agent.BidirectionalStream.command:type_name -> agent.UtmCommand - 8, // 3: agent.BidirectionalStream.result:type_name -> agent.CommandResult - 12, // 4: agent.CommandResult.executed_at:type_name -> google.protobuf.Timestamp - 10, // 5: agent.ListAgentsCommandsResponse.rows:type_name -> agent.AgentCommand - 12, // 6: agent.AgentCommand.created_at:type_name -> google.protobuf.Timestamp - 12, // 7: agent.AgentCommand.updated_at:type_name -> google.protobuf.Timestamp - 0, // 8: agent.AgentCommand.command_status:type_name -> agent.AgentCommandStatus - 3, // 9: agent.AgentService.RegisterAgent:input_type -> agent.AgentRequest - 3, // 10: agent.AgentService.UpdateAgent:input_type -> agent.AgentRequest - 13, // 11: agent.AgentService.DeleteAgent:input_type -> agent.DeleteRequest - 14, // 12: agent.AgentService.ListAgents:input_type -> agent.ListRequest - 15, // 13: agent.AgentService.GetAgentAuth:input_type -> agent.ConnectorAuthRequest - 6, // 14: agent.AgentService.AgentStream:input_type -> agent.BidirectionalStream - 14, // 15: agent.AgentService.ListAgentCommands:input_type -> agent.ListRequest - 7, // 16: agent.PanelService.ProcessCommand:input_type -> agent.UtmCommand - 1, // 17: agent.PanelService.GetConnectionKey:input_type -> agent.ConnectionKeyRequest - 1, // 18: agent.PanelService.RotateConnectionKey:input_type -> agent.ConnectionKeyRequest - 16, // 19: agent.AgentService.RegisterAgent:output_type -> agent.AuthResponse - 16, // 20: agent.AgentService.UpdateAgent:output_type -> agent.AuthResponse - 16, // 21: agent.AgentService.DeleteAgent:output_type -> agent.AuthResponse - 4, // 22: agent.AgentService.ListAgents:output_type -> agent.ListAgentsResponse - 17, // 23: agent.AgentService.GetAgentAuth:output_type -> agent.ConnectorAuthResponse - 6, // 24: agent.AgentService.AgentStream:output_type -> agent.BidirectionalStream - 9, // 25: agent.AgentService.ListAgentCommands:output_type -> agent.ListAgentsCommandsResponse - 8, // 26: agent.PanelService.ProcessCommand:output_type -> agent.CommandResult - 2, // 27: agent.PanelService.GetConnectionKey:output_type -> agent.ConnectionKeyResponse - 2, // 28: agent.PanelService.RotateConnectionKey:output_type -> agent.ConnectionKeyResponse - 19, // [19:29] is the sub-list for method output_type - 9, // [9:19] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 12, // 1: agent.Agent.status:type_name -> agent.Status + 8, // 2: agent.BidirectionalStream.command:type_name -> agent.UtmCommand + 9, // 3: agent.BidirectionalStream.result:type_name -> agent.CommandResult + 7, // 4: agent.BidirectionalStream.heartbeat:type_name -> agent.Heartbeat + 13, // 5: agent.CommandResult.executed_at:type_name -> google.protobuf.Timestamp + 11, // 6: agent.ListAgentsCommandsResponse.rows:type_name -> agent.AgentCommand + 13, // 7: agent.AgentCommand.created_at:type_name -> google.protobuf.Timestamp + 13, // 8: agent.AgentCommand.updated_at:type_name -> google.protobuf.Timestamp + 0, // 9: agent.AgentCommand.command_status:type_name -> agent.AgentCommandStatus + 3, // 10: agent.AgentService.RegisterAgent:input_type -> agent.AgentRequest + 3, // 11: agent.AgentService.UpdateAgent:input_type -> agent.AgentRequest + 14, // 12: agent.AgentService.DeleteAgent:input_type -> agent.DeleteRequest + 15, // 13: agent.AgentService.ListAgents:input_type -> agent.ListRequest + 16, // 14: agent.AgentService.GetAgentAuth:input_type -> agent.ConnectorAuthRequest + 6, // 15: agent.AgentService.AgentStream:input_type -> agent.BidirectionalStream + 15, // 16: agent.AgentService.ListAgentCommands:input_type -> agent.ListRequest + 8, // 17: agent.PanelService.ProcessCommand:input_type -> agent.UtmCommand + 1, // 18: agent.PanelService.GetConnectionKey:input_type -> agent.ConnectionKeyRequest + 1, // 19: agent.PanelService.RotateConnectionKey:input_type -> agent.ConnectionKeyRequest + 17, // 20: agent.AgentService.RegisterAgent:output_type -> agent.AuthResponse + 17, // 21: agent.AgentService.UpdateAgent:output_type -> agent.AuthResponse + 17, // 22: agent.AgentService.DeleteAgent:output_type -> agent.AuthResponse + 4, // 23: agent.AgentService.ListAgents:output_type -> agent.ListAgentsResponse + 18, // 24: agent.AgentService.GetAgentAuth:output_type -> agent.ConnectorAuthResponse + 6, // 25: agent.AgentService.AgentStream:output_type -> agent.BidirectionalStream + 10, // 26: agent.AgentService.ListAgentCommands:output_type -> agent.ListAgentsCommandsResponse + 9, // 27: agent.PanelService.ProcessCommand:output_type -> agent.CommandResult + 2, // 28: agent.PanelService.GetConnectionKey:output_type -> agent.ConnectionKeyResponse + 2, // 29: agent.PanelService.RotateConnectionKey:output_type -> agent.ConnectionKeyResponse + 20, // [20:30] is the sub-list for method output_type + 10, // [10:20] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_agent_proto_init() } @@ -1127,6 +1183,7 @@ func file_agent_proto_init() { file_agent_proto_msgTypes[5].OneofWrappers = []any{ (*BidirectionalStream_Command)(nil), (*BidirectionalStream_Result)(nil), + (*BidirectionalStream_Heartbeat)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1134,7 +1191,7 @@ func file_agent_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_agent_proto_rawDesc), len(file_agent_proto_rawDesc)), NumEnums: 1, - NumMessages: 10, + NumMessages: 11, NumExtensions: 0, NumServices: 2, }, diff --git a/installer/templates/front-end.go b/installer/templates/front-end.go index febd7d689..e902fcdbe 100644 --- a/installer/templates/front-end.go +++ b/installer/templates/front-end.go @@ -65,51 +65,43 @@ server { } - location /v1/ingest { - proxy_pass $utmstack_log_input; - proxy_request_buffering off; - } - - # The agent's persistent gRPC streams to agent-manager. nginx's - # grpc_*_timeout of 0 means "no inactivity timeout" (removing the - # directive would silently fall back to a 60s default), so an idle - # AgentStream / PingService / CollectorService is never torn down by the - # proxy. Liveness is carried by the gRPC keepalive (30s ping / 10s - # timeout on both ends) plus grpc_socket_keepalive, which still reaps a - # genuinely dead peer. location /agent.AgentService/ { grpc_pass grpcs://$utmstack_agent_manager_grpc; - grpc_read_timeout 0; - grpc_send_timeout 0; - client_body_timeout 1h; + grpc_read_timeout 7d; + grpc_send_timeout 7d; + client_body_timeout 7d; grpc_socket_keepalive on; } location /agent.PanelService/ { grpc_pass grpcs://$utmstack_agent_manager_grpc; - grpc_read_timeout 0; - grpc_send_timeout 0; + grpc_read_timeout 7d; + grpc_send_timeout 7d; + client_body_timeout 7d; grpc_socket_keepalive on; } location /agent.CollectorService/ { grpc_pass grpcs://$utmstack_agent_manager_grpc; - grpc_read_timeout 0; - grpc_send_timeout 0; + grpc_read_timeout 7d; + grpc_send_timeout 7d; + client_body_timeout 7d; grpc_socket_keepalive on; } - # log-input's ingest, whose service lives in the SDK's "plugins" package. location /plugins.Integration/ { grpc_pass grpcs://$utmstack_log_input_grpc; - grpc_read_timeout 900; - grpc_send_timeout 900; + grpc_read_timeout 7d; + grpc_send_timeout 7d; + client_body_timeout 7d; + grpc_socket_keepalive on; } location /agent.PingService/ { grpc_pass grpcs://$utmstack_agent_manager_grpc; - grpc_read_timeout 0; - grpc_send_timeout 0; + grpc_read_timeout 7d; + grpc_send_timeout 7d; + client_body_timeout 7d; grpc_socket_keepalive on; } diff --git a/installer/templates/proxy.go b/installer/templates/proxy.go index 8c16d8352..f5612f84f 100644 --- a/installer/templates/proxy.go +++ b/installer/templates/proxy.go @@ -27,17 +27,19 @@ server { location /agent. { grpc_pass grpc://127.0.0.1:10001; grpc_set_header x-shared-key $shared_key; - grpc_read_timeout 900; - grpc_send_timeout 900; + grpc_read_timeout 7d; + grpc_send_timeout 7d; + client_body_timeout 7d; + grpc_socket_keepalive on; } - # log-input's ingest. Separate only because its proto package differs; the - # router behind decides which of the two it is. location /plugins. { grpc_pass grpc://127.0.0.1:10001; grpc_set_header x-shared-key $shared_key; - grpc_read_timeout 900; - grpc_send_timeout 900; + grpc_read_timeout 7d; + grpc_send_timeout 7d; + client_body_timeout 7d; + grpc_socket_keepalive on; } location / { @@ -105,17 +107,19 @@ server { location /agent. { grpc_pass grpc://127.0.0.1:10001; grpc_set_header x-shared-key $shared_key; - grpc_read_timeout 900; - grpc_send_timeout 900; + grpc_read_timeout 7d; + grpc_send_timeout 7d; + client_body_timeout 7d; + grpc_socket_keepalive on; } - # log-input's ingest. Separate only because its proto package differs; the - # router behind decides which of the two it is. location /plugins. { grpc_pass grpc://127.0.0.1:10001; grpc_set_header x-shared-key $shared_key; - grpc_read_timeout 900; - grpc_send_timeout 900; + grpc_read_timeout 7d; + grpc_send_timeout 7d; + client_body_timeout 7d; + grpc_socket_keepalive on; } location / {