From 03e2c3c50df2a9c1d5fe8597cb42f77ecaebc1b4 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Tue, 21 Jul 2026 14:04:28 +0100 Subject: [PATCH] feat(proto): add ReportInventory RPC and inventory model --- agent/internal/grpc/pb/vantage.pb.go | 41 ++++++++++++++++++ proto/vantage/v1/vantage.proto | 35 +++++++++++++++ server/internal/grpc/pb/vantage.pb.go | 62 +++++++++++++++++++++++++++ server/internal/models/server.go | 32 ++++++++++++++ 4 files changed, 170 insertions(+) diff --git a/agent/internal/grpc/pb/vantage.pb.go b/agent/internal/grpc/pb/vantage.pb.go index c90e82d..bcbd19b 100644 --- a/agent/internal/grpc/pb/vantage.pb.go +++ b/agent/internal/grpc/pb/vantage.pb.go @@ -60,6 +60,38 @@ type ReportUpdatesRequest struct { type ReportUpdatesResponse struct{} +// Inventory report message types + +type CPUReport struct { + Model string `json:"model,omitempty"` + Cores int `json:"cores,omitempty"` + UsagePct float64 `json:"usage_pct"` + Load1 float64 `json:"load1,omitempty"` +} +type MemReport struct { + TotalBytes uint64 `json:"total_bytes"` + UsedBytes uint64 `json:"used_bytes"` +} +type PartitionReport struct { + Device string `json:"device"` + Mountpoint string `json:"mountpoint"` + Fstype string `json:"fstype,omitempty"` + TotalBytes uint64 `json:"total_bytes"` + UsedBytes uint64 `json:"used_bytes"` +} +type InventoryReport struct { + ServerId string `json:"server_id"` + AgentToken string `json:"agent_token"` + IncludeStatic bool `json:"include_static"` + CPU *CPUReport `json:"cpu,omitempty"` + Memory *MemReport `json:"memory,omitempty"` + SwapTotal uint64 `json:"swap_total"` + SwapUsed uint64 `json:"swap_used"` + Partitions []PartitionReport `json:"partitions,omitempty"` + Kernel string `json:"kernel,omitempty"` +} +type InventoryReportResponse struct{} + type ApplyUpdatesCmd struct{} type ServerCommand struct { @@ -190,6 +222,7 @@ type VantageClient interface { SyncKeys(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error) UploadGeneratedKey(ctx context.Context, in *UploadKeyRequest, opts ...grpc.CallOption) (*UploadKeyResponse, error) ReportUpdates(ctx context.Context, in *ReportUpdatesRequest, opts ...grpc.CallOption) (*ReportUpdatesResponse, error) + ReportInventory(ctx context.Context, in *InventoryReport, opts ...grpc.CallOption) (*InventoryReportResponse, error) CommandStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_CommandStreamClient, error) } @@ -245,6 +278,14 @@ func (c *keyManagerClient) ReportUpdates(ctx context.Context, in *ReportUpdatesR return out, nil } +func (c *keyManagerClient) ReportInventory(ctx context.Context, in *InventoryReport, opts ...grpc.CallOption) (*InventoryReportResponse, error) { + out := new(InventoryReportResponse) + if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/ReportInventory", in, out, opts...); err != nil { + return nil, err + } + return out, nil +} + func (c *keyManagerClient) CommandStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_CommandStreamClient, error) { desc := &grpc.StreamDesc{StreamName: "CommandStream", ServerStreams: true, ClientStreams: true} stream, err := c.cc.NewStream(ctx, desc, "/vantage.v1.Vantage/CommandStream", opts...) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index 0ff68fa..a4fc92a 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -9,6 +9,7 @@ service Vantage { rpc SyncKeys(SyncRequest) returns (SyncResponse); rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); rpc ReportUpdates(ReportUpdatesRequest) returns (ReportUpdatesResponse); + rpc ReportInventory(InventoryReport) returns (InventoryReportResponse); // Bidirectional stream: agent sends auth once, server pushes commands. rpc CommandStream(stream AgentMessage) returns (stream ServerCommand); } @@ -82,6 +83,40 @@ message ReportUpdatesRequest { message ReportUpdatesResponse {} +message CPUReport { + string model = 1; + int32 cores = 2; + double usage_pct = 3; + double load1 = 4; +} + +message MemReport { + uint64 total_bytes = 1; + uint64 used_bytes = 2; +} + +message PartitionReport { + string device = 1; + string mountpoint = 2; + string fstype = 3; + uint64 total_bytes = 4; + uint64 used_bytes = 5; +} + +message InventoryReport { + string server_id = 1; + string agent_token = 2; + bool include_static = 3; + CPUReport cpu = 4; + MemReport memory = 5; + uint64 swap_total = 6; + uint64 swap_used = 7; + repeated PartitionReport partitions = 8; + string kernel = 9; +} + +message InventoryReportResponse {} + message ApplyUpdatesCmd {} message ServerCommand { diff --git a/server/internal/grpc/pb/vantage.pb.go b/server/internal/grpc/pb/vantage.pb.go index 0f81650..b835d65 100644 --- a/server/internal/grpc/pb/vantage.pb.go +++ b/server/internal/grpc/pb/vantage.pb.go @@ -63,6 +63,38 @@ type ReportUpdatesRequest struct { type ReportUpdatesResponse struct{} +// Inventory report message types + +type CPUReport struct { + Model string `json:"model,omitempty"` + Cores int `json:"cores,omitempty"` + UsagePct float64 `json:"usage_pct"` + Load1 float64 `json:"load1,omitempty"` +} +type MemReport struct { + TotalBytes uint64 `json:"total_bytes"` + UsedBytes uint64 `json:"used_bytes"` +} +type PartitionReport struct { + Device string `json:"device"` + Mountpoint string `json:"mountpoint"` + Fstype string `json:"fstype,omitempty"` + TotalBytes uint64 `json:"total_bytes"` + UsedBytes uint64 `json:"used_bytes"` +} +type InventoryReport struct { + ServerId string `json:"server_id"` + AgentToken string `json:"agent_token"` + IncludeStatic bool `json:"include_static"` + CPU *CPUReport `json:"cpu,omitempty"` + Memory *MemReport `json:"memory,omitempty"` + SwapTotal uint64 `json:"swap_total"` + SwapUsed uint64 `json:"swap_used"` + Partitions []PartitionReport `json:"partitions,omitempty"` + Kernel string `json:"kernel,omitempty"` +} +type InventoryReportResponse struct{} + type ApplyUpdatesCmd struct{} type ServerCommand struct { @@ -195,6 +227,7 @@ type VantageServer interface { SyncKeys(context.Context, *SyncRequest) (*SyncResponse, error) UploadGeneratedKey(context.Context, *UploadKeyRequest) (*UploadKeyResponse, error) ReportUpdates(context.Context, *ReportUpdatesRequest) (*ReportUpdatesResponse, error) + ReportInventory(context.Context, *InventoryReport) (*InventoryReportResponse, error) CommandStream(Vantage_CommandStreamServer) error } @@ -216,6 +249,10 @@ func (UnimplementedVantageServer) ReportUpdates(context.Context, *ReportUpdatesR return nil, status.Errorf(codes.Unimplemented, "method ReportUpdates not implemented") } +func (UnimplementedVantageServer) ReportInventory(context.Context, *InventoryReport) (*InventoryReportResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReportInventory not implemented") +} + func (UnimplementedVantageServer) CommandStream(Vantage_CommandStreamServer) error { return status.Errorf(codes.Unimplemented, "method CommandStream not implemented") } @@ -227,6 +264,7 @@ type VantageClient interface { SyncKeys(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error) UploadGeneratedKey(ctx context.Context, in *UploadKeyRequest, opts ...grpc.CallOption) (*UploadKeyResponse, error) ReportUpdates(ctx context.Context, in *ReportUpdatesRequest, opts ...grpc.CallOption) (*ReportUpdatesResponse, error) + ReportInventory(ctx context.Context, in *InventoryReport, opts ...grpc.CallOption) (*InventoryReportResponse, error) CommandStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_CommandStreamClient, error) } @@ -270,6 +308,14 @@ func (c *keyManagerClient) ReportUpdates(ctx context.Context, in *ReportUpdatesR return out, nil } +func (c *keyManagerClient) ReportInventory(ctx context.Context, in *InventoryReport, opts ...grpc.CallOption) (*InventoryReportResponse, error) { + out := new(InventoryReportResponse) + if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/ReportInventory", in, out, opts...); err != nil { + return nil, err + } + return out, nil +} + func (c *keyManagerClient) CommandStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_CommandStreamClient, error) { stream, err := c.cc.NewStream(ctx, &Vantage_ServiceDesc.Streams[0], "/vantage.v1.Vantage/CommandStream", opts...) if err != nil { @@ -292,6 +338,7 @@ var Vantage_ServiceDesc = grpc.ServiceDesc{ {MethodName: "SyncKeys", Handler: _Vantage_SyncKeys_Handler}, {MethodName: "UploadGeneratedKey", Handler: _Vantage_UploadGeneratedKey_Handler}, {MethodName: "ReportUpdates", Handler: _Vantage_ReportUpdates_Handler}, + {MethodName: "ReportInventory", Handler: _Vantage_ReportInventory_Handler}, }, Streams: []grpc.StreamDesc{ { @@ -364,6 +411,21 @@ func _Vantage_ReportUpdates_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _Vantage_ReportInventory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InventoryReport) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VantageServer).ReportInventory(ctx, in) + } + info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/vantage.v1.Vantage/ReportInventory"} + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VantageServer).ReportInventory(ctx, req.(*InventoryReport)) + } + return interceptor(ctx, in, info, handler) +} + func _Vantage_CommandStream_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(VantageServer).CommandStream(&keyManagerCommandStreamServer{stream}) } diff --git a/server/internal/models/server.go b/server/internal/models/server.go index 369258c..98dd7d5 100644 --- a/server/internal/models/server.go +++ b/server/internal/models/server.go @@ -12,6 +12,37 @@ type PackageUpdate struct { NewVersion string `bson:"new_version" json:"new_version"` } +type CPUInfo struct { + Model string `bson:"model,omitempty" json:"model,omitempty"` + Cores int `bson:"cores,omitempty" json:"cores,omitempty"` + UsagePct float64 `bson:"usage_pct" json:"usage_pct"` + Load1 float64 `bson:"load1,omitempty" json:"load1,omitempty"` +} + +type MemInfo struct { + TotalBytes uint64 `bson:"total_bytes" json:"total_bytes"` + UsedBytes uint64 `bson:"used_bytes" json:"used_bytes"` +} + +type Partition struct { + Device string `bson:"device" json:"device"` + Mountpoint string `bson:"mountpoint" json:"mountpoint"` + Fstype string `bson:"fstype,omitempty" json:"fstype,omitempty"` + TotalBytes uint64 `bson:"total_bytes" json:"total_bytes"` + UsedBytes uint64 `bson:"used_bytes" json:"used_bytes"` +} + +type Inventory struct { + CPU CPUInfo `bson:"cpu" json:"cpu"` + Memory MemInfo `bson:"memory" json:"memory"` + SwapTotalBytes uint64 `bson:"swap_total_bytes" json:"swap_total_bytes"` + SwapUsedBytes uint64 `bson:"swap_used_bytes" json:"swap_used_bytes"` + Partitions []Partition `bson:"partitions,omitempty" json:"partitions,omitempty"` + Kernel string `bson:"kernel,omitempty" json:"kernel,omitempty"` + MetricsAt *time.Time `bson:"metrics_at,omitempty" json:"metrics_at,omitempty"` + StaticAt *time.Time `bson:"static_at,omitempty" json:"static_at,omitempty"` +} + type Server struct { ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"` ServerID string `bson:"server_id" json:"server_id"` @@ -30,5 +61,6 @@ type Server struct { LastSeen *time.Time `bson:"last_seen,omitempty" json:"last_seen,omitempty"` AvailableUpdates []PackageUpdate `bson:"available_updates,omitempty" json:"available_updates,omitempty"` UpdatesCheckedAt *time.Time `bson:"updates_checked_at,omitempty" json:"updates_checked_at,omitempty"` + Inventory *Inventory `bson:"inventory,omitempty" json:"inventory,omitempty"` CreatedAt time.Time `bson:"created_at" json:"created_at"` }