diff --git a/.examples.env b/.examples.env index 5c02770..6859dea 100644 --- a/.examples.env +++ b/.examples.env @@ -1,3 +1,4 @@ PORT=6756 LOG_LEVEL=DEBUG -MODE=DEV \ No newline at end of file +MODE=DEV +HEARTBEAT=5 \ No newline at end of file diff --git a/agent/internal/rpc/client.go b/agent/internal/rpc/client.go index 23f9ea3..56fc9cf 100644 --- a/agent/internal/rpc/client.go +++ b/agent/internal/rpc/client.go @@ -2,9 +2,11 @@ package rpc import ( "context" + "fmt" pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops" "github.com/lorsanstand/HomeOps-Hub/shared/domain" + "github.com/lorsanstand/HomeOps-Hub/shared/mappers/rpc" "google.golang.org/grpc" ) @@ -27,6 +29,13 @@ func (c *Connection) Hub() pb.HubClient { } func (c *Connection) RegisterAgent(ctx context.Context, RegisterData domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error) { - ResponseData, err := c.Hub().RegisterAgent(ctx, new(domain.ToGRPCAgentRequest(RegisterData))) - return domain.ToDomainAgentResponse(ResponseData), err + ResponseData, err := c.Hub().RegisterAgent(ctx, rpc.ToGRPCAgentRequest(RegisterData)) + if err != nil { + return domain.RegisterAgentResponse{}, fmt.Errorf("send register agent: %w", err) + } + response, err := rpc.ToDomainAgentResponse(ResponseData) + if err != nil { + return domain.RegisterAgentResponse{}, fmt.Errorf("casting response: %w", err) + } + return response, nil } diff --git a/api/gen/homeops/hub.pb.go b/api/gen/homeops/hub.pb.go index 03f9fcc..7cf34b8 100644 --- a/api/gen/homeops/hub.pb.go +++ b/api/gen/homeops/hub.pb.go @@ -11,7 +11,6 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" - sync "sync" unsafe "unsafe" ) @@ -22,855 +21,36 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type PongResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Pong string `protobuf:"bytes,1,opt,name=pong,proto3" json:"pong,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *PongResponse) Reset() { - *x = PongResponse{} - mi := &file_homeops_hub_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *PongResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PongResponse) ProtoMessage() {} - -func (x *PongResponse) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_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 PongResponse.ProtoReflect.Descriptor instead. -func (*PongResponse) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{0} -} - -func (x *PongResponse) GetPong() string { - if x != nil { - return x.Pong - } - return "" -} - -type RegisterAgentRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - AgentId string `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` - AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` - Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` - Host *HostInfo `protobuf:"bytes,4,opt,name=host,proto3" json:"host,omitempty"` - Capability []*Capability `protobuf:"bytes,5,rep,name=capability,proto3" json:"capability,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *RegisterAgentRequest) Reset() { - *x = RegisterAgentRequest{} - mi := &file_homeops_hub_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *RegisterAgentRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RegisterAgentRequest) ProtoMessage() {} - -func (x *RegisterAgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_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 RegisterAgentRequest.ProtoReflect.Descriptor instead. -func (*RegisterAgentRequest) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{1} -} - -func (x *RegisterAgentRequest) GetAgentId() string { - if x != nil { - return x.AgentId - } - return "" -} - -func (x *RegisterAgentRequest) GetAgentName() string { - if x != nil { - return x.AgentName - } - return "" -} - -func (x *RegisterAgentRequest) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *RegisterAgentRequest) GetHost() *HostInfo { - if x != nil { - return x.Host - } - return nil -} - -func (x *RegisterAgentRequest) GetCapability() []*Capability { - if x != nil { - return x.Capability - } - return nil -} - -type HostInfo struct { - state protoimpl.MessageState `protogen:"open.v1"` - System string `protobuf:"bytes,1,opt,name=system,proto3" json:"system,omitempty"` - Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` - Arch string `protobuf:"bytes,3,opt,name=arch,proto3" json:"arch,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *HostInfo) Reset() { - *x = HostInfo{} - mi := &file_homeops_hub_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *HostInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HostInfo) ProtoMessage() {} - -func (x *HostInfo) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_proto_msgTypes[2] - 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 HostInfo.ProtoReflect.Descriptor instead. -func (*HostInfo) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{2} -} - -func (x *HostInfo) GetSystem() string { - if x != nil { - return x.System - } - return "" -} - -func (x *HostInfo) GetHostname() string { - if x != nil { - return x.Hostname - } - return "" -} - -func (x *HostInfo) GetArch() string { - if x != nil { - return x.Arch - } - return "" -} - -type Capability struct { - state protoimpl.MessageState `protogen:"open.v1"` - Available bool `protobuf:"varint,1,opt,name=available,proto3" json:"available,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - Reason string `protobuf:"bytes,4,opt,name=reason,proto3" json:"reason,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Capability) Reset() { - *x = Capability{} - mi := &file_homeops_hub_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Capability) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Capability) ProtoMessage() {} - -func (x *Capability) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_proto_msgTypes[3] - 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 Capability.ProtoReflect.Descriptor instead. -func (*Capability) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{3} -} - -func (x *Capability) GetAvailable() bool { - if x != nil { - return x.Available - } - return false -} - -func (x *Capability) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *Capability) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Capability) GetReason() string { - if x != nil { - return x.Reason - } - return "" -} - -type RegisterAgentResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - HeartbeatIntervalSecond int64 `protobuf:"varint,1,opt,name=heartbeat_interval_second,json=heartbeatIntervalSecond,proto3" json:"heartbeat_interval_second,omitempty"` - AgentId string `protobuf:"bytes,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *RegisterAgentResponse) Reset() { - *x = RegisterAgentResponse{} - mi := &file_homeops_hub_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *RegisterAgentResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RegisterAgentResponse) ProtoMessage() {} - -func (x *RegisterAgentResponse) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_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 RegisterAgentResponse.ProtoReflect.Descriptor instead. -func (*RegisterAgentResponse) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{4} -} - -func (x *RegisterAgentResponse) GetHeartbeatIntervalSecond() int64 { - if x != nil { - return x.HeartbeatIntervalSecond - } - return 0 -} - -func (x *RegisterAgentResponse) GetAgentId() string { - if x != nil { - return x.AgentId - } - return "" -} - -type ServerCommandRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Args map[string]string `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - TimeoutSeconds int64 `protobuf:"varint,4,opt,name=timeout_seconds,json=timeoutSeconds,proto3" json:"timeout_seconds,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ServerCommandRequest) Reset() { - *x = ServerCommandRequest{} - mi := &file_homeops_hub_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ServerCommandRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServerCommandRequest) ProtoMessage() {} - -func (x *ServerCommandRequest) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_proto_msgTypes[5] - 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 ServerCommandRequest.ProtoReflect.Descriptor instead. -func (*ServerCommandRequest) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{5} -} - -func (x *ServerCommandRequest) GetRequestId() string { - if x != nil { - return x.RequestId - } - return "" -} - -func (x *ServerCommandRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *ServerCommandRequest) GetArgs() map[string]string { - if x != nil { - return x.Args - } - return nil -} - -func (x *ServerCommandRequest) GetTimeoutSeconds() int64 { - if x != nil { - return x.TimeoutSeconds - } - return 0 -} - -type AgentEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - AgentId string `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` - // Types that are valid to be assigned to Event: - // - // *AgentEvent_Heartbeat - // *AgentEvent_CommandResponse - // *AgentEvent_Alert - Event isAgentEvent_Event `protobuf_oneof:"event"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AgentEvent) Reset() { - *x = AgentEvent{} - mi := &file_homeops_hub_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AgentEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AgentEvent) ProtoMessage() {} - -func (x *AgentEvent) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_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 AgentEvent.ProtoReflect.Descriptor instead. -func (*AgentEvent) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{6} -} - -func (x *AgentEvent) GetAgentId() string { - if x != nil { - return x.AgentId - } - return "" -} - -func (x *AgentEvent) GetEvent() isAgentEvent_Event { - if x != nil { - return x.Event - } - return nil -} - -func (x *AgentEvent) GetHeartbeat() *Heartbeat { - if x != nil { - if x, ok := x.Event.(*AgentEvent_Heartbeat); ok { - return x.Heartbeat - } - } - return nil -} - -func (x *AgentEvent) GetCommandResponse() *CommandResponse { - if x != nil { - if x, ok := x.Event.(*AgentEvent_CommandResponse); ok { - return x.CommandResponse - } - } - return nil -} - -func (x *AgentEvent) GetAlert() *Alert { - if x != nil { - if x, ok := x.Event.(*AgentEvent_Alert); ok { - return x.Alert - } - } - return nil -} - -type isAgentEvent_Event interface { - isAgentEvent_Event() -} - -type AgentEvent_Heartbeat struct { - Heartbeat *Heartbeat `protobuf:"bytes,2,opt,name=heartbeat,proto3,oneof"` -} - -type AgentEvent_CommandResponse struct { - CommandResponse *CommandResponse `protobuf:"bytes,3,opt,name=command_response,json=commandResponse,proto3,oneof"` -} - -type AgentEvent_Alert struct { - Alert *Alert `protobuf:"bytes,4,opt,name=alert,proto3,oneof"` -} - -func (*AgentEvent_Heartbeat) isAgentEvent_Event() {} - -func (*AgentEvent_CommandResponse) isAgentEvent_Event() {} - -func (*AgentEvent_Alert) isAgentEvent_Event() {} - -type Heartbeat struct { - state protoimpl.MessageState `protogen:"open.v1"` - Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Metrics *SystemMetrics `protobuf:"bytes,2,opt,name=metrics,proto3" json:"metrics,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Heartbeat) Reset() { - *x = Heartbeat{} - mi := &file_homeops_hub_proto_msgTypes[7] - 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_homeops_hub_proto_msgTypes[7] - 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_homeops_hub_proto_rawDescGZIP(), []int{7} -} - -func (x *Heartbeat) GetTimestamp() int64 { - if x != nil { - return x.Timestamp - } - return 0 -} - -func (x *Heartbeat) GetMetrics() *SystemMetrics { - if x != nil { - return x.Metrics - } - return nil -} - -type SystemMetrics struct { - state protoimpl.MessageState `protogen:"open.v1"` - CpuUsage float32 `protobuf:"fixed32,1,opt,name=cpu_usage,json=cpuUsage,proto3" json:"cpu_usage,omitempty"` - MemoryUsage float32 `protobuf:"fixed32,2,opt,name=memory_usage,json=memoryUsage,proto3" json:"memory_usage,omitempty"` - DiskUsage float32 `protobuf:"fixed32,3,opt,name=disk_usage,json=diskUsage,proto3" json:"disk_usage,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SystemMetrics) Reset() { - *x = SystemMetrics{} - mi := &file_homeops_hub_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SystemMetrics) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SystemMetrics) ProtoMessage() {} - -func (x *SystemMetrics) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_proto_msgTypes[8] - 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 SystemMetrics.ProtoReflect.Descriptor instead. -func (*SystemMetrics) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{8} -} - -func (x *SystemMetrics) GetCpuUsage() float32 { - if x != nil { - return x.CpuUsage - } - return 0 -} - -func (x *SystemMetrics) GetMemoryUsage() float32 { - if x != nil { - return x.MemoryUsage - } - return 0 -} - -func (x *SystemMetrics) GetDiskUsage() float32 { - if x != nil { - return x.DiskUsage - } - return 0 -} - -type CommandResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` - Success bool `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"` - Output string `protobuf:"bytes,3,opt,name=output,proto3" json:"output,omitempty"` - Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` - ExecTimeMs int64 `protobuf:"varint,5,opt,name=exec_time_ms,json=execTimeMs,proto3" json:"exec_time_ms,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *CommandResponse) Reset() { - *x = CommandResponse{} - mi := &file_homeops_hub_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *CommandResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CommandResponse) ProtoMessage() {} - -func (x *CommandResponse) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_proto_msgTypes[9] - 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 CommandResponse.ProtoReflect.Descriptor instead. -func (*CommandResponse) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{9} -} - -func (x *CommandResponse) GetRequestId() string { - if x != nil { - return x.RequestId - } - return "" -} - -func (x *CommandResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *CommandResponse) GetOutput() string { - if x != nil { - return x.Output - } - return "" -} - -func (x *CommandResponse) GetError() string { - if x != nil { - return x.Error - } - return "" -} - -func (x *CommandResponse) GetExecTimeMs() int64 { - if x != nil { - return x.ExecTimeMs - } - return 0 -} - -type Alert struct { - state protoimpl.MessageState `protogen:"open.v1"` - Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Level string `protobuf:"bytes,2,opt,name=level,proto3" json:"level,omitempty"` - Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"` - Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Alert) Reset() { - *x = Alert{} - mi := &file_homeops_hub_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Alert) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Alert) ProtoMessage() {} - -func (x *Alert) ProtoReflect() protoreflect.Message { - mi := &file_homeops_hub_proto_msgTypes[10] - 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 Alert.ProtoReflect.Descriptor instead. -func (*Alert) Descriptor() ([]byte, []int) { - return file_homeops_hub_proto_rawDescGZIP(), []int{10} -} - -func (x *Alert) GetTimestamp() int64 { - if x != nil { - return x.Timestamp - } - return 0 -} - -func (x *Alert) GetLevel() string { - if x != nil { - return x.Level - } - return "" -} - -func (x *Alert) GetTitle() string { - if x != nil { - return x.Title - } - return "" -} - -func (x *Alert) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - var File_homeops_hub_proto protoreflect.FileDescriptor const file_homeops_hub_proto_rawDesc = "" + "\n" + - "\x11homeops/hub.proto\x1a\x1bgoogle/protobuf/empty.proto\"\"\n" + - "\fPongResponse\x12\x12\n" + - "\x04pong\x18\x01 \x01(\tR\x04pong\"\xb6\x01\n" + - "\x14RegisterAgentRequest\x12\x19\n" + - "\bagent_id\x18\x01 \x01(\tR\aagentId\x12\x1d\n" + - "\n" + - "agent_name\x18\x02 \x01(\tR\tagentName\x12\x18\n" + - "\aversion\x18\x03 \x01(\tR\aversion\x12\x1d\n" + - "\x04host\x18\x04 \x01(\v2\t.HostInfoR\x04host\x12+\n" + - "\n" + - "capability\x18\x05 \x03(\v2\v.CapabilityR\n" + - "capability\"R\n" + - "\bHostInfo\x12\x16\n" + - "\x06system\x18\x01 \x01(\tR\x06system\x12\x1a\n" + - "\bhostname\x18\x02 \x01(\tR\bhostname\x12\x12\n" + - "\x04arch\x18\x03 \x01(\tR\x04arch\"p\n" + - "\n" + - "Capability\x12\x1c\n" + - "\tavailable\x18\x01 \x01(\bR\tavailable\x12\x18\n" + - "\aversion\x18\x02 \x01(\tR\aversion\x12\x12\n" + - "\x04name\x18\x03 \x01(\tR\x04name\x12\x16\n" + - "\x06reason\x18\x04 \x01(\tR\x06reason\"n\n" + - "\x15RegisterAgentResponse\x12:\n" + - "\x19heartbeat_interval_second\x18\x01 \x01(\x03R\x17heartbeatIntervalSecond\x12\x19\n" + - "\bagent_id\x18\x02 \x01(\tR\aagentId\"\xe0\x01\n" + - "\x14ServerCommandRequest\x12\x1d\n" + - "\n" + - "request_id\x18\x01 \x01(\tR\trequestId\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\x123\n" + - "\x04args\x18\x03 \x03(\v2\x1f.ServerCommandRequest.ArgsEntryR\x04args\x12'\n" + - "\x0ftimeout_seconds\x18\x04 \x01(\x03R\x0etimeoutSeconds\x1a7\n" + - "\tArgsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xbb\x01\n" + - "\n" + - "AgentEvent\x12\x19\n" + - "\bagent_id\x18\x01 \x01(\tR\aagentId\x12*\n" + - "\theartbeat\x18\x02 \x01(\v2\n" + - ".HeartbeatH\x00R\theartbeat\x12=\n" + - "\x10command_response\x18\x03 \x01(\v2\x10.CommandResponseH\x00R\x0fcommandResponse\x12\x1e\n" + - "\x05alert\x18\x04 \x01(\v2\x06.AlertH\x00R\x05alertB\a\n" + - "\x05event\"S\n" + - "\tHeartbeat\x12\x1c\n" + - "\ttimestamp\x18\x01 \x01(\x03R\ttimestamp\x12(\n" + - "\ametrics\x18\x02 \x01(\v2\x0e.SystemMetricsR\ametrics\"n\n" + - "\rSystemMetrics\x12\x1b\n" + - "\tcpu_usage\x18\x01 \x01(\x02R\bcpuUsage\x12!\n" + - "\fmemory_usage\x18\x02 \x01(\x02R\vmemoryUsage\x12\x1d\n" + - "\n" + - "disk_usage\x18\x03 \x01(\x02R\tdiskUsage\"\x9a\x01\n" + - "\x0fCommandResponse\x12\x1d\n" + - "\n" + - "request_id\x18\x01 \x01(\tR\trequestId\x12\x18\n" + - "\asuccess\x18\x02 \x01(\bR\asuccess\x12\x16\n" + - "\x06output\x18\x03 \x01(\tR\x06output\x12\x14\n" + - "\x05error\x18\x04 \x01(\tR\x05error\x12 \n" + - "\fexec_time_ms\x18\x05 \x01(\x03R\n" + - "execTimeMs\"s\n" + - "\x05Alert\x12\x1c\n" + - "\ttimestamp\x18\x01 \x01(\x03R\ttimestamp\x12\x14\n" + - "\x05level\x18\x02 \x01(\tR\x05level\x12\x14\n" + - "\x05title\x18\x03 \x01(\tR\x05title\x12 \n" + - "\vdescription\x18\x04 \x01(\tR\vdescription2\xb6\x01\n" + + "\x11homeops/hub.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x16homeops/register.proto\x1a\x14homeops/stream.proto2\xb6\x01\n" + "\x03Hub\x12/\n" + "\x04Ping\x12\x16.google.protobuf.Empty\x1a\r.PongResponse\"\x00\x12@\n" + "\rRegisterAgent\x12\x15.RegisterAgentRequest\x1a\x16.RegisterAgentResponse\"\x00\x12<\n" + "\x10StreamConnection\x12\v.AgentEvent\x1a\x15.ServerCommandRequest\"\x00(\x010\x01B HostInfo - 3, // 1: RegisterAgentRequest.capability:type_name -> Capability - 11, // 2: ServerCommandRequest.args:type_name -> ServerCommandRequest.ArgsEntry - 7, // 3: AgentEvent.heartbeat:type_name -> Heartbeat - 9, // 4: AgentEvent.command_response:type_name -> CommandResponse - 10, // 5: AgentEvent.alert:type_name -> Alert - 8, // 6: Heartbeat.metrics:type_name -> SystemMetrics - 12, // 7: Hub.Ping:input_type -> google.protobuf.Empty - 1, // 8: Hub.RegisterAgent:input_type -> RegisterAgentRequest - 6, // 9: Hub.StreamConnection:input_type -> AgentEvent - 0, // 10: Hub.Ping:output_type -> PongResponse - 4, // 11: Hub.RegisterAgent:output_type -> RegisterAgentResponse - 5, // 12: Hub.StreamConnection:output_type -> ServerCommandRequest - 10, // [10:13] is the sub-list for method output_type - 7, // [7:10] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 0, // 0: Hub.Ping:input_type -> google.protobuf.Empty + 1, // 1: Hub.RegisterAgent:input_type -> RegisterAgentRequest + 2, // 2: Hub.StreamConnection:input_type -> AgentEvent + 3, // 3: Hub.Ping:output_type -> PongResponse + 4, // 4: Hub.RegisterAgent:output_type -> RegisterAgentResponse + 5, // 5: Hub.StreamConnection:output_type -> ServerCommandRequest + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_homeops_hub_proto_init() } @@ -878,24 +58,20 @@ func file_homeops_hub_proto_init() { if File_homeops_hub_proto != nil { return } - file_homeops_hub_proto_msgTypes[6].OneofWrappers = []any{ - (*AgentEvent_Heartbeat)(nil), - (*AgentEvent_CommandResponse)(nil), - (*AgentEvent_Alert)(nil), - } + file_homeops_register_proto_init() + file_homeops_stream_proto_init() type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_homeops_hub_proto_rawDesc), len(file_homeops_hub_proto_rawDesc)), NumEnums: 0, - NumMessages: 12, + NumMessages: 0, NumExtensions: 0, NumServices: 1, }, GoTypes: file_homeops_hub_proto_goTypes, DependencyIndexes: file_homeops_hub_proto_depIdxs, - MessageInfos: file_homeops_hub_proto_msgTypes, }.Build() File_homeops_hub_proto = out.File file_homeops_hub_proto_goTypes = nil diff --git a/api/gen/homeops/register.pb.go b/api/gen/homeops/register.pb.go new file mode 100644 index 0000000..06e674e --- /dev/null +++ b/api/gen/homeops/register.pb.go @@ -0,0 +1,680 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v7.34.1 +// source: homeops/register.proto + +package homeops + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PongResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Pong string `protobuf:"bytes,1,opt,name=pong,proto3" json:"pong,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PongResponse) Reset() { + *x = PongResponse{} + mi := &file_homeops_register_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PongResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PongResponse) ProtoMessage() {} + +func (x *PongResponse) ProtoReflect() protoreflect.Message { + mi := &file_homeops_register_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 PongResponse.ProtoReflect.Descriptor instead. +func (*PongResponse) Descriptor() ([]byte, []int) { + return file_homeops_register_proto_rawDescGZIP(), []int{0} +} + +func (x *PongResponse) GetPong() string { + if x != nil { + return x.Pong + } + return "" +} + +type RegisterAgentRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + AgentId string `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` + AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Host *HostInfo `protobuf:"bytes,4,opt,name=host,proto3" json:"host,omitempty"` + Capability []*Capability `protobuf:"bytes,5,rep,name=capability,proto3" json:"capability,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterAgentRequest) Reset() { + *x = RegisterAgentRequest{} + mi := &file_homeops_register_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterAgentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterAgentRequest) ProtoMessage() {} + +func (x *RegisterAgentRequest) ProtoReflect() protoreflect.Message { + mi := &file_homeops_register_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 RegisterAgentRequest.ProtoReflect.Descriptor instead. +func (*RegisterAgentRequest) Descriptor() ([]byte, []int) { + return file_homeops_register_proto_rawDescGZIP(), []int{1} +} + +func (x *RegisterAgentRequest) GetAgentId() string { + if x != nil { + return x.AgentId + } + return "" +} + +func (x *RegisterAgentRequest) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +func (x *RegisterAgentRequest) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *RegisterAgentRequest) GetHost() *HostInfo { + if x != nil { + return x.Host + } + return nil +} + +func (x *RegisterAgentRequest) GetCapability() []*Capability { + if x != nil { + return x.Capability + } + return nil +} + +type HostInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + System string `protobuf:"bytes,1,opt,name=system,proto3" json:"system,omitempty"` + Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` + Arch string `protobuf:"bytes,3,opt,name=arch,proto3" json:"arch,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *HostInfo) Reset() { + *x = HostInfo{} + mi := &file_homeops_register_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HostInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HostInfo) ProtoMessage() {} + +func (x *HostInfo) ProtoReflect() protoreflect.Message { + mi := &file_homeops_register_proto_msgTypes[2] + 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 HostInfo.ProtoReflect.Descriptor instead. +func (*HostInfo) Descriptor() ([]byte, []int) { + return file_homeops_register_proto_rawDescGZIP(), []int{2} +} + +func (x *HostInfo) GetSystem() string { + if x != nil { + return x.System + } + return "" +} + +func (x *HostInfo) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *HostInfo) GetArch() string { + if x != nil { + return x.Arch + } + return "" +} + +type Capability struct { + state protoimpl.MessageState `protogen:"open.v1"` + Available bool `protobuf:"varint,1,opt,name=available,proto3" json:"available,omitempty"` // доступен ли + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` // версия раздела + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` // название раздела по типу докер или управление пк + Reason string `protobuf:"bytes,4,opt,name=reason,proto3" json:"reason,omitempty"` // причина если раздел не доступент + Command []*CapabilityCommand `protobuf:"bytes,5,rep,name=command,proto3" json:"command,omitempty"` // команды раздела + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Capability) Reset() { + *x = Capability{} + mi := &file_homeops_register_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Capability) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Capability) ProtoMessage() {} + +func (x *Capability) ProtoReflect() protoreflect.Message { + mi := &file_homeops_register_proto_msgTypes[3] + 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 Capability.ProtoReflect.Descriptor instead. +func (*Capability) Descriptor() ([]byte, []int) { + return file_homeops_register_proto_rawDescGZIP(), []int{3} +} + +func (x *Capability) GetAvailable() bool { + if x != nil { + return x.Available + } + return false +} + +func (x *Capability) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *Capability) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Capability) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *Capability) GetCommand() []*CapabilityCommand { + if x != nil { + return x.Command + } + return nil +} + +type CapabilityCommand struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // название команды + OptArgs []*CommandsArgs `protobuf:"bytes,2,rep,name=opt_args,json=optArgs,proto3" json:"opt_args,omitempty"` // опциоанльные переменные + ReqArgs []*CommandsArgs `protobuf:"bytes,3,rep,name=req_args,json=reqArgs,proto3" json:"req_args,omitempty"` // обязательные переменные + Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` // версия команды + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` // описание команды для документации + TypeOutput string `protobuf:"bytes,7,opt,name=type_output,json=typeOutput,proto3" json:"type_output,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CapabilityCommand) Reset() { + *x = CapabilityCommand{} + mi := &file_homeops_register_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CapabilityCommand) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CapabilityCommand) ProtoMessage() {} + +func (x *CapabilityCommand) ProtoReflect() protoreflect.Message { + mi := &file_homeops_register_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 CapabilityCommand.ProtoReflect.Descriptor instead. +func (*CapabilityCommand) Descriptor() ([]byte, []int) { + return file_homeops_register_proto_rawDescGZIP(), []int{4} +} + +func (x *CapabilityCommand) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CapabilityCommand) GetOptArgs() []*CommandsArgs { + if x != nil { + return x.OptArgs + } + return nil +} + +func (x *CapabilityCommand) GetReqArgs() []*CommandsArgs { + if x != nil { + return x.ReqArgs + } + return nil +} + +func (x *CapabilityCommand) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *CapabilityCommand) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *CapabilityCommand) GetTypeOutput() string { + if x != nil { + return x.TypeOutput + } + return "" +} + +type CommandsArgs struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // название аргумента + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` // какой тип path int string bool + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // описание для документации + Default string `protobuf:"bytes,4,opt,name=default,proto3" json:"default,omitempty"` // значение по умолчанию + Enum []string `protobuf:"bytes,5,rep,name=enum,proto3" json:"enum,omitempty"` // enum комманд по типу run stop restart + Validation *ArgValidation `protobuf:"bytes,6,opt,name=validation,proto3" json:"validation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CommandsArgs) Reset() { + *x = CommandsArgs{} + mi := &file_homeops_register_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CommandsArgs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommandsArgs) ProtoMessage() {} + +func (x *CommandsArgs) ProtoReflect() protoreflect.Message { + mi := &file_homeops_register_proto_msgTypes[5] + 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 CommandsArgs.ProtoReflect.Descriptor instead. +func (*CommandsArgs) Descriptor() ([]byte, []int) { + return file_homeops_register_proto_rawDescGZIP(), []int{5} +} + +func (x *CommandsArgs) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CommandsArgs) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *CommandsArgs) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *CommandsArgs) GetDefault() string { + if x != nil { + return x.Default + } + return "" +} + +func (x *CommandsArgs) GetEnum() []string { + if x != nil { + return x.Enum + } + return nil +} + +func (x *CommandsArgs) GetValidation() *ArgValidation { + if x != nil { + return x.Validation + } + return nil +} + +type ArgValidation struct { + state protoimpl.MessageState `protogen:"open.v1"` + MinValue int64 `protobuf:"varint,1,opt,name=min_value,json=minValue,proto3" json:"min_value,omitempty"` // для чисел + MaxValue int64 `protobuf:"varint,2,opt,name=max_value,json=maxValue,proto3" json:"max_value,omitempty"` // для чисел + Pattern string `protobuf:"bytes,3,opt,name=pattern,proto3" json:"pattern,omitempty"` // для regex строк + AllowedExts []string `protobuf:"bytes,4,rep,name=allowed_exts,json=allowedExts,proto3" json:"allowed_exts,omitempty"` // для путей и файлов по типу .zip .rar итд + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ArgValidation) Reset() { + *x = ArgValidation{} + mi := &file_homeops_register_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ArgValidation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArgValidation) ProtoMessage() {} + +func (x *ArgValidation) ProtoReflect() protoreflect.Message { + mi := &file_homeops_register_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 ArgValidation.ProtoReflect.Descriptor instead. +func (*ArgValidation) Descriptor() ([]byte, []int) { + return file_homeops_register_proto_rawDescGZIP(), []int{6} +} + +func (x *ArgValidation) GetMinValue() int64 { + if x != nil { + return x.MinValue + } + return 0 +} + +func (x *ArgValidation) GetMaxValue() int64 { + if x != nil { + return x.MaxValue + } + return 0 +} + +func (x *ArgValidation) GetPattern() string { + if x != nil { + return x.Pattern + } + return "" +} + +func (x *ArgValidation) GetAllowedExts() []string { + if x != nil { + return x.AllowedExts + } + return nil +} + +type RegisterAgentResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + HeartbeatIntervalSecond int64 `protobuf:"varint,1,opt,name=heartbeat_interval_second,json=heartbeatIntervalSecond,proto3" json:"heartbeat_interval_second,omitempty"` + AgentId string `protobuf:"bytes,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterAgentResponse) Reset() { + *x = RegisterAgentResponse{} + mi := &file_homeops_register_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterAgentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterAgentResponse) ProtoMessage() {} + +func (x *RegisterAgentResponse) ProtoReflect() protoreflect.Message { + mi := &file_homeops_register_proto_msgTypes[7] + 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 RegisterAgentResponse.ProtoReflect.Descriptor instead. +func (*RegisterAgentResponse) Descriptor() ([]byte, []int) { + return file_homeops_register_proto_rawDescGZIP(), []int{7} +} + +func (x *RegisterAgentResponse) GetHeartbeatIntervalSecond() int64 { + if x != nil { + return x.HeartbeatIntervalSecond + } + return 0 +} + +func (x *RegisterAgentResponse) GetAgentId() string { + if x != nil { + return x.AgentId + } + return "" +} + +var File_homeops_register_proto protoreflect.FileDescriptor + +const file_homeops_register_proto_rawDesc = "" + + "\n" + + "\x16homeops/register.proto\"\"\n" + + "\fPongResponse\x12\x12\n" + + "\x04pong\x18\x01 \x01(\tR\x04pong\"\xb6\x01\n" + + "\x14RegisterAgentRequest\x12\x19\n" + + "\bagent_id\x18\x01 \x01(\tR\aagentId\x12\x1d\n" + + "\n" + + "agent_name\x18\x02 \x01(\tR\tagentName\x12\x18\n" + + "\aversion\x18\x03 \x01(\tR\aversion\x12\x1d\n" + + "\x04host\x18\x04 \x01(\v2\t.HostInfoR\x04host\x12+\n" + + "\n" + + "capability\x18\x05 \x03(\v2\v.CapabilityR\n" + + "capability\"R\n" + + "\bHostInfo\x12\x16\n" + + "\x06system\x18\x01 \x01(\tR\x06system\x12\x1a\n" + + "\bhostname\x18\x02 \x01(\tR\bhostname\x12\x12\n" + + "\x04arch\x18\x03 \x01(\tR\x04arch\"\x9e\x01\n" + + "\n" + + "Capability\x12\x1c\n" + + "\tavailable\x18\x01 \x01(\bR\tavailable\x12\x18\n" + + "\aversion\x18\x02 \x01(\tR\aversion\x12\x12\n" + + "\x04name\x18\x03 \x01(\tR\x04name\x12\x16\n" + + "\x06reason\x18\x04 \x01(\tR\x06reason\x12,\n" + + "\acommand\x18\x05 \x03(\v2\x12.CapabilityCommandR\acommand\"\xd8\x01\n" + + "\x11CapabilityCommand\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12(\n" + + "\bopt_args\x18\x02 \x03(\v2\r.CommandsArgsR\aoptArgs\x12(\n" + + "\breq_args\x18\x03 \x03(\v2\r.CommandsArgsR\areqArgs\x12\x18\n" + + "\aversion\x18\x04 \x01(\tR\aversion\x12 \n" + + "\vdescription\x18\x05 \x01(\tR\vdescription\x12\x1f\n" + + "\vtype_output\x18\a \x01(\tR\n" + + "typeOutput\"\xb6\x01\n" + + "\fCommandsArgs\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x18\n" + + "\adefault\x18\x04 \x01(\tR\adefault\x12\x12\n" + + "\x04enum\x18\x05 \x03(\tR\x04enum\x12.\n" + + "\n" + + "validation\x18\x06 \x01(\v2\x0e.ArgValidationR\n" + + "validation\"\x86\x01\n" + + "\rArgValidation\x12\x1b\n" + + "\tmin_value\x18\x01 \x01(\x03R\bminValue\x12\x1b\n" + + "\tmax_value\x18\x02 \x01(\x03R\bmaxValue\x12\x18\n" + + "\apattern\x18\x03 \x01(\tR\apattern\x12!\n" + + "\fallowed_exts\x18\x04 \x03(\tR\vallowedExts\"n\n" + + "\x15RegisterAgentResponse\x12:\n" + + "\x19heartbeat_interval_second\x18\x01 \x01(\x03R\x17heartbeatIntervalSecond\x12\x19\n" + + "\bagent_id\x18\x02 \x01(\tR\aagentIdB HostInfo + 3, // 1: RegisterAgentRequest.capability:type_name -> Capability + 4, // 2: Capability.command:type_name -> CapabilityCommand + 5, // 3: CapabilityCommand.opt_args:type_name -> CommandsArgs + 5, // 4: CapabilityCommand.req_args:type_name -> CommandsArgs + 6, // 5: CommandsArgs.validation:type_name -> ArgValidation + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_homeops_register_proto_init() } +func file_homeops_register_proto_init() { + if File_homeops_register_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_homeops_register_proto_rawDesc), len(file_homeops_register_proto_rawDesc)), + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_homeops_register_proto_goTypes, + DependencyIndexes: file_homeops_register_proto_depIdxs, + MessageInfos: file_homeops_register_proto_msgTypes, + }.Build() + File_homeops_register_proto = out.File + file_homeops_register_proto_goTypes = nil + file_homeops_register_proto_depIdxs = nil +} diff --git a/api/gen/homeops/stream.pb.go b/api/gen/homeops/stream.pb.go new file mode 100644 index 0000000..144d34d --- /dev/null +++ b/api/gen/homeops/stream.pb.go @@ -0,0 +1,560 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v7.34.1 +// source: homeops/stream.proto + +package homeops + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ServerCommandRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Args map[string]string `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + TimeoutSeconds int64 `protobuf:"varint,4,opt,name=timeout_seconds,json=timeoutSeconds,proto3" json:"timeout_seconds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerCommandRequest) Reset() { + *x = ServerCommandRequest{} + mi := &file_homeops_stream_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerCommandRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerCommandRequest) ProtoMessage() {} + +func (x *ServerCommandRequest) ProtoReflect() protoreflect.Message { + mi := &file_homeops_stream_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 ServerCommandRequest.ProtoReflect.Descriptor instead. +func (*ServerCommandRequest) Descriptor() ([]byte, []int) { + return file_homeops_stream_proto_rawDescGZIP(), []int{0} +} + +func (x *ServerCommandRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *ServerCommandRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ServerCommandRequest) GetArgs() map[string]string { + if x != nil { + return x.Args + } + return nil +} + +func (x *ServerCommandRequest) GetTimeoutSeconds() int64 { + if x != nil { + return x.TimeoutSeconds + } + return 0 +} + +type AgentEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + AgentId string `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` + // Types that are valid to be assigned to Event: + // + // *AgentEvent_Heartbeat + // *AgentEvent_CommandResponse + // *AgentEvent_Alert + Event isAgentEvent_Event `protobuf_oneof:"event"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentEvent) Reset() { + *x = AgentEvent{} + mi := &file_homeops_stream_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentEvent) ProtoMessage() {} + +func (x *AgentEvent) ProtoReflect() protoreflect.Message { + mi := &file_homeops_stream_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 AgentEvent.ProtoReflect.Descriptor instead. +func (*AgentEvent) Descriptor() ([]byte, []int) { + return file_homeops_stream_proto_rawDescGZIP(), []int{1} +} + +func (x *AgentEvent) GetAgentId() string { + if x != nil { + return x.AgentId + } + return "" +} + +func (x *AgentEvent) GetEvent() isAgentEvent_Event { + if x != nil { + return x.Event + } + return nil +} + +func (x *AgentEvent) GetHeartbeat() *Heartbeat { + if x != nil { + if x, ok := x.Event.(*AgentEvent_Heartbeat); ok { + return x.Heartbeat + } + } + return nil +} + +func (x *AgentEvent) GetCommandResponse() *CommandResponse { + if x != nil { + if x, ok := x.Event.(*AgentEvent_CommandResponse); ok { + return x.CommandResponse + } + } + return nil +} + +func (x *AgentEvent) GetAlert() *Alert { + if x != nil { + if x, ok := x.Event.(*AgentEvent_Alert); ok { + return x.Alert + } + } + return nil +} + +type isAgentEvent_Event interface { + isAgentEvent_Event() +} + +type AgentEvent_Heartbeat struct { + Heartbeat *Heartbeat `protobuf:"bytes,2,opt,name=heartbeat,proto3,oneof"` +} + +type AgentEvent_CommandResponse struct { + CommandResponse *CommandResponse `protobuf:"bytes,3,opt,name=command_response,json=commandResponse,proto3,oneof"` +} + +type AgentEvent_Alert struct { + Alert *Alert `protobuf:"bytes,4,opt,name=alert,proto3,oneof"` +} + +func (*AgentEvent_Heartbeat) isAgentEvent_Event() {} + +func (*AgentEvent_CommandResponse) isAgentEvent_Event() {} + +func (*AgentEvent_Alert) isAgentEvent_Event() {} + +type Heartbeat struct { + state protoimpl.MessageState `protogen:"open.v1"` + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Metrics *SystemMetrics `protobuf:"bytes,2,opt,name=metrics,proto3" json:"metrics,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Heartbeat) Reset() { + *x = Heartbeat{} + mi := &file_homeops_stream_proto_msgTypes[2] + 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_homeops_stream_proto_msgTypes[2] + 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_homeops_stream_proto_rawDescGZIP(), []int{2} +} + +func (x *Heartbeat) GetTimestamp() int64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *Heartbeat) GetMetrics() *SystemMetrics { + if x != nil { + return x.Metrics + } + return nil +} + +type SystemMetrics struct { + state protoimpl.MessageState `protogen:"open.v1"` + CpuUsage float32 `protobuf:"fixed32,1,opt,name=cpu_usage,json=cpuUsage,proto3" json:"cpu_usage,omitempty"` + MemoryUsage float32 `protobuf:"fixed32,2,opt,name=memory_usage,json=memoryUsage,proto3" json:"memory_usage,omitempty"` + DiskUsage float32 `protobuf:"fixed32,3,opt,name=disk_usage,json=diskUsage,proto3" json:"disk_usage,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SystemMetrics) Reset() { + *x = SystemMetrics{} + mi := &file_homeops_stream_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SystemMetrics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SystemMetrics) ProtoMessage() {} + +func (x *SystemMetrics) ProtoReflect() protoreflect.Message { + mi := &file_homeops_stream_proto_msgTypes[3] + 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 SystemMetrics.ProtoReflect.Descriptor instead. +func (*SystemMetrics) Descriptor() ([]byte, []int) { + return file_homeops_stream_proto_rawDescGZIP(), []int{3} +} + +func (x *SystemMetrics) GetCpuUsage() float32 { + if x != nil { + return x.CpuUsage + } + return 0 +} + +func (x *SystemMetrics) GetMemoryUsage() float32 { + if x != nil { + return x.MemoryUsage + } + return 0 +} + +func (x *SystemMetrics) GetDiskUsage() float32 { + if x != nil { + return x.DiskUsage + } + return 0 +} + +type CommandResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + Success bool `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"` + Output string `protobuf:"bytes,3,opt,name=output,proto3" json:"output,omitempty"` + Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` + ExecTimeMs int64 `protobuf:"varint,5,opt,name=exec_time_ms,json=execTimeMs,proto3" json:"exec_time_ms,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CommandResponse) Reset() { + *x = CommandResponse{} + mi := &file_homeops_stream_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CommandResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommandResponse) ProtoMessage() {} + +func (x *CommandResponse) ProtoReflect() protoreflect.Message { + mi := &file_homeops_stream_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 CommandResponse.ProtoReflect.Descriptor instead. +func (*CommandResponse) Descriptor() ([]byte, []int) { + return file_homeops_stream_proto_rawDescGZIP(), []int{4} +} + +func (x *CommandResponse) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *CommandResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *CommandResponse) GetOutput() string { + if x != nil { + return x.Output + } + return "" +} + +func (x *CommandResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *CommandResponse) GetExecTimeMs() int64 { + if x != nil { + return x.ExecTimeMs + } + return 0 +} + +type Alert struct { + state protoimpl.MessageState `protogen:"open.v1"` + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Level string `protobuf:"bytes,2,opt,name=level,proto3" json:"level,omitempty"` + Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Alert) Reset() { + *x = Alert{} + mi := &file_homeops_stream_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Alert) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Alert) ProtoMessage() {} + +func (x *Alert) ProtoReflect() protoreflect.Message { + mi := &file_homeops_stream_proto_msgTypes[5] + 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 Alert.ProtoReflect.Descriptor instead. +func (*Alert) Descriptor() ([]byte, []int) { + return file_homeops_stream_proto_rawDescGZIP(), []int{5} +} + +func (x *Alert) GetTimestamp() int64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *Alert) GetLevel() string { + if x != nil { + return x.Level + } + return "" +} + +func (x *Alert) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *Alert) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +var File_homeops_stream_proto protoreflect.FileDescriptor + +const file_homeops_stream_proto_rawDesc = "" + + "\n" + + "\x14homeops/stream.proto\"\xe0\x01\n" + + "\x14ServerCommandRequest\x12\x1d\n" + + "\n" + + "request_id\x18\x01 \x01(\tR\trequestId\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x123\n" + + "\x04args\x18\x03 \x03(\v2\x1f.ServerCommandRequest.ArgsEntryR\x04args\x12'\n" + + "\x0ftimeout_seconds\x18\x04 \x01(\x03R\x0etimeoutSeconds\x1a7\n" + + "\tArgsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xbb\x01\n" + + "\n" + + "AgentEvent\x12\x19\n" + + "\bagent_id\x18\x01 \x01(\tR\aagentId\x12*\n" + + "\theartbeat\x18\x02 \x01(\v2\n" + + ".HeartbeatH\x00R\theartbeat\x12=\n" + + "\x10command_response\x18\x03 \x01(\v2\x10.CommandResponseH\x00R\x0fcommandResponse\x12\x1e\n" + + "\x05alert\x18\x04 \x01(\v2\x06.AlertH\x00R\x05alertB\a\n" + + "\x05event\"S\n" + + "\tHeartbeat\x12\x1c\n" + + "\ttimestamp\x18\x01 \x01(\x03R\ttimestamp\x12(\n" + + "\ametrics\x18\x02 \x01(\v2\x0e.SystemMetricsR\ametrics\"n\n" + + "\rSystemMetrics\x12\x1b\n" + + "\tcpu_usage\x18\x01 \x01(\x02R\bcpuUsage\x12!\n" + + "\fmemory_usage\x18\x02 \x01(\x02R\vmemoryUsage\x12\x1d\n" + + "\n" + + "disk_usage\x18\x03 \x01(\x02R\tdiskUsage\"\x9a\x01\n" + + "\x0fCommandResponse\x12\x1d\n" + + "\n" + + "request_id\x18\x01 \x01(\tR\trequestId\x12\x18\n" + + "\asuccess\x18\x02 \x01(\bR\asuccess\x12\x16\n" + + "\x06output\x18\x03 \x01(\tR\x06output\x12\x14\n" + + "\x05error\x18\x04 \x01(\tR\x05error\x12 \n" + + "\fexec_time_ms\x18\x05 \x01(\x03R\n" + + "execTimeMs\"s\n" + + "\x05Alert\x12\x1c\n" + + "\ttimestamp\x18\x01 \x01(\x03R\ttimestamp\x12\x14\n" + + "\x05level\x18\x02 \x01(\tR\x05level\x12\x14\n" + + "\x05title\x18\x03 \x01(\tR\x05title\x12 \n" + + "\vdescription\x18\x04 \x01(\tR\vdescriptionB ServerCommandRequest.ArgsEntry + 2, // 1: AgentEvent.heartbeat:type_name -> Heartbeat + 4, // 2: AgentEvent.command_response:type_name -> CommandResponse + 5, // 3: AgentEvent.alert:type_name -> Alert + 3, // 4: Heartbeat.metrics:type_name -> SystemMetrics + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_homeops_stream_proto_init() } +func file_homeops_stream_proto_init() { + if File_homeops_stream_proto != nil { + return + } + file_homeops_stream_proto_msgTypes[1].OneofWrappers = []any{ + (*AgentEvent_Heartbeat)(nil), + (*AgentEvent_CommandResponse)(nil), + (*AgentEvent_Alert)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_homeops_stream_proto_rawDesc), len(file_homeops_stream_proto_rawDesc)), + NumEnums: 0, + NumMessages: 7, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_homeops_stream_proto_goTypes, + DependencyIndexes: file_homeops_stream_proto_depIdxs, + MessageInfos: file_homeops_stream_proto_msgTypes, + }.Build() + File_homeops_stream_proto = out.File + file_homeops_stream_proto_goTypes = nil + file_homeops_stream_proto_depIdxs = nil +} diff --git a/api/proto/homeops/hub.proto b/api/proto/homeops/hub.proto index 301b992..d402292 100644 --- a/api/proto/homeops/hub.proto +++ b/api/proto/homeops/hub.proto @@ -1,6 +1,8 @@ syntax = "proto3"; import "google/protobuf/empty.proto"; +import "homeops/register.proto"; +import "homeops/stream.proto"; option go_package = "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops;homeops"; @@ -8,77 +10,4 @@ service Hub { rpc Ping (google.protobuf.Empty) returns (PongResponse) {} rpc RegisterAgent (RegisterAgentRequest) returns (RegisterAgentResponse) {} rpc StreamConnection (stream AgentEvent) returns (stream ServerCommandRequest) {} -} - -message PongResponse { - string pong = 1; -} - -message RegisterAgentRequest { - string agent_id = 1; - string agent_name = 2; - string version = 3; - HostInfo host = 4; - repeated Capability capability = 5; -} - -message HostInfo { - string system = 1; - string hostname = 2; - string arch = 3; -} - -message Capability { - bool available = 1; - string version = 2; - string name = 3; - string reason = 4; -} - -message RegisterAgentResponse { - int64 heartbeat_interval_second = 1; - string agent_id = 2; -} - -message ServerCommandRequest { - string request_id = 1; - string name = 2; - map args = 3; - int64 timeout_seconds = 4; -} - -message AgentEvent { - string agent_id = 1; - - oneof event { - Heartbeat heartbeat = 2; - CommandResponse command_response = 3; - Alert alert = 4; - } -} - -message Heartbeat { - int64 timestamp = 1; - SystemMetrics metrics = 2; -} - -message SystemMetrics { - float cpu_usage = 1; - float memory_usage = 2; - float disk_usage = 3; -} - -message CommandResponse { - string request_id = 1; - bool success = 2; - string output = 3; - string error = 4; - int64 exec_time_ms = 5; -} - -message Alert { - int64 timestamp = 1; - string level = 2; - string title = 3; - string description = 4; } \ No newline at end of file diff --git a/api/proto/homeops/register.proto b/api/proto/homeops/register.proto new file mode 100644 index 0000000..dcbb2cc --- /dev/null +++ b/api/proto/homeops/register.proto @@ -0,0 +1,59 @@ +syntax = "proto3"; + +option go_package = "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops;homeops"; + +message PongResponse { + string pong = 1; +} + +message RegisterAgentRequest { + string agent_id = 1; + string agent_name = 2; + string version = 3; + HostInfo host = 4; + repeated Capability capability = 5; +} + +message HostInfo { + string system = 1; + string hostname = 2; + string arch = 3; +} + +message Capability { + bool available = 1; // доступен ли + string version = 2; // версия раздела + string name = 3; // название раздела по типу докер или управление пк + string reason = 4; // причина если раздел не доступент + repeated CapabilityCommand command = 5; // команды раздела +} + +message CapabilityCommand { + string name = 1; // название команды + repeated CommandsArgs opt_args = 2; // опциоанльные переменные + repeated CommandsArgs req_args = 3; // обязательные переменные + string version = 4; // версия команды + string description = 5; // описание команды для документации + string type_output = 7; +} + +message CommandsArgs { + string name = 1; // название аргумента + string type = 2; // какой тип path int string bool + string description = 3; // описание для документации + string default = 4; // значение по умолчанию + repeated string enum = 5; // enum комманд по типу run stop restart + ArgValidation validation = 6; +} + +message ArgValidation { + int64 min_value = 1; // для чисел + int64 max_value = 2; // для чисел + string pattern = 3; // для regex строк + repeated string allowed_exts = 4; // для путей и файлов по типу .zip .rar итд +} + +message RegisterAgentResponse { + int64 heartbeat_interval_second = 1; + string agent_id = 2; +} \ No newline at end of file diff --git a/api/proto/homeops/stream.proto b/api/proto/homeops/stream.proto new file mode 100644 index 0000000..dd2ebf0 --- /dev/null +++ b/api/proto/homeops/stream.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; + +option go_package = "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops;homeops"; + +message ServerCommandRequest { + string request_id = 1; + string name = 2; + map args = 3; + int64 timeout_seconds = 4; +} + +message AgentEvent { + string agent_id = 1; + + oneof event { + Heartbeat heartbeat = 2; + CommandResponse command_response = 3; + Alert alert = 4; + } +} + +message Heartbeat { + int64 timestamp = 1; + SystemMetrics metrics = 2; +} + +message SystemMetrics { + float cpu_usage = 1; + float memory_usage = 2; + float disk_usage = 3; +} + +message CommandResponse { + string request_id = 1; + bool success = 2; + string output = 3; + string error = 4; + int64 exec_time_ms = 5; +} + +message Alert { + int64 timestamp = 1; + string level = 2; + string title = 3; + string description = 4; +} \ No newline at end of file diff --git a/hub/internal/app/app.go b/hub/internal/app/app.go index 4f7eb4d..18687fe 100644 --- a/hub/internal/app/app.go +++ b/hub/internal/app/app.go @@ -59,9 +59,9 @@ func (a *App) Run() { a.log.Info().Msg("migrations applied successfully") hubStore := store.NewHubStore(DBConn) - hubService := hub_service.NewHubService(hubStore, a.log) + hubService := hub_service.NewHubService(hubStore, a.cfg.Heartbeat, a.log) statusNotifier := notifier.NewStatusNotifier() - connManger := connection_manager.NewConnectionManager(hubStore, statusNotifier, a.log) + connManger := connection_manager.NewConnectionManager(hubStore, statusNotifier, a.cfg.Heartbeat*1000, a.log) a.log.Info().Msg("starting hub service") diff --git a/hub/internal/domain/stream.go b/hub/internal/domain/stream.go index 8870ae4..9a5dc44 100644 --- a/hub/internal/domain/stream.go +++ b/hub/internal/domain/stream.go @@ -23,7 +23,7 @@ type AgentAlert struct { } type SystemMetrics struct { - CpuUsage float64 + CPUUsage float64 MemoryUsage float64 DiskUsage float64 } diff --git a/hub/internal/rpc/errors.go b/hub/internal/rpc/errors.go new file mode 100644 index 0000000..b755049 --- /dev/null +++ b/hub/internal/rpc/errors.go @@ -0,0 +1,5 @@ +package rpc + +import "fmt" + +var ErrFailedRegister = fmt.Errorf("failed register agent") diff --git a/hub/internal/rpc/server.go b/hub/internal/rpc/server.go index 242d39f..98adaa1 100644 --- a/hub/internal/rpc/server.go +++ b/hub/internal/rpc/server.go @@ -7,6 +7,7 @@ import ( pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops" "github.com/lorsanstand/HomeOps-Hub/hub/internal/service/connection_manager" "github.com/lorsanstand/HomeOps-Hub/shared/domain" + "github.com/lorsanstand/HomeOps-Hub/shared/mappers/rpc" "github.com/rs/zerolog" "google.golang.org/grpc" "google.golang.org/protobuf/types/known/emptypb" @@ -46,13 +47,18 @@ func (h *HubHandler) Ping(ctx context.Context, _ *emptypb.Empty) (*pb.PongRespon func (h *HubHandler) RegisterAgent(ctx context.Context, request *pb.RegisterAgentRequest) (*pb.RegisterAgentResponse, error) { h.log.Debug().Str("agentID", request.AgentId).Str("agentName", request.AgentName).Msg("register agent request received") - data := domain.ToDomainAgentRequest(request) + data, err := rpc.ToDomainAgentRequest(request) + if err != nil { + h.log.Error().Err(err).Msg("failed to casting request") + return &pb.RegisterAgentResponse{}, ErrFailedRegister + } resp, err := h.hub.RegisterAgent(ctx, data) if err != nil { - return domain.ToGRPCAgentResponse(resp), err + h.log.Error().Err(err).Msg("failed register agent") + return rpc.ToGRPCAgentResponse(resp), ErrFailedRegister } h.log.Info().Str("agentID", resp.AgentID).Msg("register agent request completed") - return domain.ToGRPCAgentResponse(resp), nil + return rpc.ToGRPCAgentResponse(resp), nil } func (h *HubHandler) StreamConnection(stream grpc.BidiStreamingServer[pb.AgentEvent, pb.ServerCommandRequest]) error { diff --git a/hub/internal/service/connection_manager/agent.go b/hub/internal/service/connection_manager/agent.go index a391b98..ce11c91 100644 --- a/hub/internal/service/connection_manager/agent.go +++ b/hub/internal/service/connection_manager/agent.go @@ -66,7 +66,6 @@ func (a *AgentConnection) Listen() error { response := toAgentResponse(x) ch <- response } - default: } } } @@ -109,7 +108,7 @@ func (a *AgentConnection) listenHeartbeat(heartbeats <-chan domainHub.CreateHear return } a.log.Debug(). - Float64("cpu usage", heartbeat.Metrics.CpuUsage). + Float64("cpu usage", heartbeat.Metrics.CPUUsage). Float64("disk usage", heartbeat.Metrics.DiskUsage). Float64("memory usage", heartbeat.Metrics.MemoryUsage).Msg("") diff --git a/hub/internal/service/connection_manager/agent_test.go b/hub/internal/service/connection_manager/agent_test.go index 484ab85..5f0e0e6 100644 --- a/hub/internal/service/connection_manager/agent_test.go +++ b/hub/internal/service/connection_manager/agent_test.go @@ -99,7 +99,9 @@ func TestAgentConnection_Heartbeat(t *testing.T) { func TestAgentConnection_Execute(t *testing.T) { h := newAgentTestHarness(t, 5000) - go h.agent.Listen() + go func() { + _ = h.agent.Listen() + }() // Данные для проверки requestID := make(chan domainHub.AgentResponse) @@ -156,7 +158,7 @@ func TestAgentConnection_HeartbeatTimeout(t *testing.T) { timeout := time.After(2 * time.Second) gotListen := false gotExec := false - for !(gotListen && gotExec) { + for !gotListen && !gotExec { select { case err := <-listenDone: assert.ErrorIs(t, err, context.Canceled) @@ -203,7 +205,9 @@ func TestAgentConnection_ExecuteClose(t *testing.T) { t.Cleanup(cancelExecute) executeCh := make(chan struct{}) - go h.agent.Listen() + go func() { + _ = h.agent.Listen() + }() go func() { _, err := h.agent.Execute(ctxExecute, domainHub.AgentRequest{ @@ -280,7 +284,9 @@ func TestAgentConnection_HeartbeatErrorDoesNotStop(t *testing.T) { h.heartbeat.err = errors.New("db error") h.heartbeat.mu.Unlock() - go h.agent.Listen() + go func() { + _ = h.agent.Listen() + }() h.recvCh <- &pb.AgentEvent{AgentId: "agent-1", Event: &pb.AgentEvent_Heartbeat{ Heartbeat: &pb.Heartbeat{ Timestamp: time.Now().Unix(), @@ -293,7 +299,9 @@ func TestAgentConnection_HeartbeatErrorDoesNotStop(t *testing.T) { func TestAgentConnection_ConcurrentExecute(t *testing.T) { h := newAgentTestHarness(t, 5000) - go h.agent.Listen() + go func() { + _ = h.agent.Listen() + }() responses := make(chan domainHub.AgentResponse, 2) diff --git a/hub/internal/service/connection_manager/manager.go b/hub/internal/service/connection_manager/manager.go index 13acc81..5a5480d 100644 --- a/hub/internal/service/connection_manager/manager.go +++ b/hub/internal/service/connection_manager/manager.go @@ -8,17 +8,16 @@ import ( "google.golang.org/grpc/metadata" ) -const heartbeatTimeoutMS = 6000 - type ConnectionManager struct { - heartbeat heartbeatStore - log zerolog.Logger - status statusNotifier - agentConnStore *AgentConnStore + heartbeat heartbeatStore + log zerolog.Logger + status statusNotifier + agentConnStore *AgentConnStore + heartbeatTimeout int } -func NewConnectionManager(heartbeat heartbeatStore, status statusNotifier, logger zerolog.Logger) *ConnectionManager { - return &ConnectionManager{heartbeat: heartbeat, log: logger, status: status, agentConnStore: NewAgentConnStore()} +func NewConnectionManager(heartbeat heartbeatStore, status statusNotifier, heartbeatTimeoutMS int, logger zerolog.Logger) *ConnectionManager { + return &ConnectionManager{heartbeat: heartbeat, log: logger, status: status, agentConnStore: NewAgentConnStore(), heartbeatTimeout: heartbeatTimeoutMS + 600} } func (c *ConnectionManager) NewConnection(stream StreamConn) error { @@ -32,7 +31,7 @@ func (c *ConnectionManager) NewConnection(stream StreamConn) error { status := c.status.New(AgentID) - agent := newAgentConnection(AgentID, stream, c.heartbeat, status, heartbeatTimeoutMS, c.log) + agent := newAgentConnection(AgentID, stream, c.heartbeat, status, c.heartbeatTimeout, c.log) c.agentConnStore.Add(AgentID, agent) defer c.agentConnStore.Delete(AgentID) diff --git a/hub/internal/service/connection_manager/manager_test.go b/hub/internal/service/connection_manager/manager_test.go index 61a16c6..b346130 100644 --- a/hub/internal/service/connection_manager/manager_test.go +++ b/hub/internal/service/connection_manager/manager_test.go @@ -24,7 +24,7 @@ func newConnectionManagerTestHarness(t *testing.T) *connectionManagerTestHarness heartbeat := &heartBeatMock{doneCh: make(chan struct{}, 2)} status := &statusNotifierMock{agentIDCh: make(chan string, 1)} - manager := NewConnectionManager(heartbeat, status, zerolog.New(nil)) + manager := NewConnectionManager(heartbeat, status, 10000, zerolog.New(nil)) return &connectionManagerTestHarness{manager: manager, status: status, heartbeat: heartbeat} } diff --git a/hub/internal/service/connection_manager/mapper.go b/hub/internal/service/connection_manager/mapper.go index 68fa0ac..6ffabfc 100644 --- a/hub/internal/service/connection_manager/mapper.go +++ b/hub/internal/service/connection_manager/mapper.go @@ -15,7 +15,7 @@ func toCreateHeartbeatModel(agentID string, heartbeat *pb.AgentEvent_Heartbeat) Timestamp: timestamp, Metrics: domainHub.SystemMetrics{ MemoryUsage: float64(heartbeat.Heartbeat.Metrics.MemoryUsage), - CpuUsage: float64(heartbeat.Heartbeat.Metrics.CpuUsage), + CPUUsage: float64(heartbeat.Heartbeat.Metrics.CpuUsage), DiskUsage: float64(heartbeat.Heartbeat.Metrics.DiskUsage), }, } diff --git a/hub/internal/service/hub_service/hub.go b/hub/internal/service/hub_service/hub.go index 00d7181..f9ae961 100644 --- a/hub/internal/service/hub_service/hub.go +++ b/hub/internal/service/hub_service/hub.go @@ -12,8 +12,6 @@ import ( "github.com/rs/zerolog" ) -const HEARTBEAT = 5 - type Store interface { NewAgent(ctx context.Context, agent domainHub.CreateAgentModel) error GetAgentByAgentID(ctx context.Context, AgentID string) (domainHub.AgentModel, error) @@ -21,12 +19,13 @@ type Store interface { } type HubService struct { - store Store - log zerolog.Logger + store Store + log zerolog.Logger + heartbeatTimeout int } -func NewHubService(store Store, logger zerolog.Logger) *HubService { - return &HubService{log: logger, store: store} +func NewHubService(store Store, heartbeatTimeout int, logger zerolog.Logger) *HubService { + return &HubService{log: logger, store: store, heartbeatTimeout: heartbeatTimeout} } func (h *HubService) RegisterAgent(ctx context.Context, data domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error) { @@ -47,7 +46,7 @@ func (h *HubService) RegisterAgent(ctx context.Context, data domain.RegisterAgen return domain.RegisterAgentResponse{}, fmt.Errorf("update agent in db: %w", err) } h.log.Debug().Str("agentId", agent.AgentID).Msg("agent updated successfully") - return domain.RegisterAgentResponse{AgentID: agent.AgentID, Heartbeat: HEARTBEAT}, nil + return domain.RegisterAgentResponse{AgentID: agent.AgentID, Heartbeat: h.heartbeatTimeout}, nil } AgentID, err := hasher.MakeID(data.Host, data.AgentName) @@ -62,5 +61,5 @@ func (h *HubService) RegisterAgent(ctx context.Context, data domain.RegisterAgen if err := h.store.NewAgent(ctx, agentStore); err != nil { return domain.RegisterAgentResponse{}, fmt.Errorf("insert new agent: %w", err) } - return domain.RegisterAgentResponse{AgentID: AgentID, Heartbeat: HEARTBEAT}, nil + return domain.RegisterAgentResponse{AgentID: AgentID, Heartbeat: h.heartbeatTimeout}, nil } diff --git a/hub/internal/store/mapper.go b/hub/internal/store/mapper.go index e78c9e4..8130740 100644 --- a/hub/internal/store/mapper.go +++ b/hub/internal/store/mapper.go @@ -82,7 +82,7 @@ func toDBHeartbeat(heartbeat domainHub.CreateHeartbeatModel) gen2.InsertHeartbea return gen2.InsertHeartbeatParams{ AgentID: heartbeat.AgentID, HeartbeatTimestamp: heartbeat.Timestamp, - CpuUsage: heartbeat.Metrics.CpuUsage, + CpuUsage: heartbeat.Metrics.CPUUsage, DiskUsage: heartbeat.Metrics.DiskUsage, MemoryUsage: heartbeat.Metrics.MemoryUsage, } @@ -94,7 +94,7 @@ func toHeartBeatModel(heartbeat gen2.Heartbeat) domainHub.HeartbeatModel { AgentID: heartbeat.AgentID, ID: int(heartbeat.ID), Metrics: domainHub.SystemMetrics{ - CpuUsage: heartbeat.CpuUsage, + CPUUsage: heartbeat.CpuUsage, DiskUsage: heartbeat.DiskUsage, MemoryUsage: heartbeat.MemoryUsage, }, diff --git a/shared/config/config.go b/shared/config/config.go index 5ce002d..565787c 100644 --- a/shared/config/config.go +++ b/shared/config/config.go @@ -9,14 +9,10 @@ import ( ) type Config struct { - DBHost string `env:"DB_HOST"` - DBPort int `env:"DB_PORT"` - DBPassword string `env:"DB_PASS"` - DBUser string `env:"DB_USER"` - DBName string `env:"DB_NAME"` - LogLevel string `env:"LOG_LEVEL" env-default:"INFO"` - Mode string `env:"MODE" env-default:"DEV"` - Port int `env:"PORT" env-default:"9000"` + LogLevel string `env:"LOG_LEVEL" env-default:"INFO"` + Mode string `env:"MODE" env-default:"DEV"` + Port int `env:"PORT" env-default:"9000"` + Heartbeat int `env:"HEARTBEAT" env-default:"5"` } func NewConfig() (*Config, error) { @@ -33,16 +29,6 @@ func NewConfig() (*Config, error) { return &cfg, nil } -func (c *Config) GetURLPostgres() string { - return fmt.Sprintf( - "postgres://%v:%v@%v:%v/%v?sslmode=disable", - c.DBUser, - c.DBPassword, - c.DBHost, - c.DBPort, - c.DBName) -} - func (c *Config) GetLogLevel() zerolog.Level { level, err := zerolog.ParseLevel(c.LogLevel) if err != nil { diff --git a/shared/config/config_test.go b/shared/config/config_test.go index 1ad1bc1..f7288a5 100644 --- a/shared/config/config_test.go +++ b/shared/config/config_test.go @@ -39,38 +39,3 @@ func TestConfig_GetLogLevel(t *testing.T) { }) } } - -func TestConfig_GetURLPostgres(t *testing.T) { - t.Parallel() - - tests := []struct { - name string - cfg Config - wantURLPostgres string - }{ - { - name: "success", - cfg: Config{ - DBHost: "TestHost", - DBName: "TestName", - DBPassword: "TestPassword", - DBPort: 1234, - DBUser: "TestUser", - }, - wantURLPostgres: "postgres://TestUser:TestPassword@TestHost:1234/TestName?sslmode=disable", - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - - url := tt.cfg.GetURLPostgres() - - if url != tt.wantURLPostgres { - t.Fatalf("expected %v, got: %v", tt.wantURLPostgres, url) - } - }) - } -} diff --git a/shared/domain/agent.go b/shared/domain/agent.go deleted file mode 100644 index 2a24ae5..0000000 --- a/shared/domain/agent.go +++ /dev/null @@ -1,27 +0,0 @@ -package domain - -type RegisterAgentRequest struct { - AgentID string - AgentName string - AgentVersion string - Host HostInfo - Capabilities []Capability -} - -type HostInfo struct { - System string - Hostname string - Arch string -} - -type Capability struct { - Available bool - Version string - Name string - Reason string -} - -type RegisterAgentResponse struct { - Heartbeat int - AgentID string -} diff --git a/shared/domain/mapper.go b/shared/domain/mapper.go deleted file mode 100644 index 587d361..0000000 --- a/shared/domain/mapper.go +++ /dev/null @@ -1,83 +0,0 @@ -package domain - -import ( - pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops" -) - -func ToDomainAgentRequest(request *pb.RegisterAgentRequest) RegisterAgentRequest { - if request == nil { - return RegisterAgentRequest{} - } - - return RegisterAgentRequest{ - AgentID: request.AgentId, - AgentName: request.AgentName, - Host: HostInfo{ - System: request.Host.System, - Hostname: request.Host.Hostname, - Arch: request.Host.Arch, - }, - Capabilities: ToDomainCapabilities(request.Capability), - } -} - -func ToDomainAgentResponse(response *pb.RegisterAgentResponse) RegisterAgentResponse { - if response == nil { - return RegisterAgentResponse{} - } - - return RegisterAgentResponse{ - AgentID: response.AgentId, - Heartbeat: int(response.HeartbeatIntervalSecond), - } -} - -func ToDomainCapabilities(capability []*pb.Capability) []Capability { - var caps []Capability - - for _, capa := range capability { - if capa == nil { - continue - } - - caps = append(caps, Capability{ - Name: capa.Name, - Version: capa.Version, - Reason: capa.Reason, - Available: capa.Available, - }) - } - - return caps -} - -func ToGRPCAgentRequest(request RegisterAgentRequest) pb.RegisterAgentRequest { - return pb.RegisterAgentRequest{ - AgentId: request.AgentID, - AgentName: request.AgentName, - Host: &pb.HostInfo{ - Hostname: request.Host.Hostname, - Arch: request.Host.Arch, - System: request.Host.System, - }, - Version: request.AgentVersion, - Capability: ToGRPCCapability(request.Capabilities), - } -} - -func ToGRPCAgentResponse(response RegisterAgentResponse) *pb.RegisterAgentResponse { - return &pb.RegisterAgentResponse{AgentId: response.AgentID, HeartbeatIntervalSecond: int64(response.Heartbeat)} -} - -func ToGRPCCapability(caps []Capability) []*pb.Capability { - var capability []*pb.Capability - for _, capi := range caps { - capability = append(capability, &pb.Capability{ - Name: capi.Name, - Available: capi.Available, - Version: capi.Version, - Reason: capi.Reason, - }) - } - return capability -} diff --git a/shared/domain/register.go b/shared/domain/register.go new file mode 100644 index 0000000..619cf5a --- /dev/null +++ b/shared/domain/register.go @@ -0,0 +1,53 @@ +package domain + +type RegisterAgentRequest struct { + AgentID string + AgentName string + AgentVersion string + Host HostInfo + Capabilities []Capability +} + +type HostInfo struct { + System string + Hostname string + Arch string +} + +type Capability struct { + Available bool + Version string + Name string + Reason string + Command []CapabilityCommand +} + +type CapabilityCommand struct { + Name string + OptionalArgs []CommandArgs + RequiredArgs []CommandArgs + Version string + Description string + TypeOutput string +} + +type CommandArgs struct { + Name string + Type string + Description string + Default string + Enum []string + Validation ArgValidation +} + +type ArgValidation struct { + MinValue int + MaxValue int + Pattern string + AllowedExts []string +} + +type RegisterAgentResponse struct { + Heartbeat int + AgentID string +} diff --git a/shared/mappers/rpc/mapper.go b/shared/mappers/rpc/mapper.go new file mode 100644 index 0000000..28dbc03 --- /dev/null +++ b/shared/mappers/rpc/mapper.go @@ -0,0 +1,168 @@ +package rpc + +import ( + "fmt" + + pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops" + "github.com/lorsanstand/HomeOps-Hub/shared/domain" +) + +func ToDomainAgentRequest(request *pb.RegisterAgentRequest) (domain.RegisterAgentRequest, error) { + if request == nil { + return domain.RegisterAgentRequest{}, fmt.Errorf("request is empty") + } + + return domain.RegisterAgentRequest{ + AgentVersion: request.Version, + AgentID: request.AgentId, + AgentName: request.AgentName, + Host: domain.HostInfo{ + System: request.Host.System, + Hostname: request.Host.Hostname, + Arch: request.Host.Arch, + }, + Capabilities: ToDomainCapabilities(request.Capability), + }, nil +} + +func ToDomainAgentResponse(response *pb.RegisterAgentResponse) (domain.RegisterAgentResponse, error) { + if response == nil { + return domain.RegisterAgentResponse{}, fmt.Errorf("request is empty") + } + + return domain.RegisterAgentResponse{ + AgentID: response.AgentId, + Heartbeat: int(response.HeartbeatIntervalSecond), + }, nil +} + +func ToDomainCapabilities(capabilities []*pb.Capability) []domain.Capability { + domainCaps := make([]domain.Capability, len(capabilities)) + + for id, capability := range capabilities { + if capability == nil { + continue + } + + domainCaps[id] = domain.Capability{ + Name: capability.Name, + Version: capability.Version, + Reason: capability.Reason, + Available: capability.Available, + Command: ToDomainCapabilityCommands(capability.Command), + } + } + + return domainCaps +} + +func ToDomainCapabilityCommands(commands []*pb.CapabilityCommand) []domain.CapabilityCommand { + domainCommand := make([]domain.CapabilityCommand, len(commands)) + + for id, command := range commands { + if command == nil { + continue + } + + domainCommand[id] = domain.CapabilityCommand{ + Name: command.Name, + OptionalArgs: ToDomainCommandArgs(command.OptArgs), + RequiredArgs: ToDomainCommandArgs(command.ReqArgs), + Version: command.Version, + } + } + return domainCommand +} + +func ToDomainCommandArgs(args []*pb.CommandsArgs) []domain.CommandArgs { + DomainArgs := make([]domain.CommandArgs, len(args)) + + for id, arg := range args { + DomainArgs[id] = domain.CommandArgs{ + Name: arg.Name, + Type: arg.Type, + Default: arg.Default, + Description: arg.Description, + Enum: arg.Enum, + Validation: domain.ArgValidation{ + AllowedExts: arg.Validation.AllowedExts, + MaxValue: int(arg.Validation.MaxValue), + MinValue: int(arg.Validation.MinValue), + Pattern: arg.Validation.Pattern, + }, + } + } + + return DomainArgs +} + +func ToGRPCAgentRequest(request domain.RegisterAgentRequest) *pb.RegisterAgentRequest { + return &pb.RegisterAgentRequest{ + AgentId: request.AgentID, + AgentName: request.AgentName, + Host: &pb.HostInfo{ + Hostname: request.Host.Hostname, + Arch: request.Host.Arch, + System: request.Host.System, + }, + Version: request.AgentVersion, + Capability: ToGRPCCapability(request.Capabilities), + } +} + +func ToGRPCAgentResponse(response domain.RegisterAgentResponse) *pb.RegisterAgentResponse { + return &pb.RegisterAgentResponse{AgentId: response.AgentID, HeartbeatIntervalSecond: int64(response.Heartbeat)} +} + +func ToGRPCCapability(capabilities []domain.Capability) []*pb.Capability { + GRPCCapabilities := make([]*pb.Capability, len(capabilities)) + + for id, capability := range capabilities { + GRPCCapabilities[id] = &pb.Capability{ + Name: capability.Name, + Available: capability.Available, + Version: capability.Version, + Reason: capability.Reason, + Command: ToGRPCCapabilityCommands(capability.Command), + } + } + return GRPCCapabilities +} + +func ToGRPCCapabilityCommands(commands []domain.CapabilityCommand) []*pb.CapabilityCommand { + GRPCCommands := make([]*pb.CapabilityCommand, len(commands)) + + for id, command := range commands { + GRPCCommands[id] = &pb.CapabilityCommand{ + Name: command.Name, + Version: command.Version, + OptArgs: ToGRPCCommandArgs(command.OptionalArgs), + ReqArgs: ToGRPCCommandArgs(command.RequiredArgs), + TypeOutput: command.TypeOutput, + } + } + + return GRPCCommands +} + +func ToGRPCCommandArgs(args []domain.CommandArgs) []*pb.CommandsArgs { + GRPCArgs := make([]*pb.CommandsArgs, len(args)) + + for id, arg := range args { + GRPCArgs[id] = &pb.CommandsArgs{ + Name: arg.Name, + Type: arg.Type, + Default: arg.Default, + Description: arg.Description, + Enum: arg.Enum, + Validation: &pb.ArgValidation{ + AllowedExts: arg.Validation.AllowedExts, + MaxValue: int64(arg.Validation.MaxValue), + MinValue: int64(arg.Validation.MinValue), + Pattern: arg.Validation.Pattern, + }, + } + } + + return GRPCArgs +}