feat: add web probe sentinel config plan (#895)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-25 22:07:22 +08:00
committed by GitHub
parent fd874ceef5
commit 9309efabb8
13 changed files with 786 additions and 3 deletions
+34 -3
View File
@@ -17,6 +17,7 @@ import { nodeWebObserveCollectViewNodeScript, parseNodeWebProbeObserveCollectVie
import { withWebObserveCollectRendered, withWebObserveCommandRendered, withWebObserveStatusRendered } from "./hwlab-node-web-observe-render";
import { buildWebObserveWrapperForObserveOptions, webObserveWrapperStateDirFromStatus } from "./hwlab-node-web-observe-wrapper";
import { renderWebObserveWrapperContract } from "./hwlab-node-web-observe-wrapper-render";
import { webProbeSentinelConfigPlan, withWebProbeSentinelConfigRendered, type WebProbeSentinelConfigAction } from "./hwlab-node-web-sentinel-config";
import { hwlabNodeHelp, hwlabNodeObservabilityHelp, hwlabNodeWebProbeHelp } from "./hwlab-node-help";
import { compactWebProbeResult, compactWebProbeScriptResult } from "./hwlab-node-web-probe-summary";
import { nodeObservabilityRecordingRuleExpression, nodeObservabilityRecordingRuleSummaries, nodeObservabilityWarningAlertExpression, nodeObservabilityWarningAlertSummaries } from "./hwlab-node-observability-promql";
@@ -112,7 +113,15 @@ interface NodeWebProbeObserveOptions {
commandTaskRef: string | null;
}
type NodeWebProbeOptions = NodeWebProbeRunOptions | NodeWebProbeScriptOptions | NodeWebProbeObserveOptions;
interface NodeWebProbeSentinelOptions {
action: "sentinel";
sentinelAction: WebProbeSentinelConfigAction;
node: string;
lane: string;
dryRun: boolean;
}
type NodeWebProbeOptions = NodeWebProbeRunOptions | NodeWebProbeScriptOptions | NodeWebProbeObserveOptions | NodeWebProbeSentinelOptions;
interface WebObserveIndexEntry {
id: string;
@@ -7298,7 +7307,8 @@ function rewriteDelegatedNodeString(value: string, scoped: ReturnType<typeof par
function parseNodeWebProbeOptions(args: string[]): NodeWebProbeOptions {
const [actionRaw] = args;
if (actionRaw !== "run" && actionRaw !== "script" && actionRaw !== "observe") throw new Error("web-probe usage: run|script|observe --node NODE --lane vNN [--url URL]");
if (actionRaw !== "run" && actionRaw !== "script" && actionRaw !== "observe" && actionRaw !== "sentinel") throw new Error("web-probe usage: run|script|observe|sentinel --node NODE --lane vNN [--url URL]");
if (actionRaw === "sentinel") return parseNodeWebProbeSentinelOptions(args.slice(1));
if (actionRaw === "observe") {
const normalized = normalizeNodeWebProbeObserveArgs(args.slice(1));
const explicitNode = optionValue(args, "--node");
@@ -7427,6 +7437,26 @@ function parseNodeWebProbeOptions(args: string[]): NodeWebProbeOptions {
};
}
function parseNodeWebProbeSentinelOptions(args: string[]): NodeWebProbeSentinelOptions {
const [sentinelActionRaw] = args;
if (sentinelActionRaw !== "plan" && sentinelActionRaw !== "status") {
throw new Error("web-probe sentinel usage: sentinel plan|status --node NODE --lane vNN [--dry-run]");
}
assertKnownOptions(args, new Set(["--node", "--lane"]), new Set(["--dry-run"]));
const node = requiredOption(args, "--node");
assertNodeId(node);
const lane = requiredOption(args, "--lane");
assertLane(lane);
if (!isHwlabRuntimeLane(lane)) throw new Error(`web-probe only supports HWLAB runtime lanes, got ${lane}`);
return {
action: "sentinel",
sentinelAction: sentinelActionRaw,
node,
lane,
dryRun: args.includes("--dry-run"),
};
}
function normalizeNodeWebProbeObserveArgs(args: string[]): { args: string[]; id: string | null } {
const [observeActionRaw, maybeId, ...rest] = args;
if (observeActionRaw !== "start" && maybeId !== undefined && !maybeId.startsWith("--")) {
@@ -7653,10 +7683,11 @@ function assertKnownOptions(args: string[], valueOptions: Set<string>, flagOptio
}
}
function runNodeWebProbe(options: NodeWebProbeOptions): Record<string, unknown> {
function runNodeWebProbe(options: NodeWebProbeOptions): Record<string, unknown> | RenderedCliResult {
const lane = options.lane;
if (!isHwlabRuntimeLane(lane)) throw new Error(`web-probe only supports HWLAB runtime lanes, got ${lane}`);
const spec = hwlabRuntimeLaneSpecForNode(lane, options.node);
if (options.action === "sentinel") return withWebProbeSentinelConfigRendered(webProbeSentinelConfigPlan(spec, options.sentinelAction));
if (options.action === "observe" && options.observeAction !== "start") return runNodeWebProbeObserve(options, spec, null, null, null);
const secretSpec = runtimeSecretSpec({ node: options.node, lane });
const material = readBootstrapAdminPasswordMaterial(secretSpec);