diff --git a/agent/internal/grpc/client.go b/agent/internal/grpc/client.go index 3a00db3..f5e4746 100644 --- a/agent/internal/grpc/client.go +++ b/agent/internal/grpc/client.go @@ -126,6 +126,13 @@ func (c *Client) ReportUpdates(serverID, agentToken string, updates []pb.Package return err } +func (c *Client) ReportInventory(report *pb.InventoryReport) error { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + _, err := c.client.ReportInventory(ctx, report) + return err +} + // CommandStream opens a long-lived bidirectional stream for server-pushed commands. // The caller controls the stream lifetime via ctx. func (c *Client) CommandStream(ctx context.Context) (pb.Vantage_CommandStreamClient, error) { diff --git a/agent/internal/sync/sync.go b/agent/internal/sync/sync.go index 5daac75..5d56f58 100644 --- a/agent/internal/sync/sync.go +++ b/agent/internal/sync/sync.go @@ -21,6 +21,7 @@ import ( agentexec "github.com/mrhid6/vantage/agent/internal/exec" grpcclient "github.com/mrhid6/vantage/agent/internal/grpc" "github.com/mrhid6/vantage/agent/internal/grpc/pb" + "github.com/mrhid6/vantage/agent/internal/inventory" "github.com/mrhid6/vantage/agent/internal/keys" "github.com/mrhid6/vantage/agent/internal/updates" ) @@ -68,6 +69,9 @@ func Run(ctx context.Context, cfg *config.Config, version string) error { // Check for OS updates on startup and then hourly. go runUpdateCheck(ctx, cfg) + // Report host inventory: metrics every 30s, full static snapshot every 15 min. + go runInventory(ctx, cfg) + ticker := time.NewTicker(cfg.PollInterval) defer ticker.Stop() @@ -272,6 +276,40 @@ func runUpdateCheck(ctx context.Context, cfg *config.Config) { } } +// runInventory reports host metrics every 30s and a full static snapshot every +// 15 min (and once immediately on startup so static fields populate without delay). +func runInventory(ctx context.Context, cfg *config.Config) { + client, err := grpcclient.New(cfg.ServerURL, cfg.TLS) + if err != nil { + log.Printf("inventory dial error: %v", err) + return + } + defer client.Close() + + report := func(static bool) { + r := inventory.Collect(static) + r.ServerId = cfg.ServerID + r.AgentToken = cfg.AgentToken + if err := client.ReportInventory(r); err != nil { + log.Printf("report inventory: %v", err) + } + } + + report(true) // full snapshot on startup + ticker := time.NewTicker(30 * time.Second) + defer ticker.Stop() + tick := 0 + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + tick++ + report(tick%30 == 0) // every 30th tick = 15 min → include static + } + } +} + func handleApplyUpdates(cfg *config.Config, cmd *pb.ServerCommand) { log.Printf("applying OS updates (cmd=%s)…", cmd.CommandId) if err := updates.ApplyAll(); err != nil {