feat(system): manage compute contour network profile

This commit is contained in:
DCCONSTRUCTIONS
2026-07-29 12:32:41 +03:00
parent 1eba7c82ba
commit d8ccc9345a
8 changed files with 1139 additions and 9 deletions
@@ -13,6 +13,7 @@ export interface ComputeContour {
ssh_port: number;
mqtt_host: string;
mqtt_port: number;
mqtt_bind_address: string;
telemetry_poll_interval_seconds: number;
mqtt_publish_interval_seconds: number;
revision: number;
@@ -33,6 +34,7 @@ export interface ComputeContourDraft {
ssh_port: number;
mqtt_host: string;
mqtt_port: number;
mqtt_bind_address: string;
telemetry_poll_interval_seconds: number;
mqtt_publish_interval_seconds: number;
}
@@ -52,6 +54,45 @@ export interface ComputeContourAgentInstall {
blocked_reason: string | null;
}
export interface ComputeContourNetworkStatus {
schema_version: "missioncore.compute-contour-network-status/v1";
contour_id: string;
observed_at_utc: string;
latency_ms: number;
broker: {
configured_host: string;
configured_port: number;
bind_address: string;
resolved_addresses: string[];
endpoint_reachable: boolean;
bind_reachable: boolean;
bind_address_owned: boolean;
ready: boolean;
};
worker: {
checked: boolean;
reachable: boolean;
identity_matches: boolean;
node_id: string | null;
service_status: string | null;
mqtt_host: string | null;
mqtt_port: number | null;
resolved_addresses: string[];
broker_reachable: boolean;
matches_profile: boolean;
error_code: string | null;
};
}
export interface ComputeContourNetworkApply {
schema_version: "missioncore.compute-contour-network-apply/v1";
contour_id: string;
target: "broker" | "worker";
changed: boolean;
applied_at_utc: string;
ready: boolean;
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
@@ -66,7 +107,11 @@ async function requestJson(url: string, init: RequestInit): Promise<unknown> {
},
});
if (!response.ok) {
throw new Error(`Контуры вычисления: HTTP ${response.status}.`);
const document = await response.json().catch(() => null);
const detail = isRecord(document) && typeof document.detail === "string"
? document.detail
: null;
throw new Error(detail ?? `Контуры вычисления: HTTP ${response.status}.`);
}
return response.json();
}
@@ -100,6 +145,7 @@ export async function createComputeContour(
ssh_port: draft.ssh_port,
mqtt_host: draft.mqtt_host,
mqtt_port: draft.mqtt_port,
mqtt_bind_address: draft.mqtt_bind_address,
telemetry_poll_interval_seconds: draft.telemetry_poll_interval_seconds,
mqtt_publish_interval_seconds: draft.mqtt_publish_interval_seconds,
}),
@@ -152,3 +198,45 @@ export async function fetchComputeContourAgentInstall(
}
return document as unknown as ComputeContourAgentInstall;
}
export async function fetchComputeContourNetwork(
contourId: string,
signal?: AbortSignal,
): Promise<ComputeContourNetworkStatus> {
const document = await requestJson(
`/api/v1/system/contours/${encodeURIComponent(contourId)}/network`,
{
method: "GET",
signal,
},
);
if (
!isRecord(document)
|| document.schema_version !== "missioncore.compute-contour-network-status/v1"
) {
throw new Error("Сетевой статус контура не соответствует контракту.");
}
return document as unknown as ComputeContourNetworkStatus;
}
export async function applyComputeContourNetwork(
contourId: string,
target: "broker" | "worker",
signal?: AbortSignal,
): Promise<ComputeContourNetworkApply> {
const document = await requestJson(
`/api/v1/system/contours/${encodeURIComponent(contourId)}/network/${target}`,
{
method: "POST",
signal,
},
);
if (
!isRecord(document)
|| document.schema_version !== "missioncore.compute-contour-network-apply/v1"
|| document.target !== target
) {
throw new Error("Результат применения сетевого профиля не соответствует контракту.");
}
return document as unknown as ComputeContourNetworkApply;
}