@paperclipai/plugin-kubernetes 0.1.0 → 2026.620.0-canary.4
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/LICENSE +21 -0
- package/dist/adapter-defaults.d.ts +29 -0
- package/dist/adapter-defaults.d.ts.map +1 -0
- package/dist/adapter-defaults.js +104 -0
- package/dist/adapter-defaults.js.map +1 -0
- package/dist/adapter-registry.d.ts +64 -0
- package/dist/adapter-registry.d.ts.map +1 -0
- package/dist/adapter-registry.js +25 -0
- package/dist/adapter-registry.js.map +1 -0
- package/dist/cilium-network-policy.d.ts +8 -0
- package/dist/cilium-network-policy.d.ts.map +1 -0
- package/dist/cilium-network-policy.js +57 -0
- package/dist/cilium-network-policy.js.map +1 -0
- package/dist/image-allowlist.d.ts +18 -0
- package/dist/image-allowlist.d.ts.map +1 -0
- package/dist/image-allowlist.js +39 -0
- package/dist/image-allowlist.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/job-orchestrator.d.ts +24 -0
- package/dist/job-orchestrator.d.ts.map +1 -0
- package/dist/job-orchestrator.js +90 -0
- package/dist/job-orchestrator.js.map +1 -0
- package/dist/kube-client.d.ts +15 -0
- package/dist/kube-client.d.ts.map +1 -0
- package/dist/kube-client.js +23 -0
- package/dist/kube-client.js.map +1 -0
- package/dist/lease-lifecycle.d.ts +62 -0
- package/dist/lease-lifecycle.d.ts.map +1 -0
- package/dist/lease-lifecycle.js +155 -0
- package/dist/lease-lifecycle.js.map +1 -0
- package/dist/manifest.d.ts +4 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +108 -0
- package/dist/manifest.js.map +1 -0
- package/dist/network-policy.d.ts +18 -0
- package/dist/network-policy.d.ts.map +1 -0
- package/dist/network-policy.js +113 -0
- package/dist/network-policy.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +687 -0
- package/dist/plugin.js.map +1 -0
- package/dist/pod-exec.d.ts +28 -0
- package/dist/pod-exec.d.ts.map +1 -0
- package/dist/pod-exec.js +164 -0
- package/dist/pod-exec.js.map +1 -0
- package/dist/pod-spec-builder.d.ts +25 -0
- package/dist/pod-spec-builder.d.ts.map +1 -0
- package/dist/pod-spec-builder.js +82 -0
- package/dist/pod-spec-builder.js.map +1 -0
- package/dist/sandbox-cr-builder.d.ts +40 -0
- package/dist/sandbox-cr-builder.d.ts.map +1 -0
- package/dist/sandbox-cr-builder.js +123 -0
- package/dist/sandbox-cr-builder.js.map +1 -0
- package/dist/sandbox-cr-orchestrator.d.ts +62 -0
- package/dist/sandbox-cr-orchestrator.d.ts.map +1 -0
- package/dist/sandbox-cr-orchestrator.js +248 -0
- package/dist/sandbox-cr-orchestrator.js.map +1 -0
- package/dist/sandbox-orchestrator.d.ts +39 -0
- package/dist/sandbox-orchestrator.d.ts.map +1 -0
- package/dist/sandbox-orchestrator.js +2 -0
- package/dist/sandbox-orchestrator.js.map +1 -0
- package/dist/secret-manager.d.ts +14 -0
- package/dist/secret-manager.d.ts.map +1 -0
- package/dist/secret-manager.js +39 -0
- package/dist/secret-manager.js.map +1 -0
- package/dist/tenant-orchestrator.d.ts +35 -0
- package/dist/tenant-orchestrator.d.ts.map +1 -0
- package/dist/tenant-orchestrator.js +263 -0
- package/dist/tenant-orchestrator.js.map +1 -0
- package/dist/types.d.ts +264 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +65 -0
- package/dist/types.js.map +1 -0
- package/dist/upload-interceptor.d.ts +44 -0
- package/dist/upload-interceptor.d.ts.map +1 -0
- package/dist/upload-interceptor.js +114 -0
- package/dist/upload-interceptor.js.map +1 -0
- package/dist/utils.d.ts +11 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +51 -0
- package/dist/utils.js.map +1 -0
- package/dist/worker.d.ts +3 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +5 -0
- package/dist/worker.js.map +1 -0
- package/package.json +4 -12
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SandboxOrchestrator implementation backed by the kubernetes-sigs/agent-sandbox
|
|
3
|
+
* Sandbox CRD (agents.x-k8s.io/v1alpha1).
|
|
4
|
+
*
|
|
5
|
+
* The Sandbox CR creates a long-lived pod that paperclip-server can exec into
|
|
6
|
+
* for multi-command adapter-install workflows — the key architectural win over
|
|
7
|
+
* the batch/v1 Job backend.
|
|
8
|
+
*
|
|
9
|
+
* Key semantic differences from jobOrchestrator:
|
|
10
|
+
* - claim() creates a Sandbox CR via CustomObjectsApi instead of a batch Job
|
|
11
|
+
* - getStatus() maps Sandbox phase (Pending|Ready|Terminating|Failed) to SandboxStatus
|
|
12
|
+
* - findPod() reads status.podName from the Sandbox CR (falls back to label query)
|
|
13
|
+
* - waitForCompletion() means "wait until pod is Ready to exec" NOT "wait until
|
|
14
|
+
* workload finishes". The Sandbox pod runs sleep infinity; execution completion
|
|
15
|
+
* is tracked by the individual execInPod() calls.
|
|
16
|
+
* - release() deletes the Sandbox CR with Foreground propagation (controller
|
|
17
|
+
* tears down the underlying pod).
|
|
18
|
+
*
|
|
19
|
+
* NOTE: streamLogs() is provided for interface conformance but is limited —
|
|
20
|
+
* the sleep-infinity pod has no meaningful stdout. Callers in execute mode
|
|
21
|
+
* should use execInPod() and capture its stdout/stderr directly.
|
|
22
|
+
*/
|
|
23
|
+
const SANDBOX_GROUP = "agents.x-k8s.io";
|
|
24
|
+
const SANDBOX_VERSION = "v1alpha1";
|
|
25
|
+
const SANDBOX_PLURAL = "sandboxes";
|
|
26
|
+
export class SandboxCrTimeoutError extends Error {
|
|
27
|
+
constructor(namespace, name, timeoutMs) {
|
|
28
|
+
super(`Sandbox ${namespace}/${name} did not reach Ready phase within ${timeoutMs}ms`);
|
|
29
|
+
this.name = "SandboxCrTimeoutError";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function sleep(ms) {
|
|
33
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Map a Sandbox CR status.phase value to our SandboxStatus shape.
|
|
37
|
+
* Sandbox phases: Pending | Ready | Terminating | Failed
|
|
38
|
+
*/
|
|
39
|
+
function mapSandboxPhase(cr) {
|
|
40
|
+
const status = cr.status ?? {};
|
|
41
|
+
const phase = status.phase ?? "Pending";
|
|
42
|
+
switch (phase) {
|
|
43
|
+
case "Ready":
|
|
44
|
+
return {
|
|
45
|
+
phase: "Running", // SandboxStatus.phase uses Job semantics; "Running" = active pod
|
|
46
|
+
complete: false,
|
|
47
|
+
active: 1,
|
|
48
|
+
succeeded: 0,
|
|
49
|
+
failed: 0,
|
|
50
|
+
};
|
|
51
|
+
case "Terminating":
|
|
52
|
+
return {
|
|
53
|
+
phase: "Running",
|
|
54
|
+
complete: false,
|
|
55
|
+
active: 0,
|
|
56
|
+
succeeded: 0,
|
|
57
|
+
failed: 0,
|
|
58
|
+
reason: "Terminating",
|
|
59
|
+
};
|
|
60
|
+
case "Failed": {
|
|
61
|
+
const conditions = status.conditions ?? [];
|
|
62
|
+
const failedCond = conditions.find((c) => c.type === "Failed");
|
|
63
|
+
return {
|
|
64
|
+
phase: "Failed",
|
|
65
|
+
complete: false,
|
|
66
|
+
active: 0,
|
|
67
|
+
succeeded: 0,
|
|
68
|
+
failed: 1,
|
|
69
|
+
reason: failedCond?.reason,
|
|
70
|
+
message: failedCond?.message,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
default:
|
|
74
|
+
// "Pending" or unknown
|
|
75
|
+
return {
|
|
76
|
+
phase: "Pending",
|
|
77
|
+
complete: false,
|
|
78
|
+
active: 0,
|
|
79
|
+
succeeded: 0,
|
|
80
|
+
failed: 0,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export async function createSandboxCr(clients, namespace, manifest) {
|
|
85
|
+
const result = await clients.custom.createNamespacedCustomObject({
|
|
86
|
+
group: SANDBOX_GROUP,
|
|
87
|
+
version: SANDBOX_VERSION,
|
|
88
|
+
namespace,
|
|
89
|
+
plural: SANDBOX_PLURAL,
|
|
90
|
+
body: manifest,
|
|
91
|
+
});
|
|
92
|
+
const uid = result.metadata?.uid;
|
|
93
|
+
if (!uid)
|
|
94
|
+
throw new Error("Sandbox CR created without a UID");
|
|
95
|
+
return { uid };
|
|
96
|
+
}
|
|
97
|
+
export async function getSandboxCrStatus(clients, namespace, name) {
|
|
98
|
+
const result = await clients.custom.getNamespacedCustomObject({
|
|
99
|
+
group: SANDBOX_GROUP,
|
|
100
|
+
version: SANDBOX_VERSION,
|
|
101
|
+
namespace,
|
|
102
|
+
plural: SANDBOX_PLURAL,
|
|
103
|
+
name,
|
|
104
|
+
});
|
|
105
|
+
return mapSandboxPhase(result);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Returns the pod name backing a Sandbox CR.
|
|
109
|
+
* Primary: read status.podName from the CR (set by the controller once ready).
|
|
110
|
+
* Fallback: list pods in the namespace filtered by the paperclip.io/managed-by
|
|
111
|
+
* label and the sandbox name label set on the pod template.
|
|
112
|
+
*/
|
|
113
|
+
export async function findPodForSandbox(clients, namespace, name) {
|
|
114
|
+
// Primary: read status.podName from the Sandbox CR
|
|
115
|
+
const cr = await clients.custom.getNamespacedCustomObject({
|
|
116
|
+
group: SANDBOX_GROUP,
|
|
117
|
+
version: SANDBOX_VERSION,
|
|
118
|
+
namespace,
|
|
119
|
+
plural: SANDBOX_PLURAL,
|
|
120
|
+
name,
|
|
121
|
+
});
|
|
122
|
+
const status = cr.status ?? {};
|
|
123
|
+
const podName = status.podName;
|
|
124
|
+
if (podName && podName.trim().length > 0) {
|
|
125
|
+
return podName;
|
|
126
|
+
}
|
|
127
|
+
// Secondary: the agent-sandbox controller (v0.4.x) names the backing pod
|
|
128
|
+
// EXACTLY after the Sandbox CR and labels it only with
|
|
129
|
+
// agents.x-k8s.io/sandbox-name-hash (a hash, not the full name), so the
|
|
130
|
+
// full-name label selector below matches nothing on that controller. An
|
|
131
|
+
// exact-name GET is collision-free (unlike name-prefix matching, which
|
|
132
|
+
// could hit a concurrent sandbox sharing a prefix) and resolves the pod on
|
|
133
|
+
// every controller version that keeps pod name == sandbox name.
|
|
134
|
+
try {
|
|
135
|
+
const pod = (await clients.core.readNamespacedPod({ namespace, name }));
|
|
136
|
+
if (pod?.metadata?.name) {
|
|
137
|
+
return pod.metadata.name;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
const code = err.code ??
|
|
142
|
+
err.statusCode;
|
|
143
|
+
if (code !== 404)
|
|
144
|
+
throw err;
|
|
145
|
+
}
|
|
146
|
+
// Fallback: list pods by a full-name sandbox label, for controller versions
|
|
147
|
+
// that label pods with the sandbox name. A broader managed-by selector plus
|
|
148
|
+
// name-prefix narrowing could match a concurrent sandbox whose generated
|
|
149
|
+
// name shares a prefix, and exec would target the wrong lease's pod.
|
|
150
|
+
const result = await clients.core.listNamespacedPod({
|
|
151
|
+
namespace,
|
|
152
|
+
labelSelector: `agents.x-k8s.io/sandbox-name=${name}`,
|
|
153
|
+
});
|
|
154
|
+
const items = (result.items) ?? [];
|
|
155
|
+
// The label selector already scopes to exactly this sandbox's pod(s); keep a
|
|
156
|
+
// defensive re-check on the label value only (no name-prefix matching).
|
|
157
|
+
const matching = items.filter((p) => (p.metadata?.labels ?? {})["agents.x-k8s.io/sandbox-name"] === name);
|
|
158
|
+
const running = matching.find((p) => p.status?.phase === "Running");
|
|
159
|
+
return (running ?? matching[0])?.metadata?.name ?? null;
|
|
160
|
+
}
|
|
161
|
+
export async function streamSandboxLogs(clients, namespace, podName, onChunk) {
|
|
162
|
+
// V1 limitation: readNamespacedPodLog returns combined stdout. The
|
|
163
|
+
// sleep-infinity pod will have minimal output; this is provided for interface
|
|
164
|
+
// conformance. For actual command output, use execInPod() directly.
|
|
165
|
+
const result = await clients.core.readNamespacedPodLog({
|
|
166
|
+
namespace,
|
|
167
|
+
name: podName,
|
|
168
|
+
});
|
|
169
|
+
const text = result ?? "";
|
|
170
|
+
if (text.length > 0)
|
|
171
|
+
await onChunk("stdout", text);
|
|
172
|
+
}
|
|
173
|
+
export async function deleteSandboxCr(clients, namespace, name) {
|
|
174
|
+
await clients.custom.deleteNamespacedCustomObject({
|
|
175
|
+
group: SANDBOX_GROUP,
|
|
176
|
+
version: SANDBOX_VERSION,
|
|
177
|
+
namespace,
|
|
178
|
+
plural: SANDBOX_PLURAL,
|
|
179
|
+
name,
|
|
180
|
+
propagationPolicy: "Foreground",
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Wait until the Sandbox CR's pod reaches Ready phase (i.e., the pod is up and
|
|
185
|
+
* exec-able). This is NOT waiting for a workload to finish — the Sandbox pod
|
|
186
|
+
* runs sleep infinity indefinitely. Execution completion is tracked by the
|
|
187
|
+
* individual execInPod() calls.
|
|
188
|
+
*
|
|
189
|
+
* Throws SandboxCrTimeoutError if Ready is not reached within timeoutMs.
|
|
190
|
+
* Throws if the Sandbox transitions to Failed.
|
|
191
|
+
*/
|
|
192
|
+
export async function waitForSandboxReady(clients, namespace, name, opts = {
|
|
193
|
+
timeoutMs: 120_000,
|
|
194
|
+
pollMs: 2000,
|
|
195
|
+
}) {
|
|
196
|
+
const deadline = Date.now() + opts.timeoutMs;
|
|
197
|
+
const pollMs = opts.pollMs ?? 2000;
|
|
198
|
+
while (Date.now() < deadline) {
|
|
199
|
+
const cr = await clients.custom.getNamespacedCustomObject({
|
|
200
|
+
group: SANDBOX_GROUP,
|
|
201
|
+
version: SANDBOX_VERSION,
|
|
202
|
+
namespace,
|
|
203
|
+
plural: SANDBOX_PLURAL,
|
|
204
|
+
name,
|
|
205
|
+
});
|
|
206
|
+
const status = cr.status ?? {};
|
|
207
|
+
// agent-sandbox v1alpha1 uses status.conditions[type=Ready,status=True],
|
|
208
|
+
// not status.phase. Fall back to phase for forward-compat.
|
|
209
|
+
const conditions = Array.isArray(status.conditions) ? status.conditions : [];
|
|
210
|
+
const readyCondition = conditions.find((c) => c.type === "Ready");
|
|
211
|
+
const failedCondition = conditions.find((c) => c.type === "Failed" || (c.type === "Ready" && c.status === "False" && typeof c.reason === "string" && /failed/i.test(c.reason)));
|
|
212
|
+
const phase = status.phase ?? "";
|
|
213
|
+
if (readyCondition?.status === "True" || phase === "Ready") {
|
|
214
|
+
return mapSandboxPhase(cr);
|
|
215
|
+
}
|
|
216
|
+
if (failedCondition?.status === "True" || phase === "Failed") {
|
|
217
|
+
const mapped = mapSandboxPhase(cr);
|
|
218
|
+
throw new Error(`Sandbox ${namespace}/${name} failed: ${mapped.reason ?? failedCondition?.reason ?? "unknown reason"} — ${mapped.message ?? failedCondition?.message ?? ""}`);
|
|
219
|
+
}
|
|
220
|
+
if (phase === "Terminating") {
|
|
221
|
+
// A Sandbox being torn down will never transition to Ready. Polling
|
|
222
|
+
// until the deadline would burn the full timeoutMs (potentially
|
|
223
|
+
// 30+ minutes) before throwing a generic timeout. Fail fast instead
|
|
224
|
+
// so the caller can surface a clear "the lease is being released"
|
|
225
|
+
// error and decide whether to retry against a fresh Sandbox.
|
|
226
|
+
throw new Error(`Sandbox ${namespace}/${name} is Terminating — cannot wait for Ready`);
|
|
227
|
+
}
|
|
228
|
+
// Pending — keep polling
|
|
229
|
+
await sleep(pollMs);
|
|
230
|
+
}
|
|
231
|
+
throw new SandboxCrTimeoutError(namespace, name, opts.timeoutMs);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Sandbox CR-backed conformance to SandboxOrchestrator.
|
|
235
|
+
*
|
|
236
|
+
* waitForCompletion semantics change: for this backend, "completion" means
|
|
237
|
+
* "pod is up and Ready to exec into" — NOT "workload finished". The actual
|
|
238
|
+
* command execution and its completion is handled by execInPod().
|
|
239
|
+
*/
|
|
240
|
+
export const sandboxCrOrchestrator = {
|
|
241
|
+
claim: createSandboxCr,
|
|
242
|
+
getStatus: getSandboxCrStatus,
|
|
243
|
+
findPod: findPodForSandbox,
|
|
244
|
+
streamLogs: streamSandboxLogs,
|
|
245
|
+
release: deleteSandboxCr,
|
|
246
|
+
waitForCompletion: waitForSandboxReady,
|
|
247
|
+
};
|
|
248
|
+
//# sourceMappingURL=sandbox-cr-orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-cr-orchestrator.js","sourceRoot":"","sources":["../src/sandbox-cr-orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { KubeClients } from "./kube-client.js";
|
|
2
|
+
export interface SandboxStatus {
|
|
3
|
+
phase: "Pending" | "Running" | "Succeeded" | "Failed";
|
|
4
|
+
complete: boolean;
|
|
5
|
+
active: number;
|
|
6
|
+
succeeded: number;
|
|
7
|
+
failed: number;
|
|
8
|
+
reason?: string;
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Abstract interface over a sandbox runtime backend. The current implementation
|
|
13
|
+
* is Job-backed (job-orchestrator.ts). Future backends slot in by exporting an
|
|
14
|
+
* object conforming to this shape — e.g. a Kata-FC warm-pool backend that
|
|
15
|
+
* additionally implements the optional pause/resume slots, or a CRD-backed
|
|
16
|
+
* backend on kubernetes-sigs/agent-sandbox once it reaches Beta.
|
|
17
|
+
*/
|
|
18
|
+
export interface SandboxOrchestrator {
|
|
19
|
+
/** Provision the sandbox. Returns the runtime's stable UID. */
|
|
20
|
+
claim(clients: KubeClients, namespace: string, manifest: Record<string, unknown>): Promise<{
|
|
21
|
+
uid: string;
|
|
22
|
+
}>;
|
|
23
|
+
/** Read current lifecycle phase. */
|
|
24
|
+
getStatus(clients: KubeClients, namespace: string, name: string): Promise<SandboxStatus>;
|
|
25
|
+
/** Locate the pod backing this sandbox (or null if none exists yet). */
|
|
26
|
+
findPod(clients: KubeClients, namespace: string, name: string): Promise<string | null>;
|
|
27
|
+
/** Read logs from the sandbox's pod. V1: post-completion read. */
|
|
28
|
+
streamLogs(clients: KubeClients, namespace: string, podName: string, onChunk: (stream: "stdout" | "stderr", text: string) => Promise<void>): Promise<void>;
|
|
29
|
+
/** Tear down the sandbox. Implementations MUST cascade-delete child resources. */
|
|
30
|
+
release(clients: KubeClients, namespace: string, name: string): Promise<void>;
|
|
31
|
+
/** Block until phase is Succeeded or Failed, or throw on timeout. */
|
|
32
|
+
waitForCompletion(clients: KubeClients, namespace: string, name: string, opts: {
|
|
33
|
+
timeoutMs: number;
|
|
34
|
+
pollMs?: number;
|
|
35
|
+
}): Promise<SandboxStatus>;
|
|
36
|
+
pause?(clients: KubeClients, namespace: string, name: string): Promise<void>;
|
|
37
|
+
resume?(clients: KubeClients, namespace: string, name: string): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=sandbox-orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-orchestrator.d.ts","sourceRoot":"","sources":["../src/sandbox-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtD,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,KAAK,CACH,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE5B,oCAAoC;IACpC,SAAS,CACP,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1B,wEAAwE;IACxE,OAAO,CACL,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE1B,kEAAkE;IAClE,UAAU,CACR,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACpE,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB,kFAAkF;IAClF,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9E,qEAAqE;IACrE,iBAAiB,CACf,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC,aAAa,CAAC,CAAC;IAO1B,KAAK,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,MAAM,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-orchestrator.js","sourceRoot":"","sources":["../src/sandbox-orchestrator.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { KubeClients } from "./kube-client.js";
|
|
2
|
+
export interface CreatePerRunSecretInput {
|
|
3
|
+
namespace: string;
|
|
4
|
+
secretName: string;
|
|
5
|
+
runId: string;
|
|
6
|
+
ownerKind: string;
|
|
7
|
+
ownerApiVersion: string;
|
|
8
|
+
ownerName: string;
|
|
9
|
+
ownerUid: string;
|
|
10
|
+
bootstrapToken: string;
|
|
11
|
+
adapterEnv: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createPerRunSecret(clients: KubeClients, input: CreatePerRunSecretInput): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=secret-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-manager.d.ts","sourceRoot":"","sources":["../src/secret-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC5G"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export async function createPerRunSecret(clients, input) {
|
|
2
|
+
if (!input.ownerUid) {
|
|
3
|
+
throw new Error("createPerRunSecret requires a non-empty ownerUid");
|
|
4
|
+
}
|
|
5
|
+
if ("BOOTSTRAP_TOKEN" in input.adapterEnv) {
|
|
6
|
+
throw new Error("adapterEnv must not contain BOOTSTRAP_TOKEN (reserved key)");
|
|
7
|
+
}
|
|
8
|
+
await clients.core.createNamespacedSecret({
|
|
9
|
+
namespace: input.namespace,
|
|
10
|
+
body: {
|
|
11
|
+
apiVersion: "v1",
|
|
12
|
+
kind: "Secret",
|
|
13
|
+
type: "Opaque",
|
|
14
|
+
metadata: {
|
|
15
|
+
name: input.secretName,
|
|
16
|
+
namespace: input.namespace,
|
|
17
|
+
labels: {
|
|
18
|
+
"paperclip.io/run-id": input.runId,
|
|
19
|
+
"paperclip.io/managed-by": "paperclip-k8s-plugin",
|
|
20
|
+
},
|
|
21
|
+
ownerReferences: [
|
|
22
|
+
{
|
|
23
|
+
apiVersion: input.ownerApiVersion,
|
|
24
|
+
kind: input.ownerKind,
|
|
25
|
+
name: input.ownerName,
|
|
26
|
+
uid: input.ownerUid,
|
|
27
|
+
controller: true,
|
|
28
|
+
blockOwnerDeletion: true,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
stringData: {
|
|
33
|
+
BOOTSTRAP_TOKEN: input.bootstrapToken,
|
|
34
|
+
...input.adapterEnv,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=secret-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-manager.js","sourceRoot":"","sources":["../src/secret-manager.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAoB,EAAE,KAA8B;IAC3F,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,iBAAiB,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC;QACxC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,IAAI,EAAE;YACJ,UAAU,EAAE,IAAI;YAChB,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE;gBACR,IAAI,EAAE,KAAK,CAAC,UAAU;gBACtB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,MAAM,EAAE;oBACN,qBAAqB,EAAE,KAAK,CAAC,KAAK;oBAClC,yBAAyB,EAAE,sBAAsB;iBAClD;gBACD,eAAe,EAAE;oBACf;wBACE,UAAU,EAAE,KAAK,CAAC,eAAe;wBACjC,IAAI,EAAE,KAAK,CAAC,SAAS;wBACrB,IAAI,EAAE,KAAK,CAAC,SAAS;wBACrB,GAAG,EAAE,KAAK,CAAC,QAAQ;wBACnB,UAAU,EAAE,IAAI;wBAChB,kBAAkB,EAAE,IAAI;qBACzB;iBACF;aACF;YACD,UAAU,EAAE;gBACV,eAAe,EAAE,KAAK,CAAC,cAAc;gBACrC,GAAG,KAAK,CAAC,UAAU;aACpB;SACF;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { KubeClients } from "./kube-client.js";
|
|
2
|
+
export interface EnsureTenantInput {
|
|
3
|
+
namespace: string;
|
|
4
|
+
companyId: string;
|
|
5
|
+
paperclipServerNamespace: string;
|
|
6
|
+
serviceAccountAnnotations: Record<string, string>;
|
|
7
|
+
egressMode: "standard" | "cilium";
|
|
8
|
+
egressAllowFqdns: string[];
|
|
9
|
+
egressAllowCidrs: string[];
|
|
10
|
+
resourceQuota: {
|
|
11
|
+
pods: string;
|
|
12
|
+
requestsCpu: string;
|
|
13
|
+
requestsMemory: string;
|
|
14
|
+
limitsCpu: string;
|
|
15
|
+
limitsMemory: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Lazy, first-write-wins tenant provisioning. Each helper checks if the named
|
|
20
|
+
* resource exists and creates it only on 404; if it already exists, it is
|
|
21
|
+
* left as-is — config-driven values (quota limits, RBAC permissions, network
|
|
22
|
+
* policies, egress allow-list) are FROZEN at first provisioning time.
|
|
23
|
+
*
|
|
24
|
+
* V1 limitation: changing KubernetesProviderConfig after a tenant namespace
|
|
25
|
+
* is provisioned does NOT update the in-cluster resources. To apply config
|
|
26
|
+
* changes, an operator must delete the per-tenant resources manually (or
|
|
27
|
+
* the namespace itself). A future iteration should add strategic-merge
|
|
28
|
+
* reconciliation here.
|
|
29
|
+
*
|
|
30
|
+
* Particular gotcha: switching egressMode "standard" → "cilium" leaves the
|
|
31
|
+
* old paperclip-egress-allow NetworkPolicy in place alongside the new
|
|
32
|
+
* CiliumNetworkPolicy. Both apply; the effective egress is the intersection.
|
|
33
|
+
*/
|
|
34
|
+
export declare function ensureTenant(clients: KubeClients, input: EnsureTenantInput): Promise<void>;
|
|
35
|
+
//# sourceMappingURL=tenant-orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-orchestrator.d.ts","sourceRoot":"","sources":["../src/tenant-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;IACjC,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,UAAU,EAAE,UAAU,GAAG,QAAQ,CAAC;IAClC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAQD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhG"}
|