@intentic/providers 1.125.0 → 1.126.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/authentik-api.d.ts.map +1 -1
- package/dist/auth/authentik-api.js +1 -0
- package/dist/auth/authentik-api.js.map +1 -1
- package/dist/auth/authentik.d.ts.map +1 -1
- package/dist/auth/authentik.js +22 -11
- package/dist/auth/authentik.js.map +1 -1
- package/dist/backings/garage-bucket.d.ts.map +1 -0
- package/dist/backings/garage-bucket.js.map +1 -0
- package/dist/backings/garage.d.ts.map +1 -0
- package/dist/{data → backings}/garage.js +21 -10
- package/dist/backings/garage.js.map +1 -0
- package/dist/backings/postgres-database.d.ts.map +1 -0
- package/dist/{data → backings}/postgres-database.js +4 -1
- package/dist/backings/postgres-database.js.map +1 -0
- package/dist/backings/postgres.d.ts.map +1 -0
- package/dist/{data → backings}/postgres.js +21 -10
- package/dist/backings/postgres.js.map +1 -0
- package/dist/backings/valkey-namespace.d.ts.map +1 -0
- package/dist/{data → backings}/valkey-namespace.js +4 -1
- package/dist/backings/valkey-namespace.js.map +1 -0
- package/dist/backings/valkey.d.ts.map +1 -0
- package/dist/{data → backings}/valkey.js +21 -10
- package/dist/backings/valkey.js.map +1 -0
- package/dist/backup/backup.d.ts.map +1 -1
- package/dist/backup/backup.js +6 -5
- package/dist/backup/backup.js.map +1 -1
- package/dist/core/backing-ssh.d.ts +1 -0
- package/dist/core/backing-ssh.d.ts.map +1 -1
- package/dist/core/backing-ssh.js +10 -1
- package/dist/core/backing-ssh.js.map +1 -1
- package/dist/core/inputs.d.ts +1 -0
- package/dist/core/inputs.d.ts.map +1 -1
- package/dist/core/inputs.js +1 -0
- package/dist/core/inputs.js.map +1 -1
- package/dist/core/list-stamped.d.ts +4 -0
- package/dist/core/list-stamped.d.ts.map +1 -0
- package/dist/core/list-stamped.js +54 -0
- package/dist/core/list-stamped.js.map +1 -0
- package/dist/core/over-ssh.d.ts +5 -0
- package/dist/core/over-ssh.d.ts.map +1 -0
- package/dist/core/over-ssh.js +20 -0
- package/dist/core/over-ssh.js.map +1 -0
- package/dist/core/response-detail.d.ts +2 -0
- package/dist/core/response-detail.d.ts.map +1 -0
- package/dist/core/response-detail.js +20 -0
- package/dist/core/response-detail.js.map +1 -0
- package/dist/core/ssh-diagnostics.d.ts +6 -0
- package/dist/core/ssh-diagnostics.d.ts.map +1 -0
- package/dist/core/ssh-diagnostics.js +46 -0
- package/dist/core/ssh-diagnostics.js.map +1 -0
- package/dist/core/ssh.d.ts +9 -0
- package/dist/core/ssh.d.ts.map +1 -1
- package/dist/core/ssh.js +102 -8
- package/dist/core/ssh.js.map +1 -1
- package/dist/forgejo/ci.d.ts +2 -1
- package/dist/forgejo/ci.d.ts.map +1 -1
- package/dist/forgejo/ci.js +57 -52
- package/dist/forgejo/ci.js.map +1 -1
- package/dist/forgejo/forgejo-api.d.ts.map +1 -1
- package/dist/forgejo/forgejo-api.js +3 -1
- package/dist/forgejo/forgejo-api.js.map +1 -1
- package/dist/forgejo/forgejo-notify.d.ts +2 -1
- package/dist/forgejo/forgejo-notify.d.ts.map +1 -1
- package/dist/forgejo/forgejo-notify.js +64 -59
- package/dist/forgejo/forgejo-notify.js.map +1 -1
- package/dist/forgejo/forgejo-org.d.ts +2 -1
- package/dist/forgejo/forgejo-org.d.ts.map +1 -1
- package/dist/forgejo/forgejo-org.js +18 -18
- package/dist/forgejo/forgejo-org.js.map +1 -1
- package/dist/forgejo/forgejo-runner.d.ts.map +1 -1
- package/dist/forgejo/forgejo-runner.js +15 -5
- package/dist/forgejo/forgejo-runner.js.map +1 -1
- package/dist/forgejo/forgejo-team.d.ts +2 -1
- package/dist/forgejo/forgejo-team.d.ts.map +1 -1
- package/dist/forgejo/forgejo-team.js +35 -33
- package/dist/forgejo/forgejo-team.js.map +1 -1
- package/dist/forgejo/forgejo-user.d.ts +2 -1
- package/dist/forgejo/forgejo-user.d.ts.map +1 -1
- package/dist/forgejo/forgejo-user.js +22 -22
- package/dist/forgejo/forgejo-user.js.map +1 -1
- package/dist/forgejo/forgejo.d.ts +1 -0
- package/dist/forgejo/forgejo.d.ts.map +1 -1
- package/dist/forgejo/forgejo.js +20 -9
- package/dist/forgejo/forgejo.js.map +1 -1
- package/dist/forgejo/repo.d.ts +2 -1
- package/dist/forgejo/repo.d.ts.map +1 -1
- package/dist/forgejo/repo.js +38 -38
- package/dist/forgejo/repo.js.map +1 -1
- package/dist/github/gh-ci.d.ts.map +1 -1
- package/dist/github/gh-ci.js +19 -35
- package/dist/github/gh-ci.js.map +1 -1
- package/dist/github/github-api.d.ts.map +1 -1
- package/dist/github/github-api.js +12 -4
- package/dist/github/github-api.js.map +1 -1
- package/dist/gitlab/gitlab-api.d.ts.map +1 -1
- package/dist/gitlab/gitlab-api.js +14 -5
- package/dist/gitlab/gitlab-api.js.map +1 -1
- package/dist/gitlab/gl-ci.d.ts.map +1 -1
- package/dist/gitlab/gl-ci.js +22 -34
- package/dist/gitlab/gl-ci.js.map +1 -1
- package/dist/host/host.d.ts.map +1 -1
- package/dist/host/host.js +4 -2
- package/dist/host/host.js.map +1 -1
- package/dist/host/workspace.d.ts.map +1 -1
- package/dist/host/workspace.js +15 -9
- package/dist/host/workspace.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/integrations/discord-api.d.ts.map +1 -1
- package/dist/integrations/discord-api.js +4 -3
- package/dist/integrations/discord-api.js.map +1 -1
- package/dist/integrations/stripe-api.d.ts.map +1 -1
- package/dist/integrations/stripe-api.js +1 -1
- package/dist/integrations/stripe-api.js.map +1 -1
- package/dist/komodo/deployment.d.ts +2 -1
- package/dist/komodo/deployment.d.ts.map +1 -1
- package/dist/komodo/deployment.js +36 -30
- package/dist/komodo/deployment.js.map +1 -1
- package/dist/komodo/komodo-api.d.ts.map +1 -1
- package/dist/komodo/komodo-api.js +5 -2
- package/dist/komodo/komodo-api.js.map +1 -1
- package/dist/komodo/komodo-notify.d.ts +2 -1
- package/dist/komodo/komodo-notify.d.ts.map +1 -1
- package/dist/komodo/komodo-notify.js +35 -30
- package/dist/komodo/komodo-notify.js.map +1 -1
- package/dist/komodo/komodo-periphery.d.ts.map +1 -1
- package/dist/komodo/komodo-periphery.js +5 -1
- package/dist/komodo/komodo-periphery.js.map +1 -1
- package/dist/komodo/komodo-server.d.ts +2 -1
- package/dist/komodo/komodo-server.d.ts.map +1 -1
- package/dist/komodo/komodo-server.js +30 -26
- package/dist/komodo/komodo-server.js.map +1 -1
- package/dist/komodo/komodo-user.d.ts +2 -1
- package/dist/komodo/komodo-user.d.ts.map +1 -1
- package/dist/komodo/komodo-user.js +36 -34
- package/dist/komodo/komodo-user.js.map +1 -1
- package/dist/komodo/komodo.d.ts +1 -0
- package/dist/komodo/komodo.d.ts.map +1 -1
- package/dist/komodo/komodo.js +38 -34
- package/dist/komodo/komodo.js.map +1 -1
- package/dist/network/cf-route.d.ts.map +1 -1
- package/dist/network/cf-route.js +30 -4
- package/dist/network/cf-route.js.map +1 -1
- package/dist/network/cloudflare-api.d.ts +13 -0
- package/dist/network/cloudflare-api.d.ts.map +1 -1
- package/dist/network/cloudflare-api.js +25 -7
- package/dist/network/cloudflare-api.js.map +1 -1
- package/dist/network/tunnel.d.ts.map +1 -1
- package/dist/network/tunnel.js +34 -9
- package/dist/network/tunnel.js.map +1 -1
- package/dist/observability/signoz.d.ts.map +1 -1
- package/dist/observability/signoz.js +22 -15
- package/dist/observability/signoz.js.map +1 -1
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +16 -20
- package/dist/providers.js.map +1 -1
- package/dist/services/compose-service.d.ts +1 -1
- package/dist/services/compose-service.d.ts.map +1 -1
- package/dist/services/compose-service.js +22 -15
- package/dist/services/compose-service.js.map +1 -1
- package/dist/services/infisical.js +3 -3
- package/dist/services/infisical.js.map +1 -1
- package/dist/services/invoiceninja.js +3 -3
- package/dist/services/invoiceninja.js.map +1 -1
- package/dist/services/openproject.d.ts.map +1 -1
- package/dist/services/openproject.js +4 -7
- package/dist/services/openproject.js.map +1 -1
- package/dist/services/outline.d.ts.map +1 -1
- package/dist/services/outline.js +13 -13
- package/dist/services/outline.js.map +1 -1
- package/dist/services/paperless.js +3 -3
- package/dist/services/paperless.js.map +1 -1
- package/package.json +7 -7
- package/dist/data/garage-bucket.d.ts.map +0 -1
- package/dist/data/garage-bucket.js.map +0 -1
- package/dist/data/garage.d.ts.map +0 -1
- package/dist/data/garage.js.map +0 -1
- package/dist/data/postgres-database.d.ts.map +0 -1
- package/dist/data/postgres-database.js.map +0 -1
- package/dist/data/postgres.d.ts.map +0 -1
- package/dist/data/postgres.js.map +0 -1
- package/dist/data/valkey-namespace.d.ts.map +0 -1
- package/dist/data/valkey-namespace.js.map +0 -1
- package/dist/data/valkey.d.ts.map +0 -1
- package/dist/data/valkey.js.map +0 -1
- package/dist/github/gh-deployment.d.ts +0 -4
- package/dist/github/gh-deployment.d.ts.map +0 -1
- package/dist/github/gh-deployment.js +0 -92
- package/dist/github/gh-deployment.js.map +0 -1
- package/dist/gitlab/gl-deployment.d.ts +0 -4
- package/dist/gitlab/gl-deployment.d.ts.map +0 -1
- package/dist/gitlab/gl-deployment.js +0 -93
- package/dist/gitlab/gl-deployment.js.map +0 -1
- /package/dist/{data → backings}/garage-bucket.d.ts +0 -0
- /package/dist/{data → backings}/garage-bucket.js +0 -0
- /package/dist/{data → backings}/garage.d.ts +0 -0
- /package/dist/{data → backings}/postgres-database.d.ts +0 -0
- /package/dist/{data → backings}/postgres.d.ts +0 -0
- /package/dist/{data → backings}/valkey-namespace.d.ts +0 -0
- /package/dist/{data → backings}/valkey.d.ts +0 -0
package/dist/backup/backup.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { parseInputs, sshSchema, sshTarget } from "../core/inputs.js";
|
|
3
|
+
import { listStampedContainers } from "../core/list-stamped.js";
|
|
3
4
|
import { sshExecutor } from "../core/ssh.js";
|
|
4
5
|
const backupSchema = sshSchema.extend({
|
|
5
6
|
repo: z.string(),
|
|
@@ -92,10 +93,10 @@ export const createBackupProvider = (executor = sshExecutor) => ({
|
|
|
92
93
|
return undefined;
|
|
93
94
|
}
|
|
94
95
|
try {
|
|
95
|
-
|
|
96
|
+
const [up, observed] = await Promise.all([running(session), observe(session)]);
|
|
97
|
+
if (!up) {
|
|
96
98
|
return undefined;
|
|
97
99
|
}
|
|
98
|
-
const observed = await observe(session);
|
|
99
100
|
return { outputs: {}, detail: observed };
|
|
100
101
|
}
|
|
101
102
|
finally {
|
|
@@ -126,7 +127,7 @@ export const createBackupProvider = (executor = sshExecutor) => ({
|
|
|
126
127
|
}
|
|
127
128
|
await ensureFiles(session, parsed);
|
|
128
129
|
await session.exec(`docker rm -f ${CONTAINER} 2>/dev/null || true`);
|
|
129
|
-
const run = await session.exec(`docker run -d --restart unless-stopped --name ${CONTAINER} --label intentic.id=${ctx.id} ` +
|
|
130
|
+
const run = await session.exec(`docker run -d --restart unless-stopped --name ${CONTAINER} --label intentic.id=${ctx.id} --label intentic.type=backup ` +
|
|
130
131
|
`--label "intentic.schedule=${parsed.schedule}" --label "intentic.repo=${parsed.repo}" ` +
|
|
131
132
|
`${mountArgs(parsed, dockerBin)} --entrypoint crond ${parsed.image} -f -l 8`);
|
|
132
133
|
if (run.code !== 0) {
|
|
@@ -139,8 +140,7 @@ export const createBackupProvider = (executor = sshExecutor) => ({
|
|
|
139
140
|
}
|
|
140
141
|
},
|
|
141
142
|
delete: async (inputs, ctx) => {
|
|
142
|
-
const
|
|
143
|
-
const session = await executor.connect(sshTarget(parsed));
|
|
143
|
+
const session = await executor.connect(sshTarget(parseInputs(sshSchema, inputs, "backup")));
|
|
144
144
|
try {
|
|
145
145
|
await session.exec(`docker rm -f ${CONTAINER} 2>/dev/null || true`);
|
|
146
146
|
await session.exec(`rm -rf ${STATE_DIR}`);
|
|
@@ -150,5 +150,6 @@ export const createBackupProvider = (executor = sshExecutor) => ({
|
|
|
150
150
|
await session.dispose();
|
|
151
151
|
}
|
|
152
152
|
},
|
|
153
|
+
list: (sources, ctx) => listStampedContainers(executor, "backup", sources, ctx.log),
|
|
153
154
|
});
|
|
154
155
|
//# sourceMappingURL=backup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/backup/backup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/backup/backup.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import type { SshSession } from "./ssh.js";
|
|
|
2
2
|
export declare const stateDir: (kind: string, id: string) => string;
|
|
3
3
|
export declare const containerId: (session: SshSession, stamp: string) => Promise<string>;
|
|
4
4
|
export declare const containerImage: (session: SshSession, stamp: string) => Promise<string>;
|
|
5
|
+
export declare const containerLabel: (session: SshSession, stamp: string, key: string) => Promise<string>;
|
|
5
6
|
export declare const composeUp: (session: SshSession, kind: string, id: string) => Promise<void>;
|
|
6
7
|
export declare const composeDown: (session: SshSession, kind: string, id: string) => Promise<void>;
|
|
7
8
|
export declare const restampBacking: (session: SshSession, kind: string, oldId: string, newId: string, image: string) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backing-ssh.d.ts","sourceRoot":"","sources":["../../src/core/backing-ssh.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backing-ssh.d.ts","sourceRoot":"","sources":["../../src/core/backing-ssh.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAe3C,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,EAAE,IAAI,MAAM,KAAG,MAA6C,CAAC;AAKlG,eAAO,MAAM,WAAW,GAAU,SAAS,UAAU,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,MAAM,CAGpF,CAAC;AAIF,eAAO,MAAM,cAAc,GAAU,SAAS,UAAU,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,MAAM,CAOvF,CAAC;AAIF,eAAO,MAAM,cAAc,GAAU,SAAS,UAAU,EAAE,OAAO,MAAM,EAAE,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,CAOpG,CAAC;AAGF,eAAO,MAAM,SAAS,GAAU,SAAS,UAAU,EAAE,MAAM,MAAM,EAAE,IAAI,MAAM,KAAG,OAAO,CAAC,IAAI,CAQ3F,CAAC;AAGF,eAAO,MAAM,WAAW,GAAU,SAAS,UAAU,EAAE,MAAM,MAAM,EAAE,IAAI,MAAM,KAAG,OAAO,CAAC,IAAI,CAM7F,CAAC;AAQF,eAAO,MAAM,cAAc,GAAU,SAAS,UAAU,EAAE,MAAM,MAAM,EAAE,OAAO,MAAM,EAAE,OAAO,MAAM,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CA0BjI,CAAC;AAGF,eAAO,MAAM,SAAS,GAAU,SAAS,UAAU,EAAE,MAAM,MAAM,EAAE,IAAI,MAAM,EAAE,OAAO,MAAM,EAAE,WAAW,MAAM,KAAG,OAAO,CAAC,IAAI,CAY7H,CAAC"}
|
package/dist/core/backing-ssh.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
1
2
|
const slug = (id) => id
|
|
2
3
|
.toLowerCase()
|
|
3
4
|
.replace(/[^a-z0-9]+/g, "-")
|
|
@@ -16,6 +17,14 @@ export const containerImage = async (session, stamp) => {
|
|
|
16
17
|
const result = await session.exec(`docker inspect --format '{{.Config.Image}}' ${id}`);
|
|
17
18
|
return result.stdout.trim();
|
|
18
19
|
};
|
|
20
|
+
export const containerLabel = async (session, stamp, key) => {
|
|
21
|
+
const id = await containerId(session, stamp);
|
|
22
|
+
if (id === "") {
|
|
23
|
+
return "";
|
|
24
|
+
}
|
|
25
|
+
const result = await session.exec(`docker inspect --format '{{index .Config.Labels "${key}"}}' ${id}`);
|
|
26
|
+
return result.stdout.trim();
|
|
27
|
+
};
|
|
19
28
|
export const composeUp = async (session, kind, id) => {
|
|
20
29
|
const dir = stateDir(kind, id);
|
|
21
30
|
const up = await session.exec(`docker compose -p ${projectName(kind, id)} --project-directory ${dir} --env-file ${dir}/.env -f ${dir}/compose.yaml up -d`);
|
|
@@ -61,7 +70,7 @@ export const waitReady = async (session, kind, id, probe, timeoutMs) => {
|
|
|
61
70
|
if (Date.now() >= deadline) {
|
|
62
71
|
throw new Error(`${kind} "${id}" did not become ready within ${timeoutMs}ms`);
|
|
63
72
|
}
|
|
64
|
-
await
|
|
73
|
+
await sleep(3_000);
|
|
65
74
|
}
|
|
66
75
|
};
|
|
67
76
|
//# sourceMappingURL=backing-ssh.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backing-ssh.js","sourceRoot":"","sources":["../../src/core/backing-ssh.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backing-ssh.js","sourceRoot":"","sources":["../../src/core/backing-ssh.ts"],"names":[],"mappings":"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"}
|
package/dist/core/inputs.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare const sshSchema: z.ZodObject<{
|
|
|
11
11
|
cloudflared: "cloudflared";
|
|
12
12
|
}>>;
|
|
13
13
|
}, z.core.$strip>;
|
|
14
|
+
export declare const hasPendingRef: (inputs: ResolvedInputs, ...fields: readonly string[]) => boolean;
|
|
14
15
|
export declare const parseInputs: <S extends z.ZodType>(schema: S, inputs: ResolvedInputs, label: string) => z.infer<S>;
|
|
15
16
|
export declare const parseResponse: <S extends z.ZodType>(schema: S, value: unknown, label: string) => z.infer<S>;
|
|
16
17
|
export declare const sshTarget: (parsed: z.infer<typeof sshSchema>) => SshTarget;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../src/core/inputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAO1C,eAAO,MAAM,SAAS;;;;;;;;;iBAMpB,CAAC;
|
|
1
|
+
{"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../src/core/inputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAO1C,eAAO,MAAM,SAAS;;;;;;;;;iBAMpB,CAAC;AAQH,eAAO,MAAM,aAAa,GAAI,QAAQ,cAAc,EAAE,GAAG,QAAQ,SAAS,MAAM,EAAE,KAAG,OACxB,CAAC;AAK9D,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,cAAc,EAAE,OAAO,MAAM,KAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAM5G,CAAC;AAMF,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,OAAO,EAAE,OAAO,MAAM,KAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAMtG,CAAC;AAGF,eAAO,MAAM,SAAS,GAAI,QAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,KAAG,SAM5D,CAAC;AAQH,eAAO,MAAM,WAAW,GAAI,YAAY,MAAM,KAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAG/E,CAAC;AAMH,eAAO,MAAM,aAAa,GAAI,MAAM;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAG,MACxC,CAAC"}
|
package/dist/core/inputs.js
CHANGED
|
@@ -7,6 +7,7 @@ export const sshSchema = z.object({
|
|
|
7
7
|
via: z.enum(["direct", "cloudflared"]).default("direct"),
|
|
8
8
|
});
|
|
9
9
|
const issues = (error) => error.issues.map((issue) => `${issue.path.join(".")} ${issue.message}`).join("; ");
|
|
10
|
+
export const hasPendingRef = (inputs, ...fields) => fields.some((field) => typeof inputs[field] === "symbol");
|
|
10
11
|
export const parseInputs = (schema, inputs, label) => {
|
|
11
12
|
const result = schema.safeParse(inputs);
|
|
12
13
|
if (!result.success) {
|
package/dist/core/inputs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputs.js","sourceRoot":"","sources":["../../src/core/inputs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5B,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;CAC3D,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,CAAC,KAAiB,EAAU,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"inputs.js","sourceRoot":"","sources":["../../src/core/inputs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5B,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;CAC3D,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,CAAC,KAAiB,EAAU,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAMjI,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAsB,EAAE,GAAG,MAAyB,EAAW,EAAE,CAC3F,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,CAAC;AAK9D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAsB,MAAS,EAAE,MAAsB,EAAE,KAAa,EAAc,EAAE;IAC7G,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,sBAAsB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACvB,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAsB,MAAS,EAAE,KAAc,EAAE,KAAa,EAAc,EAAE;IACvG,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,qCAAqC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACvB,CAAC,CAAC;AAGF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAiC,EAAa,EAAE,CAAC,CAAC;IACxE,OAAO,EAAE,MAAM,CAAC,OAAO;IACvB,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM;IACzB,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,GAAG,EAAE,MAAM,CAAC,GAAG;CAClB,CAAC,CAAC;AAQH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,UAAkB,EAAsC,EAAE,CAAC,CAAC;IACpF,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAClE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;CAC3C,CAAC,CAAC;AAMH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAwE,EAAU,EAAE,CAC9G,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ListedResource, ScanSource } from "@intentic/engine";
|
|
2
|
+
import type { SshExecutor } from "./ssh.js";
|
|
3
|
+
export declare const listStampedContainers: (executor: SshExecutor, kind: string, sources: readonly ScanSource[], log: (message: string) => void) => Promise<ListedResource[]>;
|
|
4
|
+
//# sourceMappingURL=list-stamped.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-stamped.d.ts","sourceRoot":"","sources":["../../src/core/list-stamped.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAiD5C,eAAO,MAAM,qBAAqB,GAC9B,UAAU,WAAW,EACrB,MAAM,MAAM,EACZ,SAAS,SAAS,UAAU,EAAE,EAC9B,KAAK,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,KAC/B,OAAO,CAAC,cAAc,EAAE,CA4B1B,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { parseInputs, sshSchema, sshTarget } from "./inputs.js";
|
|
2
|
+
const tablesByScan = new WeakMap();
|
|
3
|
+
const fetchHostTable = async (executor, source, log) => {
|
|
4
|
+
let session;
|
|
5
|
+
try {
|
|
6
|
+
session = await executor.connect(sshTarget(parseInputs(sshSchema, source.inputs, "host")));
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
log(`orphan scan: host "${source.id}" not reachable over SSH, skipping it for this scan: ${String(error)}`);
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const result = await session.exec(`docker ps -a --filter "label=intentic.type" --format '{{.Label "intentic.type"}}\t{{.Label "intentic.id"}}\t{{.Label "intentic.protect"}}'`);
|
|
14
|
+
const rows = [];
|
|
15
|
+
for (const line of result.stdout.trim().split("\n")) {
|
|
16
|
+
const [type, id, protect] = line.split("\t");
|
|
17
|
+
if (type === undefined || type === "" || id === undefined || id === "") {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
rows.push({ type, id, protected: protect === "true" });
|
|
21
|
+
}
|
|
22
|
+
return rows;
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
await session.dispose();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
export const listStampedContainers = async (executor, kind, sources, log) => {
|
|
29
|
+
let tables = tablesByScan.get(sources);
|
|
30
|
+
if (tables === undefined) {
|
|
31
|
+
tables = new Map();
|
|
32
|
+
tablesByScan.set(sources, tables);
|
|
33
|
+
}
|
|
34
|
+
const hostSources = sources.filter((source) => source.type === "host");
|
|
35
|
+
for (const source of hostSources) {
|
|
36
|
+
if (!tables.has(source.id)) {
|
|
37
|
+
tables.set(source.id, fetchHostTable(executor, source, log));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const fetched = await Promise.all(hostSources.map((source) => tables.get(source.id) ?? []));
|
|
41
|
+
const entries = [];
|
|
42
|
+
for (const [index, source] of hostSources.entries()) {
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
for (const row of fetched[index] ?? []) {
|
|
45
|
+
if (row.type !== kind || seen.has(row.id)) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
seen.add(row.id);
|
|
49
|
+
entries.push({ id: row.id, inputs: source.inputs, ...(row.protected ? { protected: true } : {}) });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return entries;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=list-stamped.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-stamped.js","sourceRoot":"","sources":["../../src/core/list-stamped.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { sshSchema } from "./inputs.js";
|
|
3
|
+
import type { SshExecutor } from "./ssh.js";
|
|
4
|
+
export declare const overSsh: <T>(executor: SshExecutor, ssh: z.infer<typeof sshSchema>, remotePort: number, fn: (baseUrl: string) => Promise<T>) => Promise<T>;
|
|
5
|
+
//# sourceMappingURL=over-ssh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"over-ssh.d.ts","sourceRoot":"","sources":["../../src/core/over-ssh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ5C,eAAO,MAAM,OAAO,GAAU,CAAC,EAC3B,UAAU,WAAW,EACrB,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,EAC9B,YAAY,MAAM,EAClB,IAAI,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,KACpC,OAAO,CAAC,CAAC,CAeX,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { sshTarget } from "./inputs.js";
|
|
2
|
+
export const overSsh = async (executor, ssh, remotePort, fn) => {
|
|
3
|
+
const session = await executor.connect(sshTarget(ssh));
|
|
4
|
+
try {
|
|
5
|
+
if (session.forward === undefined) {
|
|
6
|
+
throw new Error("ssh session does not support port forwarding");
|
|
7
|
+
}
|
|
8
|
+
const forwarded = await session.forward("127.0.0.1", remotePort);
|
|
9
|
+
try {
|
|
10
|
+
return await fn(`http://127.0.0.1:${forwarded.port}`);
|
|
11
|
+
}
|
|
12
|
+
finally {
|
|
13
|
+
await forwarded.close();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
finally {
|
|
17
|
+
await session.dispose();
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=over-ssh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"over-ssh.js","sourceRoot":"","sources":["../../src/core/over-ssh.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AASxC,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EACxB,QAAqB,EACrB,GAA8B,EAC9B,UAAkB,EAClB,EAAmC,EACzB,EAAE;IACZ,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,IAAI,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACjE,IAAI,CAAC;YACD,OAAO,MAAM,EAAE,CAAC,oBAAoB,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;gBAAS,CAAC;YACP,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;YAAS,CAAC;QACP,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-detail.d.ts","sourceRoot":"","sources":["../../src/core/response-detail.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,cAAc,GAAU,UAAU,QAAQ,KAAG,OAAO,CAAC,MAAM,CAYvE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const MAX_DETAIL = 300;
|
|
2
|
+
const CF_PAGE = /<title>[^<]*Cloudflare[^<]*<\/title>/i;
|
|
3
|
+
const CF_CODE = /errorCode:\s*(\d+)/;
|
|
4
|
+
const CF_HINTS = {
|
|
5
|
+
"1033": "the tunnel has no connected connector — cloudflared on the host is down or still re-registering",
|
|
6
|
+
};
|
|
7
|
+
export const responseDetail = async (response) => {
|
|
8
|
+
const body = await response.text();
|
|
9
|
+
const code = CF_PAGE.test(body) ? CF_CODE.exec(body)?.[1] : undefined;
|
|
10
|
+
if (code !== undefined) {
|
|
11
|
+
const hint = CF_HINTS[code];
|
|
12
|
+
return `Cloudflare edge error ${code}${hint === undefined ? "" : `: ${hint}`}`;
|
|
13
|
+
}
|
|
14
|
+
const text = body
|
|
15
|
+
.replace(/<[^>]+>/g, " ")
|
|
16
|
+
.replace(/\s+/g, " ")
|
|
17
|
+
.trim();
|
|
18
|
+
return text.length > MAX_DETAIL ? `${text.slice(0, MAX_DETAIL)}…` : text;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=response-detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-detail.js","sourceRoot":"","sources":["../../src/core/response-detail.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,GAAG,GAAG,CAAC;AAIvB,MAAM,OAAO,GAAG,uCAAuC,CAAC;AACxD,MAAM,OAAO,GAAG,oBAAoB,CAAC;AAErC,MAAM,QAAQ,GAA2B;IACrC,MAAM,EAAE,iGAAiG;CAC5G,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,QAAkB,EAAmB,EAAE;IACxE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,yBAAyB,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;IACnF,CAAC;IACD,MAAM,IAAI,GAAG,IAAI;SACZ,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACZ,OAAO,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7E,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SshExecutor, SshTarget } from "./ssh.js";
|
|
2
|
+
export declare const readinessDiagnostics: (targets: readonly SshTarget[], executor: SshExecutor, failure: {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly url: string;
|
|
5
|
+
}) => Promise<string>;
|
|
6
|
+
//# sourceMappingURL=ssh-diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-diagnostics.d.ts","sourceRoot":"","sources":["../../src/core/ssh-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAc,SAAS,EAAE,MAAM,UAAU,CAAC;AAOnE,eAAO,MAAM,oBAAoB,GAC7B,SAAS,SAAS,SAAS,EAAE,EAC7B,UAAU,WAAW,EACrB,SAAS;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KACvD,OAAO,CAAC,MAAM,CAGhB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export const readinessDiagnostics = async (targets, executor, failure) => {
|
|
2
|
+
const sections = await Promise.all(targets.map((target) => diagnoseHost(target, executor, failure)));
|
|
3
|
+
return sections.join("\n");
|
|
4
|
+
};
|
|
5
|
+
const diagnoseHost = async (target, executor, failure) => {
|
|
6
|
+
const lines = [`--- readiness diagnostics: ${target.user}@${target.address} (resource "${failure.id}", url ${failure.url}) ---`];
|
|
7
|
+
let session;
|
|
8
|
+
try {
|
|
9
|
+
session = await executor.connect(target);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
lines.push(`host ${target.address} unreachable over SSH: ${error instanceof Error ? error.message : String(error)}`);
|
|
13
|
+
return lines.join("\n");
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const run = async (command) => {
|
|
17
|
+
try {
|
|
18
|
+
const result = await session.exec(command);
|
|
19
|
+
const output = `${result.stdout}${result.stderr}`.trim();
|
|
20
|
+
return `$ ${command}\n${output === "" ? "(no output)" : output}${result.code === 0 ? "" : `\n(exit ${result.code})`}`;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
return `$ ${command}\nfailed: ${error instanceof Error ? error.message : String(error)}`;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
lines.push(await run("docker ps -a --format '{{.Names}}\t{{.Status}}\t{{.Image}}'"));
|
|
27
|
+
const labelled = await session.exec(`docker ps -a --filter label=intentic.id=${failure.id} --format '{{.Names}}'`).catch(() => undefined);
|
|
28
|
+
const names = labelled === undefined || labelled.code !== 0
|
|
29
|
+
? []
|
|
30
|
+
: labelled.stdout
|
|
31
|
+
.split("\n")
|
|
32
|
+
.map((line) => line.trim())
|
|
33
|
+
.filter((line) => line !== "");
|
|
34
|
+
for (const name of names) {
|
|
35
|
+
lines.push(await run(`docker logs --tail 50 ${name}`));
|
|
36
|
+
}
|
|
37
|
+
lines.push(await run("ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null"));
|
|
38
|
+
lines.push(await run("ip -4 -o addr"));
|
|
39
|
+
lines.push(await run(`wget -S -T 5 -O /dev/null ${failure.url} 2>&1`));
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
await session.dispose().catch(() => undefined);
|
|
43
|
+
}
|
|
44
|
+
return lines.join("\n");
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=ssh-diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-diagnostics.js","sourceRoot":"","sources":["../../src/core/ssh-diagnostics.ts"],"names":[],"mappings":"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"}
|
package/dist/core/ssh.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ export interface SshSession {
|
|
|
8
8
|
readonly dispose: () => Promise<void>;
|
|
9
9
|
readonly download?: (remotePath: string, localPath: string) => Promise<void>;
|
|
10
10
|
readonly upload?: (localPath: string, remotePath: string) => Promise<void>;
|
|
11
|
+
readonly forward?: (remoteHost: string, remotePort: number) => Promise<{
|
|
12
|
+
readonly port: number;
|
|
13
|
+
readonly close: () => Promise<void>;
|
|
14
|
+
}>;
|
|
11
15
|
}
|
|
12
16
|
export interface SshTarget {
|
|
13
17
|
readonly address: string;
|
|
@@ -26,6 +30,11 @@ export interface HostKeyStore {
|
|
|
26
30
|
}
|
|
27
31
|
export declare const inMemoryHostKeyStore: () => HostKeyStore;
|
|
28
32
|
export declare const verifyHostKey: (store: HostKeyStore, host: string, port: number, presented: string) => Promise<"ok" | "mismatch">;
|
|
33
|
+
export declare const connectWithRetry: (executor: SshExecutor, target: SshTarget, { timeoutMs, intervalMs, log, }?: {
|
|
34
|
+
timeoutMs?: number;
|
|
35
|
+
intervalMs?: number;
|
|
36
|
+
log?: (message: string) => void;
|
|
37
|
+
}) => Promise<SshSession>;
|
|
29
38
|
export declare const createSshExecutor: (store?: HostKeyStore) => SshExecutor;
|
|
30
39
|
export declare const sshExecutor: SshExecutor;
|
|
31
40
|
//# sourceMappingURL=ssh.d.ts.map
|
package/dist/core/ssh.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../src/core/ssh.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../src/core/ssh.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IAGvB,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3F,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAKtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAI3E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC,CAAC;CAC1I;AAED,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAItB,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;CAC3C;AAKD,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAKD,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC1E,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5E;AAOD,eAAO,MAAM,oBAAoB,QAAO,YASvC,CAAC;AAKF,eAAO,MAAM,aAAa,GAAU,OAAO,YAAY,EAAE,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,WAAW,MAAM,KAAG,OAAO,CAAC,IAAI,GAAG,UAAU,CAOjI,CAAC;AAwHF,eAAO,MAAM,gBAAgB,GACzB,UAAU,WAAW,EACrB,QAAQ,SAAS,EACjB,kCAIG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,KACrF,OAAO,CAAC,UAAU,CAapB,CAAC;AAOF,eAAO,MAAM,iBAAiB,GAAI,QAAO,YAAqC,KAAG,WAuMhF,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,WAAiC,CAAC"}
|
package/dist/core/ssh.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
2
3
|
import { createServer, connect as tcpConnect } from "node:net";
|
|
3
4
|
import { Client } from "ssh2";
|
|
4
5
|
const hostKeyId = (host, port) => `${host}:${port}`;
|
|
@@ -27,7 +28,6 @@ const collect = (stream, sink, onOutput) => {
|
|
|
27
28
|
onOutput?.(text);
|
|
28
29
|
});
|
|
29
30
|
};
|
|
30
|
-
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
31
31
|
const reserveLocalPort = () => new Promise((resolve, reject) => {
|
|
32
32
|
const probe = createServer();
|
|
33
33
|
probe.once("error", reject);
|
|
@@ -66,7 +66,13 @@ const waitForPort = async (port, failure, timeoutMs = 20000) => {
|
|
|
66
66
|
};
|
|
67
67
|
const startCloudflaredForwarder = async (hostname) => {
|
|
68
68
|
const port = await reserveLocalPort();
|
|
69
|
-
const child = spawn("cloudflared", ["access", "tcp", "--hostname", hostname, "--url", `127.0.0.1:${port}`], {
|
|
69
|
+
const child = spawn("cloudflared", ["access", "tcp", "--hostname", hostname, "--url", `127.0.0.1:${port}`], {
|
|
70
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
71
|
+
});
|
|
72
|
+
let stderr = "";
|
|
73
|
+
child.stderr?.on("data", (chunk) => {
|
|
74
|
+
stderr = (stderr + chunk.toString("utf8")).slice(-2000);
|
|
75
|
+
});
|
|
70
76
|
let exit;
|
|
71
77
|
child.once("error", (error) => {
|
|
72
78
|
exit = `spawn failed: ${error.message}`;
|
|
@@ -81,7 +87,28 @@ const startCloudflaredForwarder = async (hostname) => {
|
|
|
81
87
|
child.kill();
|
|
82
88
|
throw error;
|
|
83
89
|
}
|
|
84
|
-
return { port, child };
|
|
90
|
+
return { port, child, stderr: () => stderr };
|
|
91
|
+
};
|
|
92
|
+
const REACHABLE_TIMEOUT_MS = 60_000;
|
|
93
|
+
const REACHABLE_INTERVAL_MS = 3_000;
|
|
94
|
+
const READY_TIMEOUT_MS = 20_000;
|
|
95
|
+
const KEEPALIVE_INTERVAL_MS = 5_000;
|
|
96
|
+
const KEEPALIVE_COUNT_MAX = 3;
|
|
97
|
+
const EXEC_TIMEOUT_MS = 30 * 60_000;
|
|
98
|
+
export const connectWithRetry = async (executor, target, { timeoutMs = REACHABLE_TIMEOUT_MS, intervalMs = REACHABLE_INTERVAL_MS, log = () => { }, } = {}) => {
|
|
99
|
+
const deadline = Date.now() + timeoutMs;
|
|
100
|
+
for (let attempt = 1;; attempt++) {
|
|
101
|
+
try {
|
|
102
|
+
return await executor.connect(target);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (Date.now() >= deadline) {
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
log(`waiting for ${target.address}:${target.port} to become reachable (it may still be booting), retrying (attempt ${attempt})…`);
|
|
109
|
+
await delay(intervalMs);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
85
112
|
};
|
|
86
113
|
export const createSshExecutor = (store = inMemoryHostKeyStore()) => {
|
|
87
114
|
const forwarders = new Map();
|
|
@@ -95,21 +122,64 @@ export const createSshExecutor = (store = inMemoryHostKeyStore()) => {
|
|
|
95
122
|
forwarders.set(target.address, forwarder);
|
|
96
123
|
forwarder.catch(() => forwarders.delete(target.address));
|
|
97
124
|
}
|
|
98
|
-
|
|
125
|
+
const resolved = await forwarder;
|
|
126
|
+
return { host: "127.0.0.1", port: resolved.port, stderr: resolved.stderr };
|
|
99
127
|
};
|
|
100
128
|
return {
|
|
101
129
|
connect: async (target) => {
|
|
102
130
|
const endpoint = await dial(target);
|
|
103
131
|
return new Promise((resolve, reject) => {
|
|
104
132
|
const client = new Client();
|
|
105
|
-
|
|
133
|
+
const onError = (error) => {
|
|
134
|
+
if (endpoint.stderr === undefined) {
|
|
135
|
+
reject(error);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
setTimeout(() => {
|
|
139
|
+
const detail = endpoint.stderr?.().trim();
|
|
140
|
+
reject(detail ? new Error(`cloudflared tunnel to ${target.address} failed: ${error.message}\ncloudflared: ${detail}`) : error);
|
|
141
|
+
}, 50);
|
|
142
|
+
};
|
|
143
|
+
client.on("error", onError);
|
|
106
144
|
client.on("ready", () => {
|
|
107
|
-
client.removeListener("error",
|
|
145
|
+
client.removeListener("error", onError);
|
|
146
|
+
const inflight = new Set();
|
|
147
|
+
const failInflight = (error) => {
|
|
148
|
+
for (const failExec of inflight) {
|
|
149
|
+
failExec(error);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
client.on("error", failInflight);
|
|
153
|
+
client.on("close", () => failInflight(new Error(`ssh connection to ${target.address} closed before the command finished`)));
|
|
108
154
|
resolve({
|
|
109
155
|
exec: (command, onOutput) => new Promise((resolveExec, rejectExec) => {
|
|
156
|
+
let settled = false;
|
|
157
|
+
const fail = (error) => {
|
|
158
|
+
if (settled) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
settled = true;
|
|
162
|
+
inflight.delete(fail);
|
|
163
|
+
clearTimeout(timer);
|
|
164
|
+
rejectExec(error);
|
|
165
|
+
};
|
|
166
|
+
const finish = (result) => {
|
|
167
|
+
if (settled) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
settled = true;
|
|
171
|
+
inflight.delete(fail);
|
|
172
|
+
clearTimeout(timer);
|
|
173
|
+
resolveExec(result);
|
|
174
|
+
};
|
|
175
|
+
inflight.add(fail);
|
|
176
|
+
const timer = setTimeout(() => {
|
|
177
|
+
fail(new Error(`ssh exec timed out after ${EXEC_TIMEOUT_MS / 60_000}m: ${command}`));
|
|
178
|
+
client.end();
|
|
179
|
+
}, EXEC_TIMEOUT_MS);
|
|
110
180
|
client.exec(command, (error, stream) => {
|
|
111
181
|
if (error !== undefined) {
|
|
112
|
-
|
|
182
|
+
fail(error);
|
|
113
183
|
return;
|
|
114
184
|
}
|
|
115
185
|
const stdout = { value: "" };
|
|
@@ -121,7 +191,7 @@ export const createSshExecutor = (store = inMemoryHostKeyStore()) => {
|
|
|
121
191
|
code = exitCode ?? 0;
|
|
122
192
|
});
|
|
123
193
|
stream.on("close", () => {
|
|
124
|
-
|
|
194
|
+
finish({ stdout: stdout.value, stderr: stderr.value, code });
|
|
125
195
|
});
|
|
126
196
|
});
|
|
127
197
|
}),
|
|
@@ -149,6 +219,27 @@ export const createSshExecutor = (store = inMemoryHostKeyStore()) => {
|
|
|
149
219
|
sftp.fastPut(localPath, remotePath, (putError) => (putError ? rejectTransfer(putError) : resolveTransfer()));
|
|
150
220
|
});
|
|
151
221
|
}),
|
|
222
|
+
forward: (remoteHost, remotePort) => new Promise((resolveForward, rejectForward) => {
|
|
223
|
+
const server = createServer((socket) => {
|
|
224
|
+
client.forwardOut(socket.localAddress ?? "127.0.0.1", socket.localPort ?? 0, remoteHost, remotePort, (error, stream) => {
|
|
225
|
+
if (error) {
|
|
226
|
+
socket.destroy(error);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
socket.pipe(stream).pipe(socket);
|
|
230
|
+
stream.on("error", () => socket.destroy());
|
|
231
|
+
socket.on("error", () => stream.destroy());
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
server.once("error", rejectForward);
|
|
235
|
+
server.listen(0, "127.0.0.1", () => {
|
|
236
|
+
const address = server.address();
|
|
237
|
+
resolveForward({
|
|
238
|
+
port: typeof address === "object" && address !== null ? address.port : 0,
|
|
239
|
+
close: () => new Promise((resolveClose) => server.close(() => resolveClose())),
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
}),
|
|
152
243
|
});
|
|
153
244
|
});
|
|
154
245
|
client.connect({
|
|
@@ -156,6 +247,9 @@ export const createSshExecutor = (store = inMemoryHostKeyStore()) => {
|
|
|
156
247
|
port: endpoint.port,
|
|
157
248
|
username: target.user,
|
|
158
249
|
privateKey: target.privateKey,
|
|
250
|
+
readyTimeout: READY_TIMEOUT_MS,
|
|
251
|
+
keepaliveInterval: KEEPALIVE_INTERVAL_MS,
|
|
252
|
+
keepaliveCountMax: KEEPALIVE_COUNT_MAX,
|
|
159
253
|
hostVerifier: (key, callback) => {
|
|
160
254
|
verifyHostKey(store, target.address, target.port, key.toString("base64"))
|
|
161
255
|
.then((outcome) => {
|