diff --git a/CLAUDE.md b/CLAUDE.md index 8f36683..23e7369 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -451,10 +451,21 @@ is in `ScopedCollections` (which `scopedCollectionsForPurge` derives from). Ther is no history: a workload list is state, not a record. **`proto/vantage/v1/vantage.proto` is documentation, not a generator input.** -Both `pb` packages are hand-written JSON-tagged structs over a custom codec, and -there are two copies — `agent/internal/grpc/pb` and `server/internal/grpc/pb`. -A message added to one must be added to the other and to the `.proto`, in the -same commit. +`shared/grpc/pb` is hand-written JSON-tagged structs over the custom codec in +`shared/grpc/codec`, and it is **one** package shared by both sides — a message +added to it must be added to the `.proto` in the same commit, but there is no +longer a second Go copy to keep in step. There used to be two +(`agent/internal/grpc/pb` and `server/internal/grpc/pb`) and they had already +drifted: the agent's `UnimplementedVantageServer` was three methods stale and +carried no `ReportWorkloads` at all. The agent links the server half as dead +code, which the linker drops. + +This makes `agent` the **fifth** consumer of `shared/`, and the second one CI +does not rebuild on a push to main: like `vantagectl`, the agent image is cut by +`agent-release.yml` on an `agent/v*` tag, so a wire change reaches the server at +the next push and the fleet at the next agent release. That gap existed before +too — it is just now a compile error in the same tree rather than a silent +mismatch between two copies that both compiled. ### Status pages @@ -1346,7 +1357,10 @@ stale**. `vantagectl` also imports `shared/` and is the exception: it is built by `vantagectl-release.yml`, so a `shared/` fix reaches it only when someone cuts a `vantagectl/v*` tag. That is deliberate — an operator restoring a database should be running a version they can name — but it does mean a -`shared/backup` fix is not live until it is released. A change to the workflow file rebuilds everything, since +`shared/backup` fix is not live until it is released. `agent` is the same shape +of exception since `shared/grpc/pb` moved there: it is built by +`agent-release.yml` on an `agent/v*` tag, so a wire change lands on the server +at the next push to main and on the fleet only at the next agent release. A change to the workflow file rebuilds everything, since a build arg is baked into the image. So does anything that leaves no trustworthy base commit: a manual `workflow_dispatch`, a new branch, or a force-push whose old head is gone. diff --git a/agent/go.mod b/agent/go.mod index 009060a..574dff1 100644 --- a/agent/go.mod +++ b/agent/go.mod @@ -9,8 +9,11 @@ require ( ) require ( + gitea.hostxtra.co.uk/mrhid6/vantage/shared v0.0.0 golang.org/x/net v0.25.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/text v0.40.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect google.golang.org/protobuf v1.34.1 // indirect ) + +replace gitea.hostxtra.co.uk/mrhid6/vantage/shared => ../shared diff --git a/agent/go.sum b/agent/go.sum index 4c66072..4f5c8b1 100644 --- a/agent/go.sum +++ b/agent/go.sum @@ -4,8 +4,8 @@ golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= +golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e h1:Elxv5MwEkCI9f5SkoL6afed6NTdxaGoAo39eANBwHL8= google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= diff --git a/agent/internal/exec/exec.go b/agent/internal/exec/exec.go index a68f967..57dbe89 100644 --- a/agent/internal/exec/exec.go +++ b/agent/internal/exec/exec.go @@ -11,7 +11,7 @@ import ( "sync" "time" - "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) type streamWriter struct { diff --git a/agent/internal/grpc/client.go b/agent/internal/grpc/client.go index ed19409..9dacc85 100644 --- a/agent/internal/grpc/client.go +++ b/agent/internal/grpc/client.go @@ -6,7 +6,8 @@ import ( "strings" "time" - "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/codec" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" @@ -15,7 +16,7 @@ import ( ) func init() { - encoding.RegisterCodec(JSONCodec{}) + encoding.RegisterCodec(codec.JSONCodec{}) } type Client struct { diff --git a/agent/internal/grpc/codec.go b/agent/internal/grpc/codec.go deleted file mode 100644 index 478474b..0000000 --- a/agent/internal/grpc/codec.go +++ /dev/null @@ -1,17 +0,0 @@ -package grpcclient - -import "encoding/json" - -type JSONCodec struct{} - -func (JSONCodec) Marshal(v interface{}) ([]byte, error) { - return json.Marshal(v) -} - -func (JSONCodec) Unmarshal(data []byte, v interface{}) error { - return json.Unmarshal(data, v) -} - -func (JSONCodec) Name() string { - return "proto" -} diff --git a/agent/internal/grpc/pb/vantage.pb.go b/agent/internal/grpc/pb/vantage.pb.go deleted file mode 100644 index 5f6a9a8..0000000 --- a/agent/internal/grpc/pb/vantage.pb.go +++ /dev/null @@ -1,480 +0,0 @@ -package pb - -import ( - "context" - - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -type RegisterRequest struct { - ServerId string `json:"server_id"` - PreRegToken string `json:"pre_reg_token"` - Hostname string `json:"hostname"` - IpAddress string `json:"ip_address"` - OsInfo string `json:"os_info"` -} - -type RegisterResponse struct { - AgentToken string `json:"agent_token"` -} - -type SyncRequest struct { - ServerId string `json:"server_id"` - AgentToken string `json:"agent_token"` - AgentVersion string `json:"agent_version,omitempty"` -} - -type SyncResponse struct { - PublicKeys []string `json:"public_keys"` - // CollectPackages tells the agent whether this instance's licence grants - // vulnerability scanning. Absent decodes as false, which is the safe - // direction: an older server leaves agents collecting nothing. - CollectPackages bool `json:"collect_packages,omitempty"` -} - -type OSRelease struct { - Family string `json:"family"` - // VersionId is not optional: Ubuntu 22.04 and 24.04 publish different fixed - // versions for the same CVE, so a scan without it is guesswork. - VersionId string `json:"version_id"` - Arch string `json:"arch,omitempty"` -} - -type InstalledPackage struct { - Name string `json:"name"` - Version string `json:"version"` - Epoch int32 `json:"epoch,omitempty"` - Arch string `json:"arch,omitempty"` - // SourceName is what the Debian and Ubuntu feeds are keyed on: one advisory - // against "openssl" covers libssl3, openssl and libssl-dev. - SourceName string `json:"source_name,omitempty"` -} - -// ReportPackagesRequest carries a server's installed package set. -// -// The agent calls twice at most: first with Packages empty, offering only the -// hash. If the server already holds it, NeedFull is false and the ~150KB body -// is never sent. -type ReportPackagesRequest struct { - ServerId string `json:"server_id"` - AgentToken string `json:"agent_token"` - Hash string `json:"hash"` - Os OSRelease `json:"os"` - Packages []InstalledPackage `json:"packages,omitempty"` -} - -type ReportPackagesResponse struct { - NeedFull bool `json:"need_full"` -} - -type UploadKeyRequest struct { - ServerId string `json:"server_id"` - AgentToken string `json:"agent_token"` - PublicKey string `json:"public_key"` - Label string `json:"label"` - PrivateKey string `json:"private_key,omitempty"` -} - -type UploadKeyResponse struct { - KeyId string `json:"key_id"` -} - -type PackageUpdate struct { - Name string `json:"name"` - CurrentVersion string `json:"current_version,omitempty"` - NewVersion string `json:"new_version"` -} - -type ReportUpdatesRequest struct { - ServerId string `json:"server_id"` - AgentToken string `json:"agent_token"` - Updates []PackageUpdate `json:"updates"` -} - -type ReportUpdatesResponse struct{} - -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"` - RebootRequired bool `json:"reboot_required,omitempty"` -} -type InventoryReportResponse struct{} - -type MonitorSpec struct { - MonitorId string `json:"monitor_id"` - Type string `json:"type"` - URL string `json:"url,omitempty"` - Host string `json:"host,omitempty"` - Port int `json:"port,omitempty"` - Method string `json:"method,omitempty"` - ExpectedStatus int `json:"expected_status,omitempty"` - Keyword string `json:"keyword,omitempty"` - TLSWarnDays int `json:"tls_warn_days,omitempty"` - Insecure bool `json:"insecure,omitempty"` - IntervalSec int `json:"interval_sec"` - Retries int `json:"retries"` -} -type SyncMonitorsRequest struct { - ServerId string `json:"server_id"` - AgentToken string `json:"agent_token"` -} -type SyncMonitorsResponse struct { - Monitors []MonitorSpec `json:"monitors,omitempty"` -} -type CheckResult struct { - MonitorId string `json:"monitor_id"` - Up bool `json:"up"` - LatencyMs int `json:"latency_ms"` - Message string `json:"message,omitempty"` - CertExpiryUnix int64 `json:"cert_expiry_unix,omitempty"` -} -type ReportChecksRequest struct { - ServerId string `json:"server_id"` - AgentToken string `json:"agent_token"` - Results []CheckResult `json:"results,omitempty"` -} -type ReportChecksResponse struct{} - -type ApplyUpdatesCmd struct{} - -type OpenProxyCmd struct { - ProxyId string `json:"proxy_id"` - Port uint32 `json:"port"` -} - -type ProxyOpen struct { - ServerId string `json:"server_id"` - AgentToken string `json:"agent_token"` - ProxyId string `json:"proxy_id"` -} - -type ProxyClose struct { - Reason string `json:"reason,omitempty"` -} - -type ProxyClientMsg struct { - Open *ProxyOpen `json:"open,omitempty"` - Data []byte `json:"data,omitempty"` - Close *ProxyClose `json:"close,omitempty"` -} - -type ProxyServerMsg struct { - Data []byte `json:"data,omitempty"` - Close *ProxyClose `json:"close,omitempty"` -} - -type ServerCommand struct { - CommandId string `json:"command_id"` - GenerateKey *GenerateKeyCmd `json:"generate_key,omitempty"` - DeleteKey *DeleteKeyCmd `json:"delete_key,omitempty"` - UpdateAgent *UpdateAgentCmd `json:"update_agent,omitempty"` - ApplyUpdates *ApplyUpdatesCmd `json:"apply_updates,omitempty"` - RunStep *RunStepCmd `json:"run_step,omitempty"` - CleanupWorkspace *CleanupWorkspaceCmd `json:"cleanup_workspace,omitempty"` - OpenProxy *OpenProxyCmd `json:"open_proxy,omitempty"` - Ping *PingCmd `json:"ping,omitempty"` - - RefreshWorkloads *RefreshWorkloadsCmd `json:"refresh_workloads,omitempty"` - ControlWorkload *ControlWorkloadCmd `json:"control_workload,omitempty"` - WorkloadLogs *WorkloadLogsCmd `json:"workload_logs,omitempty"` -} - -// PingCmd is a server-originated liveness beat. It carries nothing and expects -// no reply: its arrival is the entire message. See the .proto for why gRPC -// keepalive is not sufficient on its own. -type PingCmd struct{} - -type CleanupWorkspaceCmd struct { - WorkspaceId string `json:"workspace_id"` -} - -type DeleteKeyCmd struct { - Label string `json:"label"` -} - -type UpdateAgentCmd struct { - Version string `json:"version"` - GiteaBaseURL string `json:"gitea_base_url"` -} - -type GenerateKeyCmd struct { - Label string `json:"label"` - KeyType string `json:"key_type,omitempty"` - KeySize int `json:"key_size,omitempty"` - Passphrase string `json:"passphrase,omitempty"` - Comment string `json:"comment,omitempty"` -} - -type AgentMessage struct { - ServerId string `json:"server_id"` - AgentToken string `json:"agent_token"` - Ready *AgentReady `json:"ready,omitempty"` - Result *CommandResult `json:"result,omitempty"` - StepResult *StepResult `json:"step_result,omitempty"` - StepOutput *StepOutputChunk `json:"step_output,omitempty"` - - WorkloadLogsResult *WorkloadLogsResult `json:"workload_logs_result,omitempty"` -} - -type AgentReady struct{} - -type CommandResult struct { - CommandId string `json:"command_id"` - Success bool `json:"success"` - Message string `json:"message"` -} - -type RunStepCmd struct { - Interpreter string `json:"interpreter"` - Script string `json:"script"` - Env map[string]string `json:"env,omitempty"` - TimeoutSeconds int `json:"timeout_seconds,omitempty"` - - WorkspaceId string `json:"workspace_id,omitempty"` -} - -type StepResult struct { - CommandId string `json:"command_id"` - ExitCode int `json:"exit_code"` - Stdout string `json:"stdout,omitempty"` - Stderr string `json:"stderr,omitempty"` - OutputEnv map[string]string `json:"output_env,omitempty"` -} - -type StepOutputChunk struct { - CommandId string `json:"command_id"` - Seq uint64 `json:"seq"` - Data []byte `json:"data,omitempty"` - Eof bool `json:"eof,omitempty"` -} - -type Vantage_CommandStreamClient interface { - Send(*AgentMessage) error - Recv() (*ServerCommand, error) - grpc.ClientStream -} - -type vantageCommandStreamClient struct { - grpc.ClientStream -} - -func (c *vantageCommandStreamClient) Send(m *AgentMessage) error { - return c.ClientStream.SendMsg(m) -} - -func (c *vantageCommandStreamClient) Recv() (*ServerCommand, error) { - m := new(ServerCommand) - if err := c.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -type Vantage_CommandStreamServer interface { - Send(*ServerCommand) error - Recv() (*AgentMessage, error) - grpc.ServerStream -} - -type keyManagerCommandStreamServer struct { - grpc.ServerStream -} - -func (s *keyManagerCommandStreamServer) Send(m *ServerCommand) error { - return s.ServerStream.SendMsg(m) -} - -func (s *keyManagerCommandStreamServer) Recv() (*AgentMessage, error) { - m := new(AgentMessage) - if err := s.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -type Vantage_ProxyStreamServer interface { - Send(*ProxyServerMsg) error - Recv() (*ProxyClientMsg, error) - grpc.ServerStream -} - -type vantageProxyStreamServer struct { - grpc.ServerStream -} - -func (s *vantageProxyStreamServer) Send(m *ProxyServerMsg) error { - return s.ServerStream.SendMsg(m) -} - -func (s *vantageProxyStreamServer) Recv() (*ProxyClientMsg, error) { - m := new(ProxyClientMsg) - if err := s.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -type Vantage_ProxyStreamClient interface { - Send(*ProxyClientMsg) error - Recv() (*ProxyServerMsg, error) - CloseSend() error - grpc.ClientStream -} - -type vantageProxyStreamClient struct { - grpc.ClientStream -} - -func (c *vantageProxyStreamClient) Send(m *ProxyClientMsg) error { - return c.ClientStream.SendMsg(m) -} - -func (c *vantageProxyStreamClient) Recv() (*ProxyServerMsg, error) { - m := new(ProxyServerMsg) - if err := c.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -type VantageClient interface { - Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) - 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) - ReportPackages(ctx context.Context, in *ReportPackagesRequest, opts ...grpc.CallOption) (*ReportPackagesResponse, error) - ReportWorkloads(ctx context.Context, in *ReportWorkloadsRequest, opts ...grpc.CallOption) (*ReportWorkloadsResponse, error) - ReportInventory(ctx context.Context, in *InventoryReport, opts ...grpc.CallOption) (*InventoryReportResponse, error) - SyncMonitors(ctx context.Context, in *SyncMonitorsRequest, opts ...grpc.CallOption) (*SyncMonitorsResponse, error) - ReportChecks(ctx context.Context, in *ReportChecksRequest, opts ...grpc.CallOption) (*ReportChecksResponse, error) - CommandStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_CommandStreamClient, error) - ProxyStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_ProxyStreamClient, error) -} - -type UnimplementedVantageServer struct{} - -func (UnimplementedVantageServer) Register(context.Context, *RegisterRequest) (*RegisterResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "not implemented") -} -func (UnimplementedVantageServer) SyncKeys(context.Context, *SyncRequest) (*SyncResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "not implemented") -} -func (UnimplementedVantageServer) UploadGeneratedKey(context.Context, *UploadKeyRequest) (*UploadKeyResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "not implemented") -} - -type keyManagerClient struct { - cc grpc.ClientConnInterface -} - -func NewVantageClient(cc grpc.ClientConnInterface) VantageClient { - return &keyManagerClient{cc} -} - -func (c *keyManagerClient) Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) { - out := new(RegisterResponse) - if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/Register", in, out, opts...); err != nil { - return nil, err - } - return out, nil -} - -func (c *keyManagerClient) SyncKeys(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error) { - out := new(SyncResponse) - if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/SyncKeys", in, out, opts...); err != nil { - return nil, err - } - return out, nil -} - -func (c *keyManagerClient) UploadGeneratedKey(ctx context.Context, in *UploadKeyRequest, opts ...grpc.CallOption) (*UploadKeyResponse, error) { - out := new(UploadKeyResponse) - if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/UploadGeneratedKey", in, out, opts...); err != nil { - return nil, err - } - return out, nil -} - -func (c *keyManagerClient) ReportUpdates(ctx context.Context, in *ReportUpdatesRequest, opts ...grpc.CallOption) (*ReportUpdatesResponse, error) { - out := new(ReportUpdatesResponse) - if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/ReportUpdates", in, out, opts...); err != nil { - return nil, err - } - return out, nil -} - -func (c *keyManagerClient) ReportPackages(ctx context.Context, in *ReportPackagesRequest, opts ...grpc.CallOption) (*ReportPackagesResponse, error) { - out := new(ReportPackagesResponse) - if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/ReportPackages", in, out, opts...); err != nil { - return nil, err - } - 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) SyncMonitors(ctx context.Context, in *SyncMonitorsRequest, opts ...grpc.CallOption) (*SyncMonitorsResponse, error) { - out := new(SyncMonitorsResponse) - if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/SyncMonitors", in, out, opts...); err != nil { - return nil, err - } - return out, nil -} - -func (c *keyManagerClient) ReportChecks(ctx context.Context, in *ReportChecksRequest, opts ...grpc.CallOption) (*ReportChecksResponse, error) { - out := new(ReportChecksResponse) - if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/ReportChecks", 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...) - if err != nil { - return nil, err - } - return &vantageCommandStreamClient{stream}, nil -} - -func (c *keyManagerClient) ProxyStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_ProxyStreamClient, error) { - desc := &grpc.StreamDesc{StreamName: "ProxyStream", ServerStreams: true, ClientStreams: true} - stream, err := c.cc.NewStream(ctx, desc, "/vantage.v1.Vantage/ProxyStream", opts...) - if err != nil { - return nil, err - } - return &vantageProxyStreamClient{stream}, nil -} diff --git a/agent/internal/grpc/pb/workloads.pb.go b/agent/internal/grpc/pb/workloads.pb.go deleted file mode 100644 index a3bc0da..0000000 --- a/agent/internal/grpc/pb/workloads.pb.go +++ /dev/null @@ -1,80 +0,0 @@ -package pb - -import ( - "context" - - "google.golang.org/grpc" -) - -// Workload registry messages. Hand-written like the rest of this package: the -// .proto is the contract, this file is the Go side of it, and the two must be -// changed together. - -// Workload is one container or one systemd unit. -type Workload struct { - Kind string `json:"kind"` - Id string `json:"id"` - Name string `json:"name"` - State string `json:"state"` - Health string `json:"health,omitempty"` - Image string `json:"image,omitempty"` - Stack string `json:"stack,omitempty"` - Ports []string `json:"ports,omitempty"` - Restarts int32 `json:"restarts,omitempty"` - StartedAt string `json:"started_at,omitempty"` // RFC3339, empty when not running - Protected bool `json:"protected,omitempty"` -} - -// ReportWorkloadsRequest carries what a server is running. -// -// Offer-then-send, the same handshake as ReportPackages: the agent calls once -// with Workloads empty, and resends with the body only if NeedFull is set. -type ReportWorkloadsRequest struct { - ServerId string `json:"server_id"` - AgentToken string `json:"agent_token"` - Hash string `json:"hash"` - DockerOk bool `json:"docker_ok"` - DockerError string `json:"docker_error,omitempty"` - SystemdOk bool `json:"systemd_ok"` - SystemdError string `json:"systemd_error,omitempty"` - Workloads []Workload `json:"workloads,omitempty"` // empty on the offer call - // Full marks the second call. It is not inferred from an empty Workloads - // slice: a host running nothing sends an empty list as its full report. - Full bool `json:"full,omitempty"` -} - -type ReportWorkloadsResponse struct { - NeedFull bool `json:"need_full"` -} - -// RefreshWorkloadsCmd carries no payload back. It makes the agent report -// immediately through ReportWorkloads, so there is exactly one writer for the -// server_workloads collection rather than two arriving by different routes. -type RefreshWorkloadsCmd struct{} - -type ControlWorkloadCmd struct { - Kind string `json:"kind"` - Id string `json:"id"` - Action string `json:"action"` // start | stop | restart -} - -type WorkloadLogsCmd struct { - Kind string `json:"kind"` - Id string `json:"id"` - Tail int32 `json:"tail,omitempty"` -} - -type WorkloadLogsResult struct { - CommandId string `json:"command_id"` - Text string `json:"text,omitempty"` - Truncated bool `json:"truncated,omitempty"` - Error string `json:"error,omitempty"` -} - -func (c *keyManagerClient) ReportWorkloads(ctx context.Context, in *ReportWorkloadsRequest, opts ...grpc.CallOption) (*ReportWorkloadsResponse, error) { - out := new(ReportWorkloadsResponse) - if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/ReportWorkloads", in, out, opts...); err != nil { - return nil, err - } - return out, nil -} diff --git a/agent/internal/inventory/collect_linux.go b/agent/internal/inventory/collect_linux.go index df2291f..3347544 100644 --- a/agent/internal/inventory/collect_linux.go +++ b/agent/internal/inventory/collect_linux.go @@ -8,7 +8,7 @@ import ( "syscall" "time" - "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) func collect(r *pb.InventoryReport, includeStatic bool) { diff --git a/agent/internal/inventory/collect_other.go b/agent/internal/inventory/collect_other.go index fa45061..4740b51 100644 --- a/agent/internal/inventory/collect_other.go +++ b/agent/internal/inventory/collect_other.go @@ -7,7 +7,6 @@ // without it this file compiles on Linux too and collides with collect_linux.go. package inventory -import "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" - +import "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" func collect(r *pb.InventoryReport, includeStatic bool) {} diff --git a/agent/internal/inventory/collect_windows.go b/agent/internal/inventory/collect_windows.go index 1369387..a6583c0 100644 --- a/agent/internal/inventory/collect_windows.go +++ b/agent/internal/inventory/collect_windows.go @@ -9,7 +9,7 @@ import ( "golang.org/x/sys/windows" "golang.org/x/sys/windows/registry" - "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) var ( diff --git a/agent/internal/inventory/inventory.go b/agent/internal/inventory/inventory.go index 8875d40..a1d5214 100644 --- a/agent/internal/inventory/inventory.go +++ b/agent/internal/inventory/inventory.go @@ -1,6 +1,6 @@ package inventory -import "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" +import "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" func Collect(includeStatic bool) *pb.InventoryReport { r := &pb.InventoryReport{IncludeStatic: includeStatic, CPU: &pb.CPUReport{}, Memory: &pb.MemReport{}} diff --git a/agent/internal/monitors/monitors.go b/agent/internal/monitors/monitors.go index 62ddb81..62d6c63 100644 --- a/agent/internal/monitors/monitors.go +++ b/agent/internal/monitors/monitors.go @@ -9,7 +9,7 @@ import ( "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/checker" "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/config" grpcclient "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc" - "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) const syncInterval = 30 * time.Second diff --git a/agent/internal/proxy/proxy.go b/agent/internal/proxy/proxy.go index c87d3e8..0d0cbc4 100644 --- a/agent/internal/proxy/proxy.go +++ b/agent/internal/proxy/proxy.go @@ -14,7 +14,7 @@ import ( "strconv" "time" - "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) const ( diff --git a/agent/internal/sync/packages.go b/agent/internal/sync/packages.go index 4830d22..c35bc55 100644 --- a/agent/internal/sync/packages.go +++ b/agent/internal/sync/packages.go @@ -10,8 +10,8 @@ import ( "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/config" grpcclient "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc" - "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/packages" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) // collectPackagesFlag is written by the 30s key poll and read by the hourly diff --git a/agent/internal/sync/sync.go b/agent/internal/sync/sync.go index 14c7cd7..4f6d06d 100644 --- a/agent/internal/sync/sync.go +++ b/agent/internal/sync/sync.go @@ -20,12 +20,12 @@ import ( "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/config" agentexec "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/exec" grpcclient "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc" - "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/inventory" "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/keys" "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/monitors" agentproxy "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/proxy" "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/updates" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) func Run(ctx context.Context, cfg *config.Config, version string) error { diff --git a/agent/internal/sync/workloads.go b/agent/internal/sync/workloads.go index 8def86f..e7b363a 100644 --- a/agent/internal/sync/workloads.go +++ b/agent/internal/sync/workloads.go @@ -7,8 +7,8 @@ import ( "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/config" grpcclient "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc" - "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/grpc/pb" "gitea.hostxtra.co.uk/mrhid6/vantage/agent/internal/workloads" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) // workloadInterval is the report cadence. Sixty seconds is affordable because diff --git a/server/internal/grpc/proxystream.go b/server/internal/grpc/proxystream.go index 3822032..9c494ec 100644 --- a/server/internal/grpc/proxystream.go +++ b/server/internal/grpc/proxystream.go @@ -3,9 +3,9 @@ package grpcserver import ( "log" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/proxy" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/services" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/server/internal/grpc/server.go b/server/internal/grpc/server.go index efc5899..ac9809f 100644 --- a/server/internal/grpc/server.go +++ b/server/internal/grpc/server.go @@ -8,9 +8,10 @@ import ( "time" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/checker" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/models" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/services" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/codec" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/encoding" @@ -19,7 +20,7 @@ import ( ) func init() { - encoding.RegisterCodec(JSONCodec{}) + encoding.RegisterCodec(codec.JSONCodec{}) } type vantageServer struct { diff --git a/server/internal/proxy/session.go b/server/internal/proxy/session.go index 847be17..373ff54 100644 --- a/server/internal/proxy/session.go +++ b/server/internal/proxy/session.go @@ -10,7 +10,7 @@ import ( "sync" "time" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) const ( diff --git a/server/internal/services/consoleproxy.go b/server/internal/services/consoleproxy.go index 4e7717c..fb481df 100644 --- a/server/internal/services/consoleproxy.go +++ b/server/internal/services/consoleproxy.go @@ -12,8 +12,8 @@ import ( "time" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/bus" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/proxy" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) // ErrAgentOffline means the console cannot be opened because the target's agent diff --git a/server/internal/services/dispatch.go b/server/internal/services/dispatch.go index f7a07f2..43cb0b4 100644 --- a/server/internal/services/dispatch.go +++ b/server/internal/services/dispatch.go @@ -11,7 +11,7 @@ import ( "time" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/bus" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" "github.com/google/uuid" ) diff --git a/server/internal/services/inventory.go b/server/internal/services/inventory.go index 4752c01..dd9bb96 100644 --- a/server/internal/services/inventory.go +++ b/server/internal/services/inventory.go @@ -5,7 +5,7 @@ import ( "time" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/db" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" "go.mongodb.org/mongo-driver/v2/bson" ) diff --git a/server/internal/services/stepresults.go b/server/internal/services/stepresults.go index e8872c0..567a9ef 100644 --- a/server/internal/services/stepresults.go +++ b/server/internal/services/stepresults.go @@ -6,7 +6,7 @@ import ( "log" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/bus" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) // Step results travel back over the bus for the same reason commands travel out diff --git a/server/internal/services/workflow_runner.go b/server/internal/services/workflow_runner.go index 4a31a70..46c4bcf 100644 --- a/server/internal/services/workflow_runner.go +++ b/server/internal/services/workflow_runner.go @@ -7,8 +7,8 @@ import ( "time" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/db" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/models" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" "github.com/google/uuid" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" diff --git a/server/internal/services/workloadresults.go b/server/internal/services/workloadresults.go index f46de80..f0814ba 100644 --- a/server/internal/services/workloadresults.go +++ b/server/internal/services/workloadresults.go @@ -6,7 +6,7 @@ import ( "log" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/bus" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" ) // Workload results travel back over the bus for the same reason commands travel diff --git a/server/internal/services/workloads.go b/server/internal/services/workloads.go index 19dee0f..71ecef5 100644 --- a/server/internal/services/workloads.go +++ b/server/internal/services/workloads.go @@ -7,8 +7,8 @@ import ( "time" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/db" - "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb" "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/models" + "gitea.hostxtra.co.uk/mrhid6/vantage/shared/grpc/pb" "github.com/google/uuid" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" diff --git a/server/internal/grpc/codec.go b/shared/grpc/codec/codec.go similarity index 93% rename from server/internal/grpc/codec.go rename to shared/grpc/codec/codec.go index fea87ec..bb88907 100644 --- a/server/internal/grpc/codec.go +++ b/shared/grpc/codec/codec.go @@ -1,4 +1,4 @@ -package grpcserver +package codec import ( "encoding/json" diff --git a/server/internal/grpc/pb/vantage.pb.go b/shared/grpc/pb/vantage.pb.go similarity index 98% rename from server/internal/grpc/pb/vantage.pb.go rename to shared/grpc/pb/vantage.pb.go index 5caa8fb..b4d2a1f 100644 --- a/server/internal/grpc/pb/vantage.pb.go +++ b/shared/grpc/pb/vantage.pb.go @@ -280,15 +280,15 @@ type Vantage_CommandStreamServer interface { grpc.ServerStream } -type keyManagerCommandStreamServer struct { +type vantageCommandStreamServer struct { grpc.ServerStream } -func (s *keyManagerCommandStreamServer) Send(m *ServerCommand) error { +func (s *vantageCommandStreamServer) Send(m *ServerCommand) error { return s.ServerStream.SendMsg(m) } -func (s *keyManagerCommandStreamServer) Recv() (*AgentMessage, error) { +func (s *vantageCommandStreamServer) Recv() (*AgentMessage, error) { m := new(AgentMessage) if err := s.ServerStream.RecvMsg(m); err != nil { return nil, err @@ -681,5 +681,5 @@ func _Vantage_ReportChecks_Handler(srv interface{}, ctx context.Context, dec fun } func _Vantage_CommandStream_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(VantageServer).CommandStream(&keyManagerCommandStreamServer{stream}) + return srv.(VantageServer).CommandStream(&vantageCommandStreamServer{stream}) } diff --git a/server/internal/grpc/pb/workloads.pb.go b/shared/grpc/pb/workloads.pb.go similarity index 98% rename from server/internal/grpc/pb/workloads.pb.go rename to shared/grpc/pb/workloads.pb.go index dc6e51d..cd502ab 100644 --- a/server/internal/grpc/pb/workloads.pb.go +++ b/shared/grpc/pb/workloads.pb.go @@ -10,7 +10,7 @@ import ( // Workload registry messages. Hand-written like the rest of this package: the // .proto is the contract, this file is the Go side of it, and the two must be -// changed together. The agent module carries the same declarations. +// changed together. // Workload is one container or one systemd unit. type Workload struct {