@kici-dev/orchestrator 0.14.1 → 0.15.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.
Files changed (49) hide show
  1. package/dist/__test-helpers__/peer-mutual-auth.d.ts +42 -0
  2. package/dist/agent/host-roster.d.ts +100 -37
  3. package/dist/app.d.ts +4 -2
  4. package/dist/cli/commands/host.d.ts +3 -0
  5. package/dist/cli/commands/source-manifest.d.ts +3 -3
  6. package/dist/cli/commands/source.d.ts +23 -0
  7. package/dist/cli/join.d.ts +2 -2
  8. package/dist/cli/kici-admin.d.ts +5 -0
  9. package/dist/cli/local-github-ingress-url.d.ts +6 -0
  10. package/dist/cli/root-option-routing.d.ts +46 -0
  11. package/dist/cli/webhook-url-notes.d.ts +15 -0
  12. package/dist/cli.js +1429 -885
  13. package/dist/cluster/coordinator-credential.d.ts +21 -0
  14. package/dist/cluster/index.d.ts +4 -4
  15. package/dist/cluster/join-client.d.ts +23 -21
  16. package/dist/cluster/join-handler.d.ts +24 -16
  17. package/dist/cluster/join-protocol-v2.d.ts +84 -0
  18. package/dist/cluster/join-token.d.ts +78 -56
  19. package/dist/cluster/peer-auth-coordinator.d.ts +16 -2
  20. package/dist/cluster/peer-client.d.ts +72 -4
  21. package/dist/cluster/peer-crypto.d.ts +60 -3
  22. package/dist/cluster/peer-discovery.d.ts +67 -0
  23. package/dist/cluster/peer-handler.d.ts +17 -5
  24. package/dist/cluster/peer-registry.d.ts +15 -1
  25. package/dist/config/schema.d.ts +14 -0
  26. package/dist/config/types.d.ts +4 -0
  27. package/dist/config.d.ts +9 -0
  28. package/dist/db/migrations/157_host_roster_identity_source.d.ts +21 -0
  29. package/dist/db/types.d.ts +16 -2
  30. package/dist/github-app-name-refresher/github-app-name-refresher.d.ts +25 -13
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +225 -81
  33. package/dist/providers/github/manifest.d.ts +58 -7
  34. package/dist/routes/admin-sources.d.ts +26 -23
  35. package/dist/routes/admin.d.ts +14 -17
  36. package/dist/routes/cluster-join.d.ts +13 -0
  37. package/dist/routes/github-webhook.d.ts +13 -11
  38. package/dist/scaler/bare-metal-backend.d.ts +42 -1
  39. package/dist/scaler/types.d.ts +7 -5
  40. package/dist/server.js +9040 -7631
  41. package/dist/sources/source-manager.d.ts +0 -24
  42. package/dist/sources/webhook-url-resolvers.d.ts +60 -0
  43. package/dist/standalone.js +9944 -8818
  44. package/dist/ws/dashboard-fleet-handler.d.ts +4 -3
  45. package/dist/ws/dashboard-fleet-write-handler.d.ts +7 -1
  46. package/dist/ws/platform-client.d.ts +18 -6
  47. package/installer-image-digests.json +3 -3
  48. package/package.json +4 -4
  49. package/sbom.spdx.json +53 -53
@@ -30,6 +30,7 @@ import type { BackendSyncManager, OrchestratorMode } from '@kici-dev/engine';
30
30
  import type { Kysely } from 'kysely';
31
31
  import type pg from 'pg';
32
32
  import type { AccessLogWriter } from '../audit/access-log.js';
33
+ import type { WebhookUrlResolution } from '../sources/webhook-url-resolvers.js';
33
34
  /**
34
35
  * Dependencies for admin API routes.
35
36
  */
@@ -42,10 +43,8 @@ export interface AdminRouteDeps {
42
43
  */
43
44
  databaseUrl?: string;
44
45
  /**
45
- * Orchestrator operating mode. Gates mode-specific admin behavior — today the
46
- * `observed`-mode refusal of GitHub-App source creation (those sources are
47
- * Platform-relayed by nature, and an observed orchestrator never accepts a
48
- * relay). Optional so WS-only / test admins can omit it.
46
+ * Orchestrator operating mode. Gates mode-specific admin behavior. Optional so
47
+ * WS-only / test admins can omit it.
49
48
  */
50
49
  mode?: OrchestratorMode;
51
50
  /**
@@ -104,26 +103,24 @@ export interface AdminRouteDeps {
104
103
  sourceStore?: SourceStore;
105
104
  /**
106
105
  * Optional -- resolves the public webhook URL for a newly added source so
107
- * `kici-admin source add` can print it. Wired in platform/hybrid mode to
108
- * register-and-await the Platform ack; independent mode returns a null URL
109
- * with a note.
106
+ * `kici-admin source add` can print it. The rules per mode live in
107
+ * `sources/webhook-url-resolvers.ts`.
110
108
  */
111
109
  resolveSourceWebhookUrl?: (params: {
112
110
  routingKey: string;
113
111
  provider: string;
114
112
  sourceId: string;
115
- }) => Promise<{
116
- webhookUrl: string | null;
117
- webhookNote?: string;
118
- }>;
113
+ }) => Promise<WebhookUrlResolution>;
119
114
  /**
120
115
  * Optional -- resolves the org-scoped GitHub webhook URL for the manifest
121
- * setup pre-flight (before any App exists). Wired in platform/hybrid mode.
122
- */
123
- resolveGithubWebhookUrl?: () => Promise<{
124
- webhookUrl: string | null;
125
- webhookNote?: string;
126
- }>;
116
+ * setup pre-flight (before any App exists), by mode.
117
+ */
118
+ resolveGithubWebhookUrl?: () => Promise<WebhookUrlResolution>;
119
+ /** Optional — builds the direct-ingress URL `source list` prints per GitHub source. */
120
+ resolveSourceIngressUrl?: (row: {
121
+ id: string;
122
+ customerId: string | null;
123
+ }) => string | null;
127
124
  /** Optional -- for DB migration endpoints. */
128
125
  db?: Kysely<any>;
129
126
  /** Optional -- for DB migration endpoints. */
@@ -0,0 +1,13 @@
1
+ /**
2
+ * POST /api/v1/cluster/join: the direct transport of `kici-admin join --peer`.
3
+ *
4
+ * The body is the same join.request the Platform relays. Unauthenticated by design:
5
+ * the joiner proves it holds a join token inside the request. A version-1 body (one
6
+ * that carries the token) is refused with 426 and `Upgrade: kici-join-v2`.
7
+ */
8
+ import { Hono } from 'hono';
9
+ import { type JoinResponse } from '@kici-dev/engine';
10
+ /** HTTP status for a join answer: a refusal without an error code is an internal failure. */
11
+ export declare function joinResponseHttpStatus(response: JoinResponse): 200 | 400 | 401 | 426 | 500;
12
+ export declare function createClusterJoinRoutes(onJoinRequest: (raw: unknown) => Promise<JoinResponse>): Hono;
13
+ //# sourceMappingURL=cluster-join.d.ts.map
@@ -25,19 +25,21 @@ export interface GithubWebhookRoutesDeps {
25
25
  */
26
26
  export declare function shouldServeGithubIngress(mode: OrchestratorMode): boolean;
27
27
  /**
28
- * Direct GitHub-App webhook ingress: `POST /webhook/:orgId/github/:sourceId`.
28
+ * Direct GitHub webhook ingress, bypassing the Platform relay:
29
29
  *
30
- * Bypasses the Platform relay. Handles both operator topologies on one route:
31
- * - App-level repoint: the App's single webhook URL points here, so GitHub
32
- * sends `X-GitHub-Hook-Installation-Target-Type: integration` +
33
- * `-Target-ID: <appId>` — validated against the source's routing key.
34
- * - Classic per-repo webhook: a repo-level hook points here with no App
35
- * target headers — `:sourceId` already identifies the source, so the
36
- * App-header check is skipped.
30
+ * - `POST /webhook/:orgId/github/:sourceId` (per-source) serves an App-level
31
+ * repoint (GitHub sends `X-GitHub-Hook-Installation-Target-Type:
32
+ * integration` + `-Target-ID: <appId>`, validated against the source's
33
+ * routing key) and a classic repository hook (no App target headers;
34
+ * `:sourceId` identifies the source).
35
+ * - `POST /webhook/:orgId/github` (org-scoped) serves an App-level webhook:
36
+ * the App's target id names the source. It is the URL the manifest flow
37
+ * bakes into a new App in observed and independent mode.
37
38
  *
38
- * Verification is the existing local `verify-inbound.ts` GitHub path (secret
39
- * read from the orchestrator secret store; rotation-aware). Dedup + dispatch
40
- * are the universal `processWebhook` pipeline via `onWebhook`.
39
+ * Both routes share verification (the local `verify-inbound.ts` GitHub path,
40
+ * secret read from the orchestrator secret store, rotation-aware), dedup on the
41
+ * raw `X-GitHub-Delivery`, and ingest through the `processWebhook` pipeline via
42
+ * `onWebhook`.
41
43
  */
42
44
  export declare function createGithubWebhookRoutes(deps: GithubWebhookRoutesDeps): Hono;
43
45
  //# sourceMappingURL=github-webhook.d.ts.map
@@ -49,6 +49,18 @@ export interface BareMetalScalerBackendOptions {
49
49
  * (`systemd-run` does not exist), with a one-time startup warning.
50
50
  */
51
51
  enforceCgroups?: boolean;
52
+ /**
53
+ * Run the `nft` calls of job-image mode (the scaler-level `requireSudo`)
54
+ * through `sudo -n`, for an orchestrator that runs as a non-root user with a
55
+ * NOPASSWD sudoers rule for nft. Process mode runs no nft. Default false.
56
+ */
57
+ requireSudo?: boolean;
58
+ /**
59
+ * Extra `host:address` mappings (the scaler-level `extraHosts`) for the agent
60
+ * containers of job-image mode, passed to the runtime as `ExtraHosts`.
61
+ * Process mode ignores them.
62
+ */
63
+ extraHosts?: string[];
52
64
  }
53
65
  export declare class BareMetalScalerBackend implements ScalerBackend {
54
66
  readonly type: "bare-metal";
@@ -71,7 +83,36 @@ export declare class BareMetalScalerBackend implements ScalerBackend {
71
83
  private readonly logCaptures;
72
84
  /** Container-mode agents' IPs on the isolated network, for nftables cleanup. */
73
85
  private readonly containerIps;
74
- constructor(options: BareMetalScalerBackendOptions);
86
+ /** Whether job-image mode's nft calls run through `sudo -n`. */
87
+ private readonly requireSudo;
88
+ private readonly extraHosts?;
89
+ /**
90
+ * Why this host cannot run nft the way {@link requireSudo} asks, as `create`
91
+ * probed it; `null` when it can. `reload` is synchronous and reads it to
92
+ * refuse job-image label sets a reload adds.
93
+ */
94
+ private readonly nftFailure;
95
+ /**
96
+ * Build a backend and check, once, that this host can run nft the way the
97
+ * scaler asks. A scaler with a job-image label set is refused here when it
98
+ * cannot, so the orchestrator stops at startup (and a reload that adds the
99
+ * scaler fails) instead of failing every spawn. A process-only scaler is
100
+ * never refused: process mode runs no nft.
101
+ */
102
+ static create(options: BareMetalScalerBackendOptions): Promise<BareMetalScalerBackend>;
103
+ /**
104
+ * @param nftFailure - The `create` probe's answer. A backend built directly
105
+ * was not probed, and is treated as able to run nft.
106
+ */
107
+ constructor(options: BareMetalScalerBackendOptions, nftFailure?: string | null);
108
+ /**
109
+ * Why a reload's job-image label sets cannot run here. `reload` is
110
+ * synchronous and cannot probe nft, so it reads what `create` probed — which
111
+ * holds only for the `requireSudo` the backend was built with.
112
+ */
113
+ private jobImageReloadErrors;
114
+ /** How every nft call of job-image mode runs: through `sudo -n` or not. */
115
+ private nftOpts;
75
116
  /**
76
117
  * Warn about label sets whose `networkPolicy` this backend cannot enforce.
77
118
  *
@@ -497,7 +497,8 @@ export interface ScalerEntry {
497
497
  orchestratorUrl?: string;
498
498
  /**
499
499
  * Extra host:IP mappings for spawned agents (e.g. ["registry.local:host-gateway"]): the
500
- * container runtime's ExtraHosts, or each Firecracker guest's /etc/hosts.
500
+ * container runtime's ExtraHosts (container scaler, bare-metal job-image agents), or
501
+ * each Firecracker guest's /etc/hosts.
501
502
  */
502
503
  extraHosts?: string[];
503
504
  /** Disable nftables-based network isolation for container backend (default: true). Set to false when nft is unavailable. */
@@ -564,10 +565,11 @@ export interface ScalerEntry {
564
565
  /** Default memory in MiB for VMs @default 512 */
565
566
  memSizeMib?: number;
566
567
  /**
567
- * Wrap privileged commands (`ip`, `chown`) with `sudo -n` when the
568
- * orchestrator runs as a non-root user (e.g. user-mode systemd on edge
569
- * worker nodes). Operators must have NOPASSWD sudoers entries for those
570
- * binaries. Default false.
568
+ * Wrap privileged commands with `sudo -n` when the orchestrator runs as a
569
+ * non-root user (e.g. user-mode systemd on edge worker nodes): the Firecracker
570
+ * backend's `ip`, `chown`, `chmod`, `kill` and `nft`, and the `nft` of a
571
+ * bare-metal scaler's job-image label sets. Operators must have NOPASSWD
572
+ * sudoers entries for those binaries. Default false.
571
573
  */
572
574
  requireSudo?: boolean;
573
575
  /**