mirror of
https://github.com/lorsanstand/HomeOps-Hub.git
synced 2026-06-19 20:05:17 +03:00
feat: add register agent in db
This commit is contained in:
+18
-5
@@ -1,15 +1,18 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
standartlog "log"
|
||||
"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"
|
||||
"github.com/rs/zerolog"
|
||||
@@ -32,6 +35,7 @@ func NewApp() *App {
|
||||
}
|
||||
|
||||
func (a *App) Run() {
|
||||
ctx := context.Background()
|
||||
migratePGConn, err := sql.Open("pgx", a.cfg.GetURLPostgres())
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("failed to connect to the database")
|
||||
@@ -47,23 +51,32 @@ func (a *App) Run() {
|
||||
|
||||
if err = mgrt.ApplyMigrations(migratePGConn); err != nil {
|
||||
a.log.Error().Err(err).Msg("migrations were not applied")
|
||||
return
|
||||
}
|
||||
migratePGConn.Close()
|
||||
|
||||
err = a.hubServe()
|
||||
pool, err := pgxpool.New(ctx, a.cfg.GetURLPostgres())
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("failed create db pool")
|
||||
return
|
||||
}
|
||||
|
||||
hubStore := store.NewHubStore(pool)
|
||||
|
||||
hubService := hub_service.NewHubService(hubStore, a.log)
|
||||
|
||||
err = a.hubServe(hubService)
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("failed to start the server")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) hubServe() error {
|
||||
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", "http://"+address).Msg("start GRPC server")
|
||||
|
||||
hub := hub_service.NewHubService(a.log)
|
||||
|
||||
server := grpcserv.NewHubHandler(hub, a.log)
|
||||
server := grpcserv.NewHubHandler(hubService, a.log)
|
||||
|
||||
lis, err := net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
CREATE TABLE agents (
|
||||
id BIGINT UNIQUE PRIMARY KEY,
|
||||
id SERIAL PRIMARY KEY,
|
||||
agent_id VARCHAR(32) UNIQUE NOT NULL,
|
||||
agent_name VARCHAR(255),
|
||||
architecture VARCHAR(10) NOT NULL,
|
||||
@@ -10,5 +10,5 @@ CREATE TABLE agents (
|
||||
registered_at timestamp without time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_agent_id ON agent (id);
|
||||
CREATE UNIQUE INDEX idx_agent_id_id On agent (agent_id)
|
||||
CREATE UNIQUE INDEX idx_agent_id ON agents (id);
|
||||
CREATE UNIQUE INDEX idx_agent_id_id On agents (agent_id)
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
_ "github.com/jackc/pgx/v5/stdlib"
|
||||
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
"github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
type HubService interface {
|
||||
RegisterAgent(data domain.RegisterAgentRequest) domain.RegisterAgentResponse
|
||||
RegisterAgent(ctx context.Context, data domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error)
|
||||
}
|
||||
|
||||
type HubHandler struct {
|
||||
@@ -39,6 +39,6 @@ func (h *HubHandler) Ping(ctx context.Context, _ *emptypb.Empty) (*pb.PongRespon
|
||||
|
||||
func (h *HubHandler) RegisterAgent(ctx context.Context, request *pb.RegisterAgentRequest) (*pb.RegisterAgentResponse, error) {
|
||||
data := domain.ToDomainAgentRequest(request)
|
||||
resp := h.hub.RegisterAgent(data)
|
||||
return domain.ToGRPCAgentResponse(resp), nil
|
||||
resp, err := h.hub.RegisterAgent(ctx, data)
|
||||
return domain.ToGRPCAgentResponse(resp), err
|
||||
}
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
package hub_service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/store"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/utils/hasher"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
NewAgent(ctx context.Context, agent store.Agent) error
|
||||
}
|
||||
|
||||
type HubService struct {
|
||||
log zerolog.Logger
|
||||
store Store
|
||||
log zerolog.Logger
|
||||
}
|
||||
|
||||
func NewHubService(logger zerolog.Logger) *HubService {
|
||||
return &HubService{log: logger}
|
||||
func NewHubService(store Store, logger zerolog.Logger) *HubService {
|
||||
return &HubService{log: logger, store: store}
|
||||
}
|
||||
|
||||
func (h *HubService) RegisterAgent(data domain.RegisterAgentRequest) domain.RegisterAgentResponse {
|
||||
func (h *HubService) RegisterAgent(ctx context.Context, data domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error) {
|
||||
h.log.Debug().Msg("registered new agent")
|
||||
AgentID := data.AgentId
|
||||
if data.AgentId == "" {
|
||||
var err error
|
||||
@@ -25,5 +34,20 @@ func (h *HubService) RegisterAgent(data domain.RegisterAgentRequest) domain.Regi
|
||||
}
|
||||
}
|
||||
|
||||
return domain.RegisterAgentResponse{AgentID: AgentID, Heartbeat: 5}
|
||||
agentStore := store.Agent{
|
||||
AgentID: AgentID,
|
||||
AgentName: data.AgentName,
|
||||
Architecture: data.Host.Arch,
|
||||
System: data.Host.System,
|
||||
Hostname: data.Host.Hostname,
|
||||
Version: data.AgentVersion,
|
||||
Capabilities: data.Capabilities,
|
||||
}
|
||||
|
||||
if err := h.store.NewAgent(ctx, agentStore); err != nil {
|
||||
h.log.Warn().Err(err).Msg("failed add new agent in db")
|
||||
return domain.RegisterAgentResponse{}, err
|
||||
}
|
||||
|
||||
return domain.RegisterAgentResponse{AgentID: AgentID, Heartbeat: 5}, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: agent.sql
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const createAgent = `-- name: CreateAgent :exec
|
||||
INSERT INTO agents (agent_id, agent_name, architecture, system, hostname, version, capabilities)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
`
|
||||
|
||||
type CreateAgentParams struct {
|
||||
AgentID string
|
||||
AgentName *string
|
||||
Architecture string
|
||||
System string
|
||||
Hostname string
|
||||
Version string
|
||||
Capabilities []byte
|
||||
}
|
||||
|
||||
func (q *Queries) CreateAgent(ctx context.Context, arg CreateAgentParams) error {
|
||||
_, err := q.db.Exec(ctx, createAgent,
|
||||
arg.AgentID,
|
||||
arg.AgentName,
|
||||
arg.Architecture,
|
||||
arg.System,
|
||||
arg.Hostname,
|
||||
arg.Version,
|
||||
arg.Capabilities,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
|
||||
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
|
||||
QueryRow(context.Context, string, ...interface{}) pgx.Row
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
type Agent struct {
|
||||
ID int64
|
||||
AgentID string
|
||||
AgentName *string
|
||||
Architecture string
|
||||
System string
|
||||
Hostname string
|
||||
Version string
|
||||
Capabilities []byte
|
||||
RegisteredAt pgtype.Timestamp
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
-- name: CreateAgent :exec
|
||||
INSERT INTO agents (agent_id, agent_name, architecture, system, hostname, version, capabilities)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7);
|
||||
@@ -0,0 +1,21 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/store/sqlc/gen"
|
||||
)
|
||||
|
||||
type HubStore struct {
|
||||
queries *gen.Queries
|
||||
}
|
||||
|
||||
func NewHubStore(db *pgxpool.Pool) *HubStore {
|
||||
queries := gen.New(db)
|
||||
return &HubStore{queries}
|
||||
}
|
||||
|
||||
func (h *HubStore) NewAgent(ctx context.Context, agent Agent) error {
|
||||
return h.queries.CreateAgent(ctx, toDBAgent(agent))
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/store/sqlc/gen"
|
||||
)
|
||||
|
||||
type Agent struct {
|
||||
AgentID string
|
||||
AgentName string
|
||||
Architecture string
|
||||
System string
|
||||
Hostname string
|
||||
Version string
|
||||
Capabilities []domain.Capability
|
||||
}
|
||||
|
||||
func toDBAgent(agent Agent) gen.CreateAgentParams {
|
||||
return gen.CreateAgentParams{
|
||||
AgentID: agent.AgentID,
|
||||
AgentName: &agent.AgentName,
|
||||
Architecture: agent.Architecture,
|
||||
System: agent.System,
|
||||
Version: agent.Version,
|
||||
Capabilities: toJsonCapabilities(agent.Capabilities),
|
||||
}
|
||||
}
|
||||
|
||||
func toJsonCapabilities(caps []domain.Capability) []byte {
|
||||
data, err := json.Marshal(caps)
|
||||
if err != nil {
|
||||
return []byte{}
|
||||
}
|
||||
return data
|
||||
}
|
||||
Reference in New Issue
Block a user