add info about aviable commands in heartbeat

This commit is contained in:
2026-06-24 04:11:31 +03:00
parent 9eb2a06757
commit 25ae509d52
8 changed files with 86 additions and 1 deletions
+4
View File
@@ -10,6 +10,10 @@ from nexus_sync.common import Command, CommandKind, CommandResult, CommandResult
PresetBuilder = Callable[[Mapping[str, Any]], Sequence[str]]
DEFAULT_OUTPUT_LIMIT_BYTES = 64 * 1024
DEFAULT_PRESET_DESCRIPTIONS = {
"hostname": "Return system hostname",
"network_interfaces": "Return network interface information",
}
@dataclass(frozen=True)
+21 -1
View File
@@ -13,11 +13,17 @@ from typing import Callable, Mapping, Protocol, Self
from pydantic import ValidationError
from nexus_sync.client.config import load_command_access_policy
from nexus_sync.client.execute import CommandAccessPolicy, execute_command
from nexus_sync.client.execute import (
DEFAULT_PRESET_DESCRIPTIONS,
DEFAULT_PRESETS,
CommandAccessPolicy,
execute_command,
)
from nexus_sync.common import (
ClientInfo,
ClientPlatform,
ClientState,
ClientCommandCapability,
CommandResult,
HeartbeatRequest,
HeartbeatResponse,
@@ -93,10 +99,24 @@ def build_heartbeat_request(
local_time=datetime.now().astimezone(),
uptime_seconds=None,
),
available_commands=list_available_commands(config.command_access_policy),
last_command_result=last_command_result,
)
def list_available_commands(
access_policy: CommandAccessPolicy,
) -> list[ClientCommandCapability]:
return [
ClientCommandCapability(
name=name,
description=DEFAULT_PRESET_DESCRIPTIONS.get(name, ""),
)
for name in sorted(DEFAULT_PRESETS)
if access_policy.allows(name)
]
def send_heartbeat(
config: ClientConfig,
heartbeat: HeartbeatRequest,
+2
View File
@@ -4,6 +4,7 @@ from nexus_sync.common.models import (
ClientPlatform,
ClientRecord,
ClientState,
ClientCommandCapability,
Command,
CommandKind,
CommandRecord,
@@ -21,6 +22,7 @@ __all__ = [
"ClientPlatform",
"ClientRecord",
"ClientState",
"ClientCommandCapability",
"Command",
"CommandKind",
"CommandRecord",
+7
View File
@@ -47,6 +47,11 @@ class ClientState(StrictBaseModel):
uptime_seconds: int | None = Field(default=None, ge=0)
class ClientCommandCapability(StrictBaseModel):
name: str
description: str
class CommandResult(StrictBaseModel):
command_id: str
status: CommandResultStatus
@@ -62,6 +67,7 @@ class HeartbeatRequest(StrictBaseModel):
observed_at: datetime
client: ClientInfo
state: ClientState
available_commands: list[ClientCommandCapability] = Field(default_factory=list)
last_command_result: CommandResult | None = None
@@ -89,6 +95,7 @@ class ClientRecord(StrictBaseModel):
last_seen_at: datetime
is_active: bool = True
token_hash: str | None = None
available_commands: list[ClientCommandCapability] = Field(default_factory=list)
class CommandRecord(StrictBaseModel):
+1
View File
@@ -45,6 +45,7 @@ class InMemoryStore:
last_seen_at=now,
is_active=True,
token_hash=token_hash,
available_commands=heartbeat.available_commands,
)
self.clients[heartbeat.client_id] = record
return record