diff --git a/.gitignore b/.gitignore
index d19b928..0adaa22 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.env
-agent.dev.yaml
\ No newline at end of file
+config.yaml
+.idea
\ No newline at end of file
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..2cfb250
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,47 @@
+version: "2"
+
+run:
+ # Сколько времени давать линтеру на проверку (для больших проектов лучше ставить 5m)
+ timeout: 3m
+ # Проверять ли тесты
+ tests: true
+
+linters:
+ # Отключаем все по умолчанию, чтобы включить только нужные нам
+ disable-all: true
+ enable:
+ # --- ОБЯЗАТЕЛЬНЫЕ (База) ---
+ - errcheck # Проверяет, не забыл ли ты обработать ошибку (if err != nil)
+ - govet # Официальный инструмент Go, ищет подозрительные конструкции
+ - ineffassign # Находит переменные, которым присвоили значение, но не использовали
+ - staticcheck # Огромный набор проверок на логические ошибки
+ - unused # Ищет неиспользуемый код (функции, переменные, типы)
+
+ # --- ОБУЧАЮЩИЕ (Помогут новичку) ---
+ - revive # Замена старому golint: следит за именованием и комментариями
+ - errname # Проверяет, что ошибки названы по стандарту (например, ErrSentinel)
+ - goconst # Находит строки, которые часто повторяются (подскажет сделать константу)
+ - makezero # Следит, чтобы ты не делал лишних аллокаций в slice
+
+ settings:
+ revive:
+ # Настраиваем правила
+ rules:
+ # Отключаем обязательные комментарии для экспортируемых сущностей
+ - name: exported
+ disabled: true
+ # Отключаем требование комментариев к пакетам
+ - name: package-comments
+ disabled: true
+ # Оставляем полезное: проверка именования (var_name -> varName)
+ - name: var-naming
+ severity: warning
+
+issues:
+ # Не ограничивай количество ошибок, пока учишься
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+ # Исключаем некоторые папки (например, сгенерированный код)
+ exclude-dirs:
+ - vendor
\ No newline at end of file
diff --git a/.idea/golinter.xml b/.idea/golinter.xml
new file mode 100644
index 0000000..1ccf3ec
--- /dev/null
+++ b/.idea/golinter.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.sync-conflict-20260504-202326-XNSB2YU.xml b/.idea/workspace.sync-conflict-20260504-202326-XNSB2YU.xml
new file mode 100644
index 0000000..ef52743
--- /dev/null
+++ b/.idea/workspace.sync-conflict-20260504-202326-XNSB2YU.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "associatedIndex": 6
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1775479991162
+
+
+ 1775479991162
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cmd/agent/main.go b/agent/cmd/main.go
similarity index 53%
rename from cmd/agent/main.go
rename to agent/cmd/main.go
index 67febdd..9fcdbb1 100644
--- a/cmd/agent/main.go
+++ b/agent/cmd/main.go
@@ -1,11 +1,13 @@
package main
-import "github.com/lorsanstand/HomeOps-Hub/internal/agent/app"
+import (
+ "github.com/lorsanstand/HomeOps-Hub/agent/internal/app"
+)
func main() {
start, err := app.NewApp()
if err != nil {
- return
+ panic(err)
}
start.Run()
}
diff --git a/internal/agent/app/app.go b/agent/internal/app/app.go
similarity index 52%
rename from internal/agent/app/app.go
rename to agent/internal/app/app.go
index a588b6d..d7b5f8e 100644
--- a/internal/agent/app/app.go
+++ b/agent/internal/app/app.go
@@ -5,13 +5,13 @@ import (
standartlog "log"
"github.com/docker/docker/client"
- "github.com/lorsanstand/HomeOps-Hub/internal/agent/rpc"
- "github.com/lorsanstand/HomeOps-Hub/internal/agent/service/agent_service"
- "github.com/lorsanstand/HomeOps-Hub/internal/agent/service/collector"
- "github.com/lorsanstand/HomeOps-Hub/internal/agent/service/docker_service"
- "github.com/lorsanstand/HomeOps-Hub/internal/agent/utils/config_yaml"
- "github.com/lorsanstand/HomeOps-Hub/internal/agent/utils/settings"
- log2 "github.com/lorsanstand/HomeOps-Hub/internal/shared/log"
+ "github.com/lorsanstand/HomeOps-Hub/agent/internal/rpc"
+ "github.com/lorsanstand/HomeOps-Hub/agent/internal/service/agent_service"
+ "github.com/lorsanstand/HomeOps-Hub/agent/internal/service/collector"
+ "github.com/lorsanstand/HomeOps-Hub/agent/internal/service/docker_service"
+ "github.com/lorsanstand/HomeOps-Hub/agent/internal/utils/config_yaml"
+ "github.com/lorsanstand/HomeOps-Hub/agent/internal/utils/settings"
+ "github.com/lorsanstand/HomeOps-Hub/shared/log"
"github.com/rs/zerolog"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
@@ -25,23 +25,23 @@ type App struct {
}
func NewApp() (*App, error) {
-
cfg, err := config_yaml.NewConfig()
if err != nil {
standartlog.Fatalf("failed to get config: %v", err)
return nil, err
}
- log := log2.NewLogger(cfg)
- log = log.With().Str("component", "agent.app").Logger()
+ logger := log.NewLogger(cfg)
+ logger = logger.With().Str("component", "internal.app").Logger()
+ logger = logger.With().Str("name", cfg.AppName).Logger()
sett, err := settings.ReadSettings(cfg.SettingsPath)
if err != nil {
- log.Error().Err(err).Msg("failed to get settings")
+ logger.Error().Err(err).Msg("failed to get settings")
return nil, err
}
- return &App{cfg: cfg, log: log, settings: sett}, nil
+ return &App{cfg: cfg, log: logger, settings: sett}, nil
}
func (a *App) Run() {
@@ -49,12 +49,17 @@ func (a *App) Run() {
GRPCConn, err := grpc.NewClient(a.cfg.GetGRPCAddress(), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
- a.log.Error().Err(err).Msg("failed to get hub connections")
+ a.log.Error().Err(err).Msg("failed to connection hub")
return
}
+ a.log.Info().Msg("connection to the hub successful")
- conn := rpc.NewConnectAgent(GRPCConn, a.log)
- defer conn.Close()
+ conn := rpc.NewConnectAgent(GRPCConn)
+ defer func() {
+ if err := conn.Close(); err != nil {
+ a.log.Warn().Err(err).Msg("failed to close rpc connection")
+ }
+ }()
var DockerService collector.Docker
@@ -63,11 +68,15 @@ func (a *App) Run() {
a.log.Warn().Err(err).Msg("failed to get docker API")
DockerService = docker_service.NewBadDocker("not_installed")
} else {
+ a.log.Info().Msg("successfully to get docker API")
DockerService = docker_service.NewDockerService(DockerClient, a.log)
}
collect := collector.NewCollector(DockerService, a.log)
agent := agent_service.NewAgentService(collect, conn, a.settings, a.cfg, a.log)
- agent.RegisterAgentConn(ctx)
+ if err := agent.RegisterAgentConn(ctx); err != nil {
+ a.log.Error().Err(err).Msg("failed to agent registration")
+ }
+ a.log.Info().Msg("agent registration complete")
}
diff --git a/internal/agent/rpc/client.go b/agent/internal/rpc/client.go
similarity index 62%
rename from internal/agent/rpc/client.go
rename to agent/internal/rpc/client.go
index a945085..23f9ea3 100644
--- a/internal/agent/rpc/client.go
+++ b/agent/internal/rpc/client.go
@@ -4,27 +4,21 @@ import (
"context"
pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops"
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
- "github.com/rs/zerolog"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
"google.golang.org/grpc"
)
type Connection struct {
hub pb.HubClient
conn *grpc.ClientConn
- log zerolog.Logger
}
-func NewConnectAgent(conn *grpc.ClientConn, logger zerolog.Logger) *Connection {
- logger = logger.With().Str("component", "agent.rpc").Logger()
-
+func NewConnectAgent(conn *grpc.ClientConn) *Connection {
client := pb.NewHubClient(conn)
-
- return &Connection{hub: client, conn: conn, log: logger}
+ return &Connection{hub: client, conn: conn}
}
func (c *Connection) Close() error {
- c.log.Warn().Msg("connection close")
return c.conn.Close()
}
@@ -34,6 +28,5 @@ 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)))
- c.log.Info().Msg("register agent")
return domain.ToDomainAgentResponse(ResponseData), err
}
diff --git a/agent/internal/service/agent_service/agent.go b/agent/internal/service/agent_service/agent.go
new file mode 100644
index 0000000..6eb18b0
--- /dev/null
+++ b/agent/internal/service/agent_service/agent.go
@@ -0,0 +1,71 @@
+package agent_service
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/lorsanstand/HomeOps-Hub/agent/internal/utils/config_yaml"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
+ "github.com/rs/zerolog"
+)
+
+type Collector interface {
+ GatherInfoSystem() (domain.HostInfo, []domain.Capability)
+}
+
+type Settings interface {
+ InsertAgentID(agentID string) error
+ GetAgentID() string
+}
+
+type HubConnection interface {
+ RegisterAgent(ctx context.Context, RegisterData domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error)
+}
+
+type AgentService struct {
+ collect Collector
+ conn HubConnection
+ log zerolog.Logger
+ cfg *config_yaml.AgentConfig
+ heartBeat int
+ settings Settings
+}
+
+func NewAgentService(
+ collector Collector,
+ conn HubConnection,
+ settings Settings,
+ cfg *config_yaml.AgentConfig,
+ logger zerolog.Logger,
+) *AgentService {
+ logger = logger.With().Str("component", "internal.service.agent_serivce").Logger()
+
+ return &AgentService{collect: collector, conn: conn, cfg: cfg, log: logger, settings: settings}
+}
+
+func (a *AgentService) RegisterAgentConn(ctx context.Context) error {
+ a.log.Debug().Msg("getting info by system")
+ info, caps := a.collect.GatherInfoSystem()
+ a.log.Debug().Msg("create request data for register agent")
+ AgentID := a.settings.GetAgentID()
+ AgentName := a.cfg.AppName
+ AgentData := domain.RegisterAgentRequest{
+ AgentID: AgentID,
+ AgentName: AgentName,
+ Host: info,
+ Capabilities: caps,
+ AgentVersion: a.cfg.GetAgentVersion(),
+ }
+
+ data, err := a.conn.RegisterAgent(ctx, AgentData)
+ if err != nil {
+ return fmt.Errorf("register agent: %w", err)
+ }
+
+ if err = a.settings.InsertAgentID(data.AgentID); err != nil {
+ return fmt.Errorf("save agent ID: %w", err)
+ }
+ a.log.Info().Str("agentID", data.AgentID).Msg("agent registration end")
+
+ return nil
+}
diff --git a/agent/internal/service/agent_service/agent_test.go b/agent/internal/service/agent_service/agent_test.go
new file mode 100644
index 0000000..a229c03
--- /dev/null
+++ b/agent/internal/service/agent_service/agent_test.go
@@ -0,0 +1,109 @@
+package agent_service
+
+import (
+ "context"
+ "errors"
+ "testing"
+
+ "github.com/lorsanstand/HomeOps-Hub/agent/internal/utils/config_yaml"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
+ "github.com/rs/zerolog"
+)
+
+type CollectorMock struct {
+ host domain.HostInfo
+ caps []domain.Capability
+}
+
+func (c *CollectorMock) GatherInfoSystem() (domain.HostInfo, []domain.Capability) {
+ return c.host, c.caps
+}
+
+type ConnectionMock struct {
+ regAgentErr error
+ regResp domain.RegisterAgentResponse
+ regData domain.RegisterAgentRequest
+}
+
+func (c *ConnectionMock) RegisterAgent(ctx context.Context, RegisterData domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error) {
+ c.regData = RegisterData
+ return c.regResp, c.regAgentErr
+}
+
+type SettingsMock struct {
+ insertErr error
+ agentID string
+ countUse int
+}
+
+func (s *SettingsMock) InsertAgentID(agentID string) error {
+ s.agentID = agentID
+ s.countUse++
+ return s.insertErr
+}
+
+func (s *SettingsMock) GetAgentID() string {
+ return s.agentID
+}
+
+func TestAgentService_RegisterAgentConn(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ wantErr error
+ insertAgentIDUse int
+ settings SettingsMock
+ collector CollectorMock
+ conn ConnectionMock
+ cfg config_yaml.AgentConfig
+ }{
+ {
+ name: "success",
+ wantErr: nil,
+ insertAgentIDUse: 1,
+ settings: SettingsMock{agentID: "", insertErr: nil},
+ collector: CollectorMock{
+ host: domain.HostInfo{System: "Linux", Hostname: "test", Arch: "x64"},
+ caps: []domain.Capability{
+ {Available: true, Version: "0", Name: "testCaps", Reason: ""},
+ },
+ },
+ conn: ConnectionMock{regAgentErr: nil, regResp: domain.RegisterAgentResponse{AgentID: "123", Heartbeat: 4}},
+ cfg: config_yaml.AgentConfig{AppName: "test"},
+ },
+ }
+
+ for _, tt := range tests {
+ tt := tt
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ ctx := context.Background()
+
+ svc := NewAgentService(&tt.collector,
+ &tt.conn,
+ &tt.settings,
+ &tt.cfg,
+ zerolog.New(nil),
+ )
+
+ err := svc.RegisterAgentConn(ctx)
+ if !errors.Is(err, tt.wantErr) {
+ t.Fatalf("expected error %v, got: %v", tt.wantErr, err)
+ }
+
+ if tt.insertAgentIDUse != tt.settings.countUse {
+ t.Errorf("expected count insert agent id %v, got: %v", tt.insertAgentIDUse, tt.settings.countUse)
+ }
+
+ if tt.settings.agentID != tt.conn.regResp.AgentID {
+ t.Errorf("expected insert agent id %v, got: %v", tt.conn.regResp.AgentID, tt.settings.agentID)
+ }
+
+ if tt.cfg.AppName != tt.conn.regData.AgentName {
+ t.Fatalf("expected agent name %v, got: %v", tt.cfg.AppName, tt.conn.regData.AgentName)
+ }
+
+ })
+ }
+}
diff --git a/internal/agent/service/collector/collector.go b/agent/internal/service/collector/collector.go
similarity index 84%
rename from internal/agent/service/collector/collector.go
rename to agent/internal/service/collector/collector.go
index 93cea10..e0351ed 100644
--- a/internal/agent/service/collector/collector.go
+++ b/agent/internal/service/collector/collector.go
@@ -4,7 +4,7 @@ import (
"os"
"runtime"
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
"github.com/rs/zerolog"
)
@@ -18,7 +18,7 @@ type Collector struct {
}
func NewCollector(docker Docker, logger zerolog.Logger) *Collector {
- logger = logger.With().Str("component", "agent.service.collector").Logger()
+ logger = logger.With().Str("component", "internal.service.collector").Logger()
return &Collector{log: logger, dockerReader: docker}
}
diff --git a/internal/agent/service/docker_service/bad.go b/agent/internal/service/docker_service/bad.go
similarity index 85%
rename from internal/agent/service/docker_service/bad.go
rename to agent/internal/service/docker_service/bad.go
index 6c48587..ed02d48 100644
--- a/internal/agent/service/docker_service/bad.go
+++ b/agent/internal/service/docker_service/bad.go
@@ -1,7 +1,7 @@
package docker_service
import (
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
)
type BadDocker struct {
diff --git a/internal/agent/service/docker_service/docker.go b/agent/internal/service/docker_service/docker.go
similarity index 86%
rename from internal/agent/service/docker_service/docker.go
rename to agent/internal/service/docker_service/docker.go
index 487b1e1..825878c 100644
--- a/internal/agent/service/docker_service/docker.go
+++ b/agent/internal/service/docker_service/docker.go
@@ -5,7 +5,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
"github.com/rs/zerolog"
)
@@ -23,13 +23,13 @@ type DockerService struct {
func NewDockerService(api dockerAPI, logger zerolog.Logger) *DockerService {
return &DockerService{
dockerClient: api,
- log: logger.With().Str("component", "agent.serivce.docker").Logger(),
+ log: logger.With().Str("component", "internal.serivce.docker").Logger(),
}
}
func (d *DockerService) CheckDockerDaemon(ctx context.Context) error {
_, err := d.dockerClient.Ping(ctx)
- d.log.Debug().Msg("check docker")
+ d.log.Debug().Msg("ping docker")
return err
}
diff --git a/internal/agent/service/docker_service/docker_test.go b/agent/internal/service/docker_service/docker_test.go
similarity index 94%
rename from internal/agent/service/docker_service/docker_test.go
rename to agent/internal/service/docker_service/docker_test.go
index 25db239..c7b4170 100644
--- a/internal/agent/service/docker_service/docker_test.go
+++ b/agent/internal/service/docker_service/docker_test.go
@@ -10,7 +10,7 @@ import (
"github.com/rs/zerolog"
)
-var testError error = errors.New("test")
+var errTest error = errors.New("test")
type DockerMock struct {
pingErr error
@@ -46,11 +46,11 @@ func TestCheckDockerDaemon(t *testing.T) {
{
name: "docker error",
mock: DockerMock{
- pingErr: testError,
+ pingErr: errTest,
containers: nil,
containerErr: nil,
},
- wantErr: testError,
+ wantErr: errTest,
},
}
@@ -98,10 +98,10 @@ func TestContainersList(t *testing.T) {
mock: DockerMock{
pingErr: nil,
containers: nil,
- containerErr: testError,
+ containerErr: errTest,
},
wantLen: 0,
- wantErr: testError,
+ wantErr: errTest,
},
{
name: "docker empty container",
diff --git a/internal/agent/utils/config_yaml/config.go b/agent/internal/utils/config_yaml/config.go
similarity index 83%
rename from internal/agent/utils/config_yaml/config.go
rename to agent/internal/utils/config_yaml/config.go
index 9d24106..f8d4b1b 100644
--- a/internal/agent/utils/config_yaml/config.go
+++ b/agent/internal/utils/config_yaml/config.go
@@ -8,6 +8,9 @@ import (
"gopkg.in/yaml.v3"
)
+const MODE = "DEV"
+const AgentVersion = "0.0"
+
type AgentConfig struct {
AppName string `yaml:"app_name"`
HubConnect struct {
@@ -19,7 +22,7 @@ type AgentConfig struct {
}
func NewConfig() (*AgentConfig, error) {
- yamlFile, err := os.ReadFile("agent.dev.yaml")
+ yamlFile, err := os.ReadFile("config.yaml")
if err != nil {
return nil, fmt.Errorf("failed open file: %v", err)
}
@@ -42,7 +45,11 @@ func (c *AgentConfig) GetLogLevel() zerolog.Level {
}
func (c *AgentConfig) GetMode() string {
- return "DEV"
+ return MODE
+}
+
+func (c *AgentConfig) GetAgentVersion() string {
+ return AgentVersion
}
func (c *AgentConfig) GetGRPCAddress() string {
diff --git a/internal/agent/utils/config_yaml/config_yaml_test.go b/agent/internal/utils/config_yaml/config_yaml_test.go
similarity index 100%
rename from internal/agent/utils/config_yaml/config_yaml_test.go
rename to agent/internal/utils/config_yaml/config_yaml_test.go
diff --git a/internal/agent/utils/settings/settings.go b/agent/internal/utils/settings/settings.go
similarity index 69%
rename from internal/agent/utils/settings/settings.go
rename to agent/internal/utils/settings/settings.go
index 1632780..35d7418 100644
--- a/internal/agent/utils/settings/settings.go
+++ b/agent/internal/utils/settings/settings.go
@@ -13,7 +13,7 @@ type Settings struct {
path string
}
-func ReadSettings(path string) (*Settings, error) {
+func ReadSettings(path string) (sett *Settings, err error) {
if path == "" {
homeDir, err := os.UserHomeDir()
if err != nil {
@@ -22,7 +22,7 @@ func ReadSettings(path string) (*Settings, error) {
path = filepath.Join(homeDir, ".config", "homeops")
}
- err := os.Mkdir(path, 0755)
+ err = os.Mkdir(path, 0755)
if err != nil {
if !errors.Is(err, os.ErrExist) {
return nil, err
@@ -39,7 +39,12 @@ func ReadSettings(path string) (*Settings, error) {
return nil, err
}
} else {
- defer file.Close()
+ defer func() {
+ closeErr := file.Close()
+ if err == nil {
+ err = closeErr
+ }
+ }()
err = json.NewDecoder(file).Decode(&settings)
if err != nil && !errors.Is(err, io.EOF) {
return nil, err
@@ -51,12 +56,19 @@ func ReadSettings(path string) (*Settings, error) {
return &settings, nil
}
-func (s *Settings) Insert(sett Settings) error {
+func (s *Settings) InsertAgentID(agentID string) (err error) {
file, err := os.OpenFile(s.path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return err
}
- defer file.Close()
+ defer func() {
+ closeErr := file.Close()
+ if err == nil {
+ err = closeErr
+ }
+ }()
+
+ sett := Settings{AgentID: agentID}
if err = json.NewEncoder(file).Encode(sett); err != nil {
return err
@@ -64,3 +76,7 @@ func (s *Settings) Insert(sett Settings) error {
return nil
}
+
+func (s *Settings) GetAgentID() string {
+ return s.AgentID
+}
diff --git a/api/gen/homeops/hub.pb.go b/api/gen/homeops/hub.pb.go
index 284f28c..03f9fcc 100644
--- a/api/gen/homeops/hub.pb.go
+++ b/api/gen/homeops/hub.pb.go
@@ -322,6 +322,436 @@ func (x *RegisterAgentResponse) GetAgentId() string {
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 = "" +
@@ -350,10 +780,49 @@ const file_homeops_hub_proto_rawDesc = "" +
"\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\aagentId2x\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" +
"\x03Hub\x12/\n" +
"\x04Ping\x12\x16.google.protobuf.Empty\x1a\r.PongResponse\"\x00\x12@\n" +
- "\rRegisterAgent\x12\x15.RegisterAgentRequest\x1a\x16.RegisterAgentResponse\"\x00B HostInfo
- 3, // 1: RegisterAgentRequest.capability:type_name -> Capability
- 5, // 2: Hub.Ping:input_type -> google.protobuf.Empty
- 1, // 3: Hub.RegisterAgent:input_type -> RegisterAgentRequest
- 0, // 4: Hub.Ping:output_type -> PongResponse
- 4, // 5: Hub.RegisterAgent:output_type -> RegisterAgentResponse
- 4, // [4:6] is the sub-list for method output_type
- 2, // [2:4] is the sub-list for method input_type
- 2, // [2:2] is the sub-list for extension type_name
- 2, // [2:2] is the sub-list for extension extendee
- 0, // [0:2] is the sub-list for field type_name
+ 2, // 0: RegisterAgentRequest.host:type_name -> 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
}
func init() { file_homeops_hub_proto_init() }
@@ -395,13 +878,18 @@ 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),
+ }
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: 5,
+ NumMessages: 12,
NumExtensions: 0,
NumServices: 1,
},
diff --git a/api/gen/homeops/hub_grpc.pb.go b/api/gen/homeops/hub_grpc.pb.go
index e032d6c..d689399 100644
--- a/api/gen/homeops/hub_grpc.pb.go
+++ b/api/gen/homeops/hub_grpc.pb.go
@@ -20,8 +20,9 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
- Hub_Ping_FullMethodName = "/Hub/Ping"
- Hub_RegisterAgent_FullMethodName = "/Hub/RegisterAgent"
+ Hub_Ping_FullMethodName = "/Hub/Ping"
+ Hub_RegisterAgent_FullMethodName = "/Hub/RegisterAgent"
+ Hub_StreamConnection_FullMethodName = "/Hub/StreamConnection"
)
// HubClient is the client API for Hub service.
@@ -30,6 +31,7 @@ const (
type HubClient interface {
Ping(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PongResponse, error)
RegisterAgent(ctx context.Context, in *RegisterAgentRequest, opts ...grpc.CallOption) (*RegisterAgentResponse, error)
+ StreamConnection(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[AgentEvent, ServerCommandRequest], error)
}
type hubClient struct {
@@ -60,12 +62,26 @@ func (c *hubClient) RegisterAgent(ctx context.Context, in *RegisterAgentRequest,
return out, nil
}
+func (c *hubClient) StreamConnection(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[AgentEvent, ServerCommandRequest], error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ stream, err := c.cc.NewStream(ctx, &Hub_ServiceDesc.Streams[0], Hub_StreamConnection_FullMethodName, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpc.GenericClientStream[AgentEvent, ServerCommandRequest]{ClientStream: stream}
+ return x, nil
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type Hub_StreamConnectionClient = grpc.BidiStreamingClient[AgentEvent, ServerCommandRequest]
+
// HubServer is the server API for Hub service.
// All implementations must embed UnimplementedHubServer
// for forward compatibility.
type HubServer interface {
Ping(context.Context, *emptypb.Empty) (*PongResponse, error)
RegisterAgent(context.Context, *RegisterAgentRequest) (*RegisterAgentResponse, error)
+ StreamConnection(grpc.BidiStreamingServer[AgentEvent, ServerCommandRequest]) error
mustEmbedUnimplementedHubServer()
}
@@ -82,6 +98,9 @@ func (UnimplementedHubServer) Ping(context.Context, *emptypb.Empty) (*PongRespon
func (UnimplementedHubServer) RegisterAgent(context.Context, *RegisterAgentRequest) (*RegisterAgentResponse, error) {
return nil, status.Error(codes.Unimplemented, "method RegisterAgent not implemented")
}
+func (UnimplementedHubServer) StreamConnection(grpc.BidiStreamingServer[AgentEvent, ServerCommandRequest]) error {
+ return status.Error(codes.Unimplemented, "method StreamConnection not implemented")
+}
func (UnimplementedHubServer) mustEmbedUnimplementedHubServer() {}
func (UnimplementedHubServer) testEmbeddedByValue() {}
@@ -139,6 +158,13 @@ func _Hub_RegisterAgent_Handler(srv interface{}, ctx context.Context, dec func(i
return interceptor(ctx, in, info, handler)
}
+func _Hub_StreamConnection_Handler(srv interface{}, stream grpc.ServerStream) error {
+ return srv.(HubServer).StreamConnection(&grpc.GenericServerStream[AgentEvent, ServerCommandRequest]{ServerStream: stream})
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type Hub_StreamConnectionServer = grpc.BidiStreamingServer[AgentEvent, ServerCommandRequest]
+
// Hub_ServiceDesc is the grpc.ServiceDesc for Hub service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -155,6 +181,13 @@ var Hub_ServiceDesc = grpc.ServiceDesc{
Handler: _Hub_RegisterAgent_Handler,
},
},
- Streams: []grpc.StreamDesc{},
+ Streams: []grpc.StreamDesc{
+ {
+ StreamName: "StreamConnection",
+ Handler: _Hub_StreamConnection_Handler,
+ ServerStreams: true,
+ ClientStreams: true,
+ },
+ },
Metadata: "homeops/hub.proto",
}
diff --git a/api/proto/homeops/hub.proto b/api/proto/homeops/hub.proto
index e7f32d9..301b992 100644
--- a/api/proto/homeops/hub.proto
+++ b/api/proto/homeops/hub.proto
@@ -7,6 +7,7 @@ option go_package = "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops;homeops"
service Hub {
rpc Ping (google.protobuf.Empty) returns (PongResponse) {}
rpc RegisterAgent (RegisterAgentRequest) returns (RegisterAgentResponse) {}
+ rpc StreamConnection (stream AgentEvent) returns (stream ServerCommandRequest) {}
}
message PongResponse {
@@ -37,4 +38,47 @@ message Capability {
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/cmd/telegram/main.go b/cmd/telegram/main.go
deleted file mode 100644
index 06ab7d0..0000000
--- a/cmd/telegram/main.go
+++ /dev/null
@@ -1 +0,0 @@
-package main
diff --git a/cmd/hub/main.go b/hub/cmd/main.go
similarity index 50%
rename from cmd/hub/main.go
rename to hub/cmd/main.go
index afc06ec..5e2033c 100644
--- a/cmd/hub/main.go
+++ b/hub/cmd/main.go
@@ -1,6 +1,8 @@
package main
-import "github.com/lorsanstand/HomeOps-Hub/internal/hub/app"
+import (
+ "github.com/lorsanstand/HomeOps-Hub/hub/internal/app"
+)
func main() {
start := app.NewApp()
diff --git a/internal/hub/app/app.go b/hub/internal/app/app.go
similarity index 80%
rename from internal/hub/app/app.go
rename to hub/internal/app/app.go
index 56652b0..c1db0e3 100644
--- a/internal/hub/app/app.go
+++ b/hub/internal/app/app.go
@@ -8,13 +8,13 @@ import (
"net"
"github.com/jackc/pgx/v5/pgxpool"
- hubdir "github.com/lorsanstand/HomeOps-Hub/internal/hub"
- "github.com/lorsanstand/HomeOps-Hub/internal/hub/migrator"
- grpcserv "github.com/lorsanstand/HomeOps-Hub/internal/hub/rpc"
- "github.com/lorsanstand/HomeOps-Hub/internal/hub/service/hub_service"
- "github.com/lorsanstand/HomeOps-Hub/internal/hub/store"
- "github.com/lorsanstand/HomeOps-Hub/internal/shared/config"
- "github.com/lorsanstand/HomeOps-Hub/internal/shared/log"
+ hubdir "github.com/lorsanstand/HomeOps-Hub/hub/internal"
+ "github.com/lorsanstand/HomeOps-Hub/hub/internal/migrator"
+ grpcserv "github.com/lorsanstand/HomeOps-Hub/hub/internal/rpc"
+ "github.com/lorsanstand/HomeOps-Hub/hub/internal/service/hub_service"
+ "github.com/lorsanstand/HomeOps-Hub/hub/internal/store"
+ "github.com/lorsanstand/HomeOps-Hub/shared/config"
+ "github.com/lorsanstand/HomeOps-Hub/shared/log"
"github.com/rs/zerolog"
)
@@ -27,6 +27,7 @@ func NewApp() *App {
cfg, err := config.NewConfig()
if err != nil {
standartlog.Fatalf("failed get config: %v", err)
+ return nil
}
logger := log.NewLogger(cfg)
@@ -42,7 +43,6 @@ func (a *App) Run() {
a.log.Error().Err(err).Msg("failed to connect to the database for migrations")
return
}
- defer migratePGConn.Close()
mgrt, err := migrator.NewMigrator(hubdir.MigrationsFS, "migrations")
if err != nil {
@@ -56,7 +56,9 @@ func (a *App) Run() {
return
}
a.log.Info().Msg("migrations applied successfully")
- migratePGConn.Close()
+ if err := migratePGConn.Close(); err != nil {
+ a.log.Warn().Err(err).Msg("failed to close migrate postgres connection")
+ }
a.log.Info().Msg("creating database connection pool")
pool, err := pgxpool.New(ctx, a.cfg.GetURLPostgres())
@@ -80,7 +82,6 @@ func (a *App) Run() {
func (a *App) hubServe(hubService *hub_service.HubService) error {
address := fmt.Sprintf("0.0.0.0:%v", a.cfg.Port)
- a.log.Info().Str("address", address).Msg("starting gRPC server")
server := grpcserv.NewHubHandler(hubService, a.log)
diff --git a/internal/hub/domain/structure.go b/hub/internal/domain/structure.go
similarity index 89%
rename from internal/hub/domain/structure.go
rename to hub/internal/domain/structure.go
index 795fe89..79bea4a 100644
--- a/internal/hub/domain/structure.go
+++ b/hub/internal/domain/structure.go
@@ -3,7 +3,7 @@ package domain
import (
"time"
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
)
type CreateAgentModel struct {
diff --git a/internal/hub/embed.go b/hub/internal/embed.go
similarity index 80%
rename from internal/hub/embed.go
rename to hub/internal/embed.go
index 1938b80..e4740ca 100644
--- a/internal/hub/embed.go
+++ b/hub/internal/embed.go
@@ -1,4 +1,4 @@
-package hub
+package internal
import "embed"
diff --git a/internal/hub/migrations/20260415151037_create_agent_table.down.sql b/hub/internal/migrations/20260415151037_create_agent_table.down.sql
similarity index 100%
rename from internal/hub/migrations/20260415151037_create_agent_table.down.sql
rename to hub/internal/migrations/20260415151037_create_agent_table.down.sql
diff --git a/internal/hub/migrations/20260415151037_create_agent_table.up.sql b/hub/internal/migrations/20260415151037_create_agent_table.up.sql
similarity index 100%
rename from internal/hub/migrations/20260415151037_create_agent_table.up.sql
rename to hub/internal/migrations/20260415151037_create_agent_table.up.sql
diff --git a/internal/hub/migrator/migrator.go b/hub/internal/migrator/migrator.go
similarity index 87%
rename from internal/hub/migrator/migrator.go
rename to hub/internal/migrator/migrator.go
index 22338f8..159bd8e 100644
--- a/internal/hub/migrator/migrator.go
+++ b/hub/internal/migrator/migrator.go
@@ -5,6 +5,7 @@ import (
"embed"
"errors"
"fmt"
+
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/golang-migrate/migrate/v4"
@@ -25,7 +26,7 @@ func NewMigrator(sqlFiles embed.FS, dirname string) (*Migrator, error) {
return &Migrator{srcDriver: d}, nil
}
-func (m *Migrator) ApplyMigrations(db *sql.DB) error {
+func (m *Migrator) ApplyMigrations(db *sql.DB) (err error) {
driver, err := postgres.WithInstance(db, &postgres.Config{})
if err != nil {
return fmt.Errorf("unable to create db instance: %w", err)
@@ -36,7 +37,12 @@ func (m *Migrator) ApplyMigrations(db *sql.DB) error {
return fmt.Errorf("unable to create migration: %w", err)
}
- defer migrator.Close()
+ defer func() {
+ closeErr, _ := migrator.Close()
+ if err == nil {
+ err = closeErr
+ }
+ }()
if err = migrator.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
return fmt.Errorf("unable to apply migrations: %w", err)
diff --git a/internal/hub/rpc/server.go b/hub/internal/rpc/server.go
similarity index 83%
rename from internal/hub/rpc/server.go
rename to hub/internal/rpc/server.go
index 1a5aade..d9de289 100644
--- a/internal/hub/rpc/server.go
+++ b/hub/internal/rpc/server.go
@@ -4,7 +4,7 @@ import (
"context"
pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops"
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
"github.com/rs/zerolog"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/emptypb"
@@ -38,13 +38,13 @@ 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")
+ h.log.Debug().Str("agentID", request.AgentId).Str("agentName", request.AgentName).Msg("register agent request received")
data := domain.ToDomainAgentRequest(request)
resp, err := h.hub.RegisterAgent(ctx, data)
if err != nil {
- h.log.Error().Err(err).Str("agentId", request.AgentId).Msg("register agent request failed")
+ h.log.Error().Err(err).Str("agentID", request.AgentId).Msg("register agent request failed")
return domain.ToGRPCAgentResponse(resp), err
}
- h.log.Debug().Str("agentId", resp.AgentID).Msg("register agent request completed")
+ h.log.Info().Str("agentID", resp.AgentID).Msg("register agent request completed")
return domain.ToGRPCAgentResponse(resp), nil
}
diff --git a/internal/hub/service/hub_service/hub.go b/hub/internal/service/hub_service/hub.go
similarity index 51%
rename from internal/hub/service/hub_service/hub.go
rename to hub/internal/service/hub_service/hub.go
index aa86b1a..00d7181 100644
--- a/internal/hub/service/hub_service/hub.go
+++ b/hub/internal/service/hub_service/hub.go
@@ -6,12 +6,14 @@ import (
"errors"
"fmt"
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
- domainHub "github.com/lorsanstand/HomeOps-Hub/internal/hub/domain"
- "github.com/lorsanstand/HomeOps-Hub/internal/hub/utils/hasher"
+ domainHub "github.com/lorsanstand/HomeOps-Hub/hub/internal/domain"
+ "github.com/lorsanstand/HomeOps-Hub/hub/internal/utils/hasher"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
"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)
@@ -28,43 +30,37 @@ func NewHubService(store Store, logger zerolog.Logger) *HubService {
}
func (h *HubService) RegisterAgent(ctx context.Context, data domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error) {
- h.log.Debug().Str("agentId", data.AgentId).Str("agentName", data.AgentName).Msg("started registering agent")
- agent, err := h.store.GetAgentByAgentID(ctx, data.AgentId)
+ h.log.Debug().Str("agentID", data.AgentID).Str("agentName", data.AgentName).Msg("started registering agent")
+ agent, err := h.store.GetAgentByAgentID(ctx, data.AgentID)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
- h.log.Error().Err(err).Str("agentId", data.AgentId).Msg("failed to get agent from database")
return domain.RegisterAgentResponse{}, fmt.Errorf("failed select agent to db: %w", err)
}
- if data.AgentId != "" && !errors.Is(err, sql.ErrNoRows) {
- h.log.Debug().Str("agentId", agent.AgentID).Str("agentName", data.AgentName).Msg("agent exists, updating")
+ if data.AgentID != "" && !errors.Is(err, sql.ErrNoRows) {
+ h.log.Debug().Str("agentID", agent.AgentID).Str("agentName", data.AgentName).Msg("agent exists, updating")
- data.AgentId = agent.AgentID
+ data.AgentID = agent.AgentID
agentStore := toCreateAgentModel(data)
if err := h.store.UpdateAgentByID(ctx, agent.ID, agentStore); err != nil {
- h.log.Error().Err(err).Str("agentId", agent.AgentID).Msg("failed to update agent in database")
- return domain.RegisterAgentResponse{}, err
+ return domain.RegisterAgentResponse{}, fmt.Errorf("update agent in db: %w", err)
}
- h.log.Info().Str("agentId", agent.AgentID).Msg("agent updated successfully")
- return domain.RegisterAgentResponse{AgentID: agent.AgentID, Heartbeat: 5}, nil
+ h.log.Debug().Str("agentId", agent.AgentID).Msg("agent updated successfully")
+ return domain.RegisterAgentResponse{AgentID: agent.AgentID, Heartbeat: HEARTBEAT}, nil
}
AgentID, err := hasher.MakeID(data.Host, data.AgentName)
if err != nil {
- h.log.Error().Err(err).Str("agentName", data.AgentName).Str("hostname", data.Host.Hostname).Msg("failed to generate agent id")
- return domain.RegisterAgentResponse{}, err
+ return domain.RegisterAgentResponse{}, fmt.Errorf("generate agent ID: %w", err)
}
- data.AgentId = AgentID
+ data.AgentID = AgentID
agentStore := toCreateAgentModel(data)
if err := h.store.NewAgent(ctx, agentStore); err != nil {
- h.log.Error().Err(err).Str("agentId", AgentID).Str("agentName", data.AgentName).Msg("failed to create new agent in database")
- return domain.RegisterAgentResponse{}, err
+ return domain.RegisterAgentResponse{}, fmt.Errorf("insert new agent: %w", err)
}
-
- h.log.Info().Str("agentId", AgentID).Str("agentName", data.AgentName).Str("hostname", data.Host.Hostname).Msg("agent registered successfully")
- return domain.RegisterAgentResponse{AgentID: AgentID, Heartbeat: 5}, nil
+ return domain.RegisterAgentResponse{AgentID: AgentID, Heartbeat: HEARTBEAT}, nil
}
diff --git a/internal/hub/service/hub_service/mapper.go b/hub/internal/service/hub_service/mapper.go
similarity index 71%
rename from internal/hub/service/hub_service/mapper.go
rename to hub/internal/service/hub_service/mapper.go
index 6a020d8..9013dab 100644
--- a/internal/hub/service/hub_service/mapper.go
+++ b/hub/internal/service/hub_service/mapper.go
@@ -1,13 +1,13 @@
package hub_service
import (
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
- domainHub "github.com/lorsanstand/HomeOps-Hub/internal/hub/domain"
+ domainHub "github.com/lorsanstand/HomeOps-Hub/hub/internal/domain"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
)
func toCreateAgentModel(agent domain.RegisterAgentRequest) domainHub.CreateAgentModel {
return domainHub.CreateAgentModel{
- AgentID: agent.AgentId,
+ AgentID: agent.AgentID,
AgentName: agent.AgentName,
Architecture: agent.Host.Arch,
System: agent.Host.System,
diff --git a/internal/hub/store/mapper.go b/hub/internal/store/mapper.go
similarity index 66%
rename from internal/hub/store/mapper.go
rename to hub/internal/store/mapper.go
index cbce0c3..b843735 100644
--- a/internal/hub/store/mapper.go
+++ b/hub/internal/store/mapper.go
@@ -3,36 +3,36 @@ package store
import (
"encoding/json"
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
- domainHub "github.com/lorsanstand/HomeOps-Hub/internal/hub/domain"
- "github.com/lorsanstand/HomeOps-Hub/internal/hub/store/sqlc/gen"
+ domainHub "github.com/lorsanstand/HomeOps-Hub/hub/internal/domain"
+ gen2 "github.com/lorsanstand/HomeOps-Hub/hub/internal/store/sqlc/gen"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
)
-func toDBAgent(agent domainHub.CreateAgentModel) gen.CreateAgentParams {
- return gen.CreateAgentParams{
+func toDBAgent(agent domainHub.CreateAgentModel) gen2.CreateAgentParams {
+ return gen2.CreateAgentParams{
AgentID: agent.AgentID,
AgentName: &agent.AgentName,
Architecture: agent.Architecture,
System: agent.System,
Hostname: agent.Hostname,
Version: agent.Version,
- Capabilities: toJsonCapabilities(agent.Capabilities),
+ Capabilities: toJSONCapabilities(agent.Capabilities),
}
}
-func toUpdateDBAgent(agent domainHub.CreateAgentModel) gen.UpdateAgentByIDParams {
- return gen.UpdateAgentByIDParams{
+func toUpdateDBAgent(agent domainHub.CreateAgentModel) gen2.UpdateAgentByIDParams {
+ return gen2.UpdateAgentByIDParams{
AgentID: agent.AgentID,
AgentName: &agent.AgentName,
Architecture: agent.Architecture,
System: agent.System,
Hostname: agent.Hostname,
Version: agent.Version,
- Capabilities: toJsonCapabilities(agent.Capabilities),
+ Capabilities: toJSONCapabilities(agent.Capabilities),
}
}
-func toJsonCapabilities(caps []domain.Capability) []byte {
+func toJSONCapabilities(caps []domain.Capability) []byte {
data, err := json.Marshal(caps)
if err != nil {
// Note: Error is silently handled - consider logging in production
@@ -41,7 +41,7 @@ func toJsonCapabilities(caps []domain.Capability) []byte {
return data
}
-func toAgentModel(dbAgent gen.Agent) domainHub.AgentModel {
+func toAgentModel(dbAgent gen2.Agent) domainHub.AgentModel {
var dbAgentName string
if dbAgent.AgentName != nil {
dbAgentName = *dbAgent.AgentName
diff --git a/internal/hub/store/sqlc/gen/agent.sql.go b/hub/internal/store/sqlc/gen/agent.sql.go
similarity index 99%
rename from internal/hub/store/sqlc/gen/agent.sql.go
rename to hub/internal/store/sqlc/gen/agent.sql.go
index 6a6e23c..3d55d93 100644
--- a/internal/hub/store/sqlc/gen/agent.sql.go
+++ b/hub/internal/store/sqlc/gen/agent.sql.go
@@ -1,7 +1,7 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
-// source: agent.sql
+// source: cmd.sql
package gen
diff --git a/internal/hub/store/sqlc/gen/db.go b/hub/internal/store/sqlc/gen/db.go
similarity index 100%
rename from internal/hub/store/sqlc/gen/db.go
rename to hub/internal/store/sqlc/gen/db.go
diff --git a/internal/hub/store/sqlc/gen/models.go b/hub/internal/store/sqlc/gen/models.go
similarity index 100%
rename from internal/hub/store/sqlc/gen/models.go
rename to hub/internal/store/sqlc/gen/models.go
diff --git a/internal/hub/store/sqlc/queries/agent.sql b/hub/internal/store/sqlc/queries/agent.sql
similarity index 100%
rename from internal/hub/store/sqlc/queries/agent.sql
rename to hub/internal/store/sqlc/queries/agent.sql
diff --git a/internal/hub/store/store.go b/hub/internal/store/store.go
similarity index 86%
rename from internal/hub/store/store.go
rename to hub/internal/store/store.go
index 02936d4..851eec9 100644
--- a/internal/hub/store/store.go
+++ b/hub/internal/store/store.go
@@ -4,8 +4,8 @@ import (
"context"
"github.com/jackc/pgx/v5/pgxpool"
- domainHub "github.com/lorsanstand/HomeOps-Hub/internal/hub/domain"
- "github.com/lorsanstand/HomeOps-Hub/internal/hub/store/sqlc/gen"
+ domainHub "github.com/lorsanstand/HomeOps-Hub/hub/internal/domain"
+ "github.com/lorsanstand/HomeOps-Hub/hub/internal/store/sqlc/gen"
)
type HubStore struct {
diff --git a/internal/hub/utils/hasher/id.go b/hub/internal/utils/hasher/id.go
similarity index 90%
rename from internal/hub/utils/hasher/id.go
rename to hub/internal/utils/hasher/id.go
index e28b504..21f94f8 100644
--- a/internal/hub/utils/hasher/id.go
+++ b/hub/internal/utils/hasher/id.go
@@ -6,7 +6,7 @@ import (
"encoding/hex"
"fmt"
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
+ "github.com/lorsanstand/HomeOps-Hub/shared/domain"
)
func newSalt(n int) ([]byte, error) {
diff --git a/internal/agent/service/agent_service/agent.go b/internal/agent/service/agent_service/agent.go
deleted file mode 100644
index af9f050..0000000
--- a/internal/agent/service/agent_service/agent.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package agent_service
-
-import (
- "context"
- "fmt"
-
- "github.com/lorsanstand/HomeOps-Hub/internal/agent/utils/config_yaml"
- "github.com/lorsanstand/HomeOps-Hub/internal/agent/utils/settings"
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
- "github.com/rs/zerolog"
-)
-
-const AgentVersion = "0.0"
-
-type Collector interface {
- GatherInfoSystem() (domain.HostInfo, []domain.Capability)
-}
-
-type HubConnection interface {
- RegisterAgent(ctx context.Context, RegisterData domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error)
-}
-
-type AgentService struct {
- collect Collector
- conn HubConnection
- log zerolog.Logger
- cfg *config_yaml.AgentConfig
- heartBeat int
- settings *settings.Settings
-}
-
-func NewAgentService(
- collector Collector,
- conn HubConnection,
- settings *settings.Settings,
- cfg *config_yaml.AgentConfig,
- logger zerolog.Logger,
-) *AgentService {
- logger = logger.With().Str("component", "agent.service.agent_serivce").Logger()
-
- return &AgentService{collect: collector, conn: conn, cfg: cfg, log: logger, settings: settings}
-}
-
-func (a *AgentService) RegisterAgentConn(ctx context.Context) {
- info, caps := a.collect.GatherInfoSystem()
- AgentID := a.settings.AgentID
- AgentName := a.cfg.AppName
- AgentData := domain.RegisterAgentRequest{AgentId: AgentID, AgentName: AgentName, Host: info, Capabilities: caps, AgentVersion: AgentVersion}
-
- data, err := a.conn.RegisterAgent(ctx, AgentData)
- if err != nil {
- a.log.Error().Err(err).Msg("failed register agent")
- return
- }
-
- if err = a.settings.Insert(settings.Settings{AgentID: data.AgentID}); err != nil {
- a.log.Warn().Err(err).Msg("failed to save agent id")
- }
- fmt.Println(data)
-}
diff --git a/internal/agent/service/agent_service/agent_test.go b/internal/agent/service/agent_service/agent_test.go
deleted file mode 100644
index b6852ac..0000000
--- a/internal/agent/service/agent_service/agent_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package agent_service
-
-import (
- "context"
-
- "github.com/lorsanstand/HomeOps-Hub/internal/domain"
-)
-
-type CollectorMock struct {
- host domain.HostInfo
- caps []domain.Capability
-}
-
-func (c *CollectorMock) GatherInfoSystem() (domain.HostInfo, []domain.Capability) {
- return c.host, c.caps
-}
-
-type ConnectionMock struct {
- regAgentErr error
- regResp domain.RegisterAgentResponse
-}
-
-func (c *ConnectionMock) RegisterAgent(ctx context.Context, RegisterData domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error) {
- return c.regResp, c.regAgentErr
-}
diff --git a/internal/shared/config/config.go b/shared/config/config.go
similarity index 100%
rename from internal/shared/config/config.go
rename to shared/config/config.go
diff --git a/internal/shared/config/config_test.go b/shared/config/config_test.go
similarity index 100%
rename from internal/shared/config/config_test.go
rename to shared/config/config_test.go
diff --git a/internal/domain/agent.go b/shared/domain/agent.go
similarity index 94%
rename from internal/domain/agent.go
rename to shared/domain/agent.go
index 8a5f062..2a24ae5 100644
--- a/internal/domain/agent.go
+++ b/shared/domain/agent.go
@@ -1,7 +1,7 @@
package domain
type RegisterAgentRequest struct {
- AgentId string
+ AgentID string
AgentName string
AgentVersion string
Host HostInfo
diff --git a/internal/domain/mapper.go b/shared/domain/mapper.go
similarity index 97%
rename from internal/domain/mapper.go
rename to shared/domain/mapper.go
index 2812e8e..587d361 100644
--- a/internal/domain/mapper.go
+++ b/shared/domain/mapper.go
@@ -10,7 +10,7 @@ func ToDomainAgentRequest(request *pb.RegisterAgentRequest) RegisterAgentRequest
}
return RegisterAgentRequest{
- AgentId: request.AgentId,
+ AgentID: request.AgentId,
AgentName: request.AgentName,
Host: HostInfo{
System: request.Host.System,
@@ -53,7 +53,7 @@ func ToDomainCapabilities(capability []*pb.Capability) []Capability {
func ToGRPCAgentRequest(request RegisterAgentRequest) pb.RegisterAgentRequest {
return pb.RegisterAgentRequest{
- AgentId: request.AgentId,
+ AgentId: request.AgentID,
AgentName: request.AgentName,
Host: &pb.HostInfo{
Hostname: request.Host.Hostname,
diff --git a/internal/shared/log/init.go b/shared/log/init.go
similarity index 100%
rename from internal/shared/log/init.go
rename to shared/log/init.go
diff --git a/sqlc.yaml b/sqlc.yaml
index 4e02b14..5c97fd8 100644
--- a/sqlc.yaml
+++ b/sqlc.yaml
@@ -2,11 +2,11 @@ version: "2"
sql:
- engine: "postgresql"
- queries: "internal/hub/store/sqlc/queries"
- schema: "./internal/hub/migrations/"
+ queries: "hub/internal/store/sqlc/queries"
+ schema: "./hub/internal/migrations/"
gen:
go:
sql_package: "pgx/v5"
package: "gen"
- out: "internal/hub/store/sqlc/gen"
+ out: "hub/internal/store/sqlc/gen"
emit_pointers_for_null_types: true
\ No newline at end of file