mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-28 11:17:07 +00:00
refactor(mesh): route inspectStackServices through proxyFetch (#1082)
inspectStackServices was constructing its Authorization, x-sencho-tier,
and x-sencho-variant headers inline. proxyFetch is the centralized
helper used by listStacksOnNode, pushOverrideToNode, triggerRemeshRedeploy,
and removeOverrideFromNode. Equivalent today for a GET-no-body call, but
any future header added to proxyFetch (audit context, license fingerprint,
request id) would silently miss inspectStackServices.
Wire output is byte-identical: same URL, same method, same three headers,
same 5 s timeout. The new catch arm converts MeshError('push_failed') back
to the existing warn + return [] contract callers (optInStack,
refreshAliasCache) rely on. Pattern mirrors listStacksOnNode.
This commit is contained in:
@@ -1180,19 +1180,14 @@ export class MeshService extends EventEmitter implements MeshForwarderHost {
|
|||||||
if (!node) return [];
|
if (!node) return [];
|
||||||
if (node.type !== 'remote') return this.inspectLocalStackServices(stackName);
|
if (node.type !== 'remote') return this.inspectLocalStackServices(stackName);
|
||||||
|
|
||||||
const target = NodeRegistry.getInstance().getProxyTarget(nodeId);
|
|
||||||
if (!target) {
|
|
||||||
console.warn(`[MeshService] inspectStackServices: no proxy target for node ${nodeId} (${sanitizeForLog(node.name)})`);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const url = `${target.apiUrl.replace(/\/$/, '')}/api/mesh/local-services/${encodeURIComponent(stackName)}`;
|
const res = await this.proxyFetch(
|
||||||
const headers: Record<string, string> = {};
|
nodeId,
|
||||||
if (target.apiToken) headers['Authorization'] = `Bearer ${target.apiToken}`;
|
'GET',
|
||||||
const proxyHeaders = LicenseService.getInstance().getProxyHeaders();
|
`/api/mesh/local-services/${encodeURIComponent(stackName)}`,
|
||||||
headers[PROXY_TIER_HEADER] = proxyHeaders.tier;
|
undefined,
|
||||||
headers[PROXY_VARIANT_HEADER] = proxyHeaders.variant || '';
|
5_000,
|
||||||
const res = await fetch(url, { headers, signal: AbortSignal.timeout(5_000) });
|
);
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
console.error(`[MeshService] inspectStackServices: HTTP ${res.status} from node ${nodeId} (${sanitizeForLog(node.name)})`);
|
console.error(`[MeshService] inspectStackServices: HTTP ${res.status} from node ${nodeId} (${sanitizeForLog(node.name)})`);
|
||||||
return [];
|
return [];
|
||||||
@@ -1200,6 +1195,13 @@ export class MeshService extends EventEmitter implements MeshForwarderHost {
|
|||||||
const body = await res.json() as { services?: Array<{ service: string; ports: number[] }> };
|
const body = await res.json() as { services?: Array<{ service: string; ports: number[] }> };
|
||||||
return body.services ?? [];
|
return body.services ?? [];
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
// proxyFetch throws MeshError('push_failed') when getProxyTarget
|
||||||
|
// returns null (e.g. pilot tunnel offline). Treat the same as a
|
||||||
|
// non-OK response: empty list.
|
||||||
|
if (err instanceof MeshError && err.code === 'push_failed') {
|
||||||
|
console.warn(`[MeshService] inspectStackServices: no proxy target for node ${nodeId} (${sanitizeForLog(node.name)})`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
console.error('[MeshService] inspectStackServices remote unreachable:', sanitizeForLog((err as Error).message));
|
console.error('[MeshService] inspectStackServices remote unreachable:', sanitizeForLog((err as Error).message));
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user