@paperclipai/plugin-kubernetes 0.1.0 → 2026.620.0-canary.11
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,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resume + destroy lifecycle helpers for Kubernetes sandbox leases.
|
|
3
|
+
*
|
|
4
|
+
* Resume semantics: a lease is resumable only while its workload resource
|
|
5
|
+
* (Sandbox CR or Job) still exists and its pod is Running/Ready (or becomes
|
|
6
|
+
* Ready within a short bounded wait). Unlike Daytona — where a stopped sandbox
|
|
7
|
+
* can be started again by ID — Kubernetes pods are NOT restartable: once the
|
|
8
|
+
* pod backing a lease is gone or terminally failed, the lease can never be
|
|
9
|
+
* revived in place. That asymmetry is intentional; the plugin reports the
|
|
10
|
+
* lease as expired and the server falls back to a fresh acquireLease, which
|
|
11
|
+
* provisions a new pod.
|
|
12
|
+
*
|
|
13
|
+
* Destroy semantics: the forced cleanup path. Deletes every resource
|
|
14
|
+
* acquireLease created (Sandbox CR / Job, its pod, the per-run Secret),
|
|
15
|
+
* treating 404s as success so it is idempotent and safe to call against
|
|
16
|
+
* half-deleted leases.
|
|
17
|
+
*/
|
|
18
|
+
import type { KubeClients } from "./kube-client.js";
|
|
19
|
+
/** True when a Kubernetes API error means "resource not found" (HTTP 404). */
|
|
20
|
+
export declare function isKubeNotFoundError(err: unknown): boolean;
|
|
21
|
+
export type ResumeCheckResult = {
|
|
22
|
+
resumable: true;
|
|
23
|
+
podName: string | null;
|
|
24
|
+
phase: "Pending" | "Running";
|
|
25
|
+
} | {
|
|
26
|
+
resumable: false;
|
|
27
|
+
reason: string;
|
|
28
|
+
};
|
|
29
|
+
export interface ResumeCheckInput {
|
|
30
|
+
namespace: string;
|
|
31
|
+
/** Workload resource name (Sandbox CR name or Job name) == providerLeaseId. */
|
|
32
|
+
name: string;
|
|
33
|
+
backend: "sandbox-cr" | "job";
|
|
34
|
+
/** Bounded wait for an existing Sandbox pod to report Ready. */
|
|
35
|
+
readyTimeoutMs?: number;
|
|
36
|
+
pollMs?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check whether the workload behind a lease is still alive and exec-able.
|
|
40
|
+
* Returns `resumable: false` (never throws "expected" states) when the
|
|
41
|
+
* resource is gone (404), terminally failed, terminating, or doesn't become
|
|
42
|
+
* Ready within the bounded wait — all of which mean the caller should fall
|
|
43
|
+
* back to a fresh acquireLease.
|
|
44
|
+
*/
|
|
45
|
+
export declare function checkLeaseResumable(clients: KubeClients, input: ResumeCheckInput): Promise<ResumeCheckResult>;
|
|
46
|
+
export interface DestroyLeaseInput {
|
|
47
|
+
namespace: string;
|
|
48
|
+
/** Workload resource name (Sandbox CR name or Job name) == providerLeaseId. */
|
|
49
|
+
name: string;
|
|
50
|
+
backend: "sandbox-cr" | "job";
|
|
51
|
+
podName: string | null;
|
|
52
|
+
secretName: string | null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Forcibly delete every resource acquireLease created for this lease.
|
|
56
|
+
* Workload first (its deletion cascades to the pod and, via ownerReferences,
|
|
57
|
+
* the per-run Secret in the normal case); then the pod and Secret explicitly
|
|
58
|
+
* so a wedged controller or broken ownerRef cannot strand them. Every delete
|
|
59
|
+
* treats 404 as success — destroy is idempotent.
|
|
60
|
+
*/
|
|
61
|
+
export declare function destroyLeaseResources(clients: KubeClients, input: DestroyLeaseInput): Promise<void>;
|
|
62
|
+
//# sourceMappingURL=lease-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease-lifecycle.d.ts","sourceRoot":"","sources":["../src/lease-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQpD,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAIzD;AAUD,MAAM,MAAM,iBAAiB,GACzB;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,GACzE;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,GAAG,KAAK,CAAC;IAC9B,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAoF5B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,GAAG,KAAK,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,IAAI,CAAC,CAsBf"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resume + destroy lifecycle helpers for Kubernetes sandbox leases.
|
|
3
|
+
*
|
|
4
|
+
* Resume semantics: a lease is resumable only while its workload resource
|
|
5
|
+
* (Sandbox CR or Job) still exists and its pod is Running/Ready (or becomes
|
|
6
|
+
* Ready within a short bounded wait). Unlike Daytona — where a stopped sandbox
|
|
7
|
+
* can be started again by ID — Kubernetes pods are NOT restartable: once the
|
|
8
|
+
* pod backing a lease is gone or terminally failed, the lease can never be
|
|
9
|
+
* revived in place. That asymmetry is intentional; the plugin reports the
|
|
10
|
+
* lease as expired and the server falls back to a fresh acquireLease, which
|
|
11
|
+
* provisions a new pod.
|
|
12
|
+
*
|
|
13
|
+
* Destroy semantics: the forced cleanup path. Deletes every resource
|
|
14
|
+
* acquireLease created (Sandbox CR / Job, its pod, the per-run Secret),
|
|
15
|
+
* treating 404s as success so it is idempotent and safe to call against
|
|
16
|
+
* half-deleted leases.
|
|
17
|
+
*/
|
|
18
|
+
import { deleteJob, findPodForJob, getJobStatus } from "./job-orchestrator.js";
|
|
19
|
+
import { deleteSandboxCr, findPodForSandbox, waitForSandboxReady, } from "./sandbox-cr-orchestrator.js";
|
|
20
|
+
/** True when a Kubernetes API error means "resource not found" (HTTP 404). */
|
|
21
|
+
export function isKubeNotFoundError(err) {
|
|
22
|
+
const code = err.code
|
|
23
|
+
?? err.statusCode;
|
|
24
|
+
return code === 404;
|
|
25
|
+
}
|
|
26
|
+
async function ignoreNotFound(promise) {
|
|
27
|
+
try {
|
|
28
|
+
await promise;
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
if (!isKubeNotFoundError(err))
|
|
32
|
+
throw err;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check whether the workload behind a lease is still alive and exec-able.
|
|
37
|
+
* Returns `resumable: false` (never throws "expected" states) when the
|
|
38
|
+
* resource is gone (404), terminally failed, terminating, or doesn't become
|
|
39
|
+
* Ready within the bounded wait — all of which mean the caller should fall
|
|
40
|
+
* back to a fresh acquireLease.
|
|
41
|
+
*/
|
|
42
|
+
export async function checkLeaseResumable(clients, input) {
|
|
43
|
+
if (input.backend === "sandbox-cr") {
|
|
44
|
+
// Bounded wait for the Sandbox to report Ready. waitForSandboxReady fails
|
|
45
|
+
// fast on Failed/Terminating; a timeout means the pod never came up. None
|
|
46
|
+
// of those states are resumable — k8s pods cannot be restarted in place.
|
|
47
|
+
try {
|
|
48
|
+
await waitForSandboxReady(clients, input.namespace, input.name, {
|
|
49
|
+
timeoutMs: input.readyTimeoutMs ?? 30_000,
|
|
50
|
+
pollMs: input.pollMs ?? 1_000,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
if (isKubeNotFoundError(err)) {
|
|
55
|
+
return { resumable: false, reason: "Sandbox CR no longer exists" };
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
resumable: false,
|
|
59
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
let podName;
|
|
63
|
+
try {
|
|
64
|
+
podName = await findPodForSandbox(clients, input.namespace, input.name);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
// CR deleted between the readiness check and the pod lookup.
|
|
68
|
+
if (isKubeNotFoundError(err)) {
|
|
69
|
+
return { resumable: false, reason: "Sandbox CR no longer exists" };
|
|
70
|
+
}
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
if (!podName) {
|
|
74
|
+
return {
|
|
75
|
+
resumable: false,
|
|
76
|
+
reason: "Sandbox is Ready but no backing pod was found",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// Confirm the pod itself is Running and not being torn down — the CR
|
|
80
|
+
// status can lag pod deletion.
|
|
81
|
+
let pod;
|
|
82
|
+
try {
|
|
83
|
+
pod = await clients.core.readNamespacedPod({
|
|
84
|
+
namespace: input.namespace,
|
|
85
|
+
name: podName,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
if (isKubeNotFoundError(err)) {
|
|
90
|
+
return { resumable: false, reason: `Pod ${podName} no longer exists` };
|
|
91
|
+
}
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
const podPhase = pod.status?.phase;
|
|
95
|
+
const terminating = Boolean(pod.metadata?.deletionTimestamp);
|
|
96
|
+
if (podPhase !== "Running" || terminating) {
|
|
97
|
+
return {
|
|
98
|
+
resumable: false,
|
|
99
|
+
reason: `Pod ${podName} is ${terminating ? "terminating" : podPhase ?? "in an unknown phase"}`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return { resumable: true, podName, phase: "Running" };
|
|
103
|
+
}
|
|
104
|
+
// ── Job backend ───────────────────────────────────────────────────────────
|
|
105
|
+
let status;
|
|
106
|
+
try {
|
|
107
|
+
status = await getJobStatus(clients, input.namespace, input.name);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
if (isKubeNotFoundError(err)) {
|
|
111
|
+
return { resumable: false, reason: "Job no longer exists" };
|
|
112
|
+
}
|
|
113
|
+
throw err;
|
|
114
|
+
}
|
|
115
|
+
if (status.phase === "Succeeded" || status.phase === "Failed") {
|
|
116
|
+
// Terminal Jobs cannot be re-run in place.
|
|
117
|
+
return { resumable: false, reason: `Job is ${status.phase}` };
|
|
118
|
+
}
|
|
119
|
+
// Pending/Running Jobs are resumable: execute() waits for completion
|
|
120
|
+
// itself, so a not-yet-scheduled pod (podName null) is fine here.
|
|
121
|
+
const podName = await findPodForJob(clients, input.namespace, input.name);
|
|
122
|
+
return {
|
|
123
|
+
resumable: true,
|
|
124
|
+
podName,
|
|
125
|
+
phase: status.phase === "Running" ? "Running" : "Pending",
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Forcibly delete every resource acquireLease created for this lease.
|
|
130
|
+
* Workload first (its deletion cascades to the pod and, via ownerReferences,
|
|
131
|
+
* the per-run Secret in the normal case); then the pod and Secret explicitly
|
|
132
|
+
* so a wedged controller or broken ownerRef cannot strand them. Every delete
|
|
133
|
+
* treats 404 as success — destroy is idempotent.
|
|
134
|
+
*/
|
|
135
|
+
export async function destroyLeaseResources(clients, input) {
|
|
136
|
+
if (input.backend === "sandbox-cr") {
|
|
137
|
+
await ignoreNotFound(deleteSandboxCr(clients, input.namespace, input.name));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
await ignoreNotFound(deleteJob(clients, input.namespace, input.name));
|
|
141
|
+
}
|
|
142
|
+
if (input.podName) {
|
|
143
|
+
await ignoreNotFound(clients.core.deleteNamespacedPod({
|
|
144
|
+
namespace: input.namespace,
|
|
145
|
+
name: input.podName,
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
if (input.secretName) {
|
|
149
|
+
await ignoreNotFound(clients.core.deleteNamespacedSecret({
|
|
150
|
+
namespace: input.namespace,
|
|
151
|
+
name: input.secretName,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=lease-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease-lifecycle.js","sourceRoot":"","sources":["../src/lease-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAKzE,QAAA,MAAM,QAAQ,EAAE,yBAiHf,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const PLUGIN_ID = "paperclip.kubernetes-sandbox-provider";
|
|
2
|
+
const PLUGIN_VERSION = "0.1.0-alpha.1";
|
|
3
|
+
const manifest = {
|
|
4
|
+
id: PLUGIN_ID,
|
|
5
|
+
apiVersion: 1,
|
|
6
|
+
version: PLUGIN_VERSION,
|
|
7
|
+
displayName: "Kubernetes Sandbox (alpha)",
|
|
8
|
+
description: "Built on kubernetes-sigs/agent-sandbox (v1alpha1). ALPHA — expect breaking changes as the upstream CRD evolves. Falls back to stable batch/v1 Job mode for clusters without agent-sandbox installed. First-party Paperclip sandbox-provider plugin for Kubernetes.",
|
|
9
|
+
author: "Paperclip",
|
|
10
|
+
categories: ["automation"],
|
|
11
|
+
capabilities: ["environment.drivers.register"],
|
|
12
|
+
entrypoints: {
|
|
13
|
+
worker: "./dist/worker.js",
|
|
14
|
+
},
|
|
15
|
+
environmentDrivers: [
|
|
16
|
+
{
|
|
17
|
+
driverKey: "kubernetes",
|
|
18
|
+
kind: "sandbox_provider",
|
|
19
|
+
displayName: "Kubernetes",
|
|
20
|
+
description: "Dispatches agent runs in per-tenant Kubernetes namespaces. Default backend (sandbox-cr, alpha) uses kubernetes-sigs/agent-sandbox for multi-command exec; fallback backend (job) uses stable batch/v1 Job for clusters without agent-sandbox installed.",
|
|
21
|
+
configSchema: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
inCluster: {
|
|
25
|
+
type: "boolean",
|
|
26
|
+
description: "When true, the plugin uses the in-pod ServiceAccount credentials. Requires paperclip-server to be running inside the target cluster.",
|
|
27
|
+
},
|
|
28
|
+
kubeconfig: {
|
|
29
|
+
type: "string",
|
|
30
|
+
format: "secret-ref",
|
|
31
|
+
description: "Inline kubeconfig YAML. Paste a kubeconfig or an existing Paperclip secret reference; pasted values are stored as company secrets.",
|
|
32
|
+
},
|
|
33
|
+
namespacePrefix: {
|
|
34
|
+
type: "string",
|
|
35
|
+
description: "Prefix for the per-company tenant namespace (default: paperclip-).",
|
|
36
|
+
},
|
|
37
|
+
companySlug: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "Override the auto-derived company slug used in the tenant namespace name.",
|
|
40
|
+
},
|
|
41
|
+
imageRegistry: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "Override the default registry for agent runtime images (default: ghcr.io/paperclipai).",
|
|
44
|
+
},
|
|
45
|
+
imageAllowList: {
|
|
46
|
+
type: "array",
|
|
47
|
+
items: { type: "string" },
|
|
48
|
+
description: "Glob patterns of allowed `target.imageOverride` values. Empty list = no override permitted.",
|
|
49
|
+
},
|
|
50
|
+
imagePullSecrets: {
|
|
51
|
+
type: "array",
|
|
52
|
+
items: { type: "string" },
|
|
53
|
+
description: "Names of pre-created Docker image pull secrets in the tenant namespace.",
|
|
54
|
+
},
|
|
55
|
+
egressAllowFqdns: {
|
|
56
|
+
type: "array",
|
|
57
|
+
items: { type: "string" },
|
|
58
|
+
description: "Additional FQDNs to allow egress to from agent pods. Adapter-default FQDNs (e.g. api.anthropic.com) are added automatically.",
|
|
59
|
+
},
|
|
60
|
+
egressAllowCidrs: {
|
|
61
|
+
type: "array",
|
|
62
|
+
items: { type: "string" },
|
|
63
|
+
description: "Additional CIDRs to allow egress to from agent pods.",
|
|
64
|
+
},
|
|
65
|
+
egressMode: {
|
|
66
|
+
type: "string",
|
|
67
|
+
enum: ["standard", "cilium"],
|
|
68
|
+
description: "Network policy mode. `cilium` enables FQDN-based egress filtering via CiliumNetworkPolicy.",
|
|
69
|
+
},
|
|
70
|
+
runtimeClassName: {
|
|
71
|
+
type: "string",
|
|
72
|
+
description: "Optional RuntimeClass for pod isolation (e.g. `kata-fc` for Firecracker-backed microVMs). Cluster must have the RuntimeClass installed.",
|
|
73
|
+
},
|
|
74
|
+
serviceAccountAnnotations: {
|
|
75
|
+
type: "object",
|
|
76
|
+
additionalProperties: { type: "string" },
|
|
77
|
+
description: "Annotations applied to the per-tenant ServiceAccount (e.g. `eks.amazonaws.com/role-arn` for IRSA).",
|
|
78
|
+
},
|
|
79
|
+
jobTtlSecondsAfterFinished: {
|
|
80
|
+
type: "integer",
|
|
81
|
+
minimum: 0,
|
|
82
|
+
description: "Seconds after a Job completes before it is garbage-collected (default: 900).",
|
|
83
|
+
},
|
|
84
|
+
podActivityDeadlineSec: {
|
|
85
|
+
type: "integer",
|
|
86
|
+
minimum: 1,
|
|
87
|
+
description: "Hard ceiling on a single run's wall-clock time (default: 3600).",
|
|
88
|
+
},
|
|
89
|
+
adapterType: {
|
|
90
|
+
type: "string",
|
|
91
|
+
description: "The adapter type that Jobs in this environment will run (e.g. `claude_local`, `codex_local`). Defaults to `claude_local`. Each environment is bound to one adapter; create multiple environments for different adapters.",
|
|
92
|
+
},
|
|
93
|
+
backend: {
|
|
94
|
+
type: "string",
|
|
95
|
+
enum: ["sandbox-cr", "job"],
|
|
96
|
+
description: "sandbox-cr (default, alpha — requires kubernetes-sigs/agent-sandbox installed) | job (stable fallback — batch/v1 Job, one-shot entrypoint, no multi-command exec)",
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
anyOf: [
|
|
100
|
+
{ required: ["inCluster"] },
|
|
101
|
+
{ required: ["kubeconfig"] },
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
export default manifest;
|
|
108
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,MAAM,SAAS,GAAG,uCAAuC,CAAC;AAC1D,MAAM,cAAc,GAAG,eAAe,CAAC;AAEvC,MAAM,QAAQ,GAA8B;IAC1C,EAAE,EAAE,SAAS;IACb,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,cAAc;IACvB,WAAW,EAAE,4BAA4B;IACzC,WAAW,EACT,oQAAoQ;IACtQ,MAAM,EAAE,WAAW;IACnB,UAAU,EAAE,CAAC,YAAY,CAAC;IAC1B,YAAY,EAAE,CAAC,8BAA8B,CAAC;IAC9C,WAAW,EAAE;QACX,MAAM,EAAE,kBAAkB;KAC3B;IACD,kBAAkB,EAAE;QAClB;YACE,SAAS,EAAE,YAAY;YACvB,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,YAAY;YACzB,WAAW,EACT,yPAAyP;YAC3P,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,SAAS,EAAE;wBACT,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,sIAAsI;qBACzI;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,MAAM,EAAE,YAAY;wBACpB,WAAW,EACT,oIAAoI;qBACvI;oBACD,eAAe,EAAE;wBACf,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,oEAAoE;qBAClF;oBACD,WAAW,EAAE;wBACX,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,2EAA2E;qBACzF;oBACD,aAAa,EAAE;wBACb,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,wFAAwF;qBACtG;oBACD,cAAc,EAAE;wBACd,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACzB,WAAW,EACT,6FAA6F;qBAChG;oBACD,gBAAgB,EAAE;wBAChB,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACzB,WAAW,EAAE,yEAAyE;qBACvF;oBACD,gBAAgB,EAAE;wBAChB,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACzB,WAAW,EACT,8HAA8H;qBACjI;oBACD,gBAAgB,EAAE;wBAChB,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACzB,WAAW,EAAE,sDAAsD;qBACpE;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;wBAC5B,WAAW,EAAE,4FAA4F;qBAC1G;oBACD,gBAAgB,EAAE;wBAChB,IAAI,EAAE,QAAQ;wBACd,WAAW,EACT,yIAAyI;qBAC5I;oBACD,yBAAyB,EAAE;wBACzB,IAAI,EAAE,QAAQ;wBACd,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACxC,WAAW,EACT,oGAAoG;qBACvG;oBACD,0BAA0B,EAAE;wBAC1B,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,CAAC;wBACV,WAAW,EAAE,8EAA8E;qBAC5F;oBACD,sBAAsB,EAAE;wBACtB,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,CAAC;wBACV,WAAW,EAAE,iEAAiE;qBAC/E;oBACD,WAAW,EAAE;wBACX,IAAI,EAAE,QAAQ;wBACd,WAAW,EACT,0NAA0N;qBAC7N;oBACD,OAAO,EAAE;wBACP,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC;wBAC3B,WAAW,EACT,mKAAmK;qBACtK;iBACF;gBACD,KAAK,EAAE;oBACL,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE;oBAC3B,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE;iBAC7B;aACF;SACF;KACF;CACF,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface BuildNetworkPolicyInput {
|
|
2
|
+
namespace: string;
|
|
3
|
+
paperclipServerNamespace: string;
|
|
4
|
+
egressAllowCidrs: string[];
|
|
5
|
+
/**
|
|
6
|
+
* Adapter-configured FQDNs (e.g. `api.anthropic.com`). Standard
|
|
7
|
+
* NetworkPolicy cannot express FQDNs natively — only Cilium can.
|
|
8
|
+
* When this list is non-empty AND no explicit `egressAllowCidrs`
|
|
9
|
+
* was provided, the standard NetworkPolicy falls back to "public
|
|
10
|
+
* IPv4 except RFC1918/link-local/loopback/multicast" so the
|
|
11
|
+
* configured FQDNs at least become reachable. This is broader
|
|
12
|
+
* than the operator probably wants — switch to `egressMode:
|
|
13
|
+
* "cilium"` for exact FQDN allow-listing in production.
|
|
14
|
+
*/
|
|
15
|
+
egressAllowFqdns?: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function buildNetworkPolicyManifests(input: BuildNetworkPolicyInput): Record<string, unknown>[];
|
|
18
|
+
//# sourceMappingURL=network-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-policy.d.ts","sourceRoot":"","sources":["../src/network-policy.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;IACjC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AA2BD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAyFrG"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IPv4 ranges to carve out of `0.0.0.0/0` when we apply the
|
|
3
|
+
* public-internet fallback. Keeps agent pods from reaching cluster
|
|
4
|
+
* internals (RFC1918), node link-local + AWS IMDS (169.254.0.0/16),
|
|
5
|
+
* cluster loopback (127.0.0.0/8), CGNAT (100.64.0.0/10), this-network
|
|
6
|
+
* (0.0.0.0/8), and multicast (224.0.0.0/4).
|
|
7
|
+
*/
|
|
8
|
+
const PRIVATE_AND_LINK_LOCAL_EXCEPT_CIDRS = [
|
|
9
|
+
"0.0.0.0/8",
|
|
10
|
+
"10.0.0.0/8",
|
|
11
|
+
"100.64.0.0/10",
|
|
12
|
+
"127.0.0.0/8",
|
|
13
|
+
"169.254.0.0/16",
|
|
14
|
+
"172.16.0.0/12",
|
|
15
|
+
"192.168.0.0/16",
|
|
16
|
+
"224.0.0.0/4",
|
|
17
|
+
];
|
|
18
|
+
// Design note: the deny-all baseline blocks all ingress to agent pods.
|
|
19
|
+
// Paperclip-server does NOT push to agent pods — the agent shim makes
|
|
20
|
+
// outbound calls to paperclip-server via the egress allow-list (port 3100).
|
|
21
|
+
// This pull/callback model means no ingress rule is needed. If a future
|
|
22
|
+
// feature requires server→agent push (e.g. forced shutdown, live exec),
|
|
23
|
+
// add a targeted ingress rule here scoped to the paperclip-server pod
|
|
24
|
+
// selector.
|
|
25
|
+
export function buildNetworkPolicyManifests(input) {
|
|
26
|
+
const denyAll = {
|
|
27
|
+
apiVersion: "networking.k8s.io/v1",
|
|
28
|
+
kind: "NetworkPolicy",
|
|
29
|
+
metadata: {
|
|
30
|
+
name: "paperclip-deny-all",
|
|
31
|
+
namespace: input.namespace,
|
|
32
|
+
labels: { "paperclip.io/managed-by": "paperclip-k8s-plugin" },
|
|
33
|
+
},
|
|
34
|
+
spec: {
|
|
35
|
+
podSelector: {},
|
|
36
|
+
policyTypes: ["Ingress", "Egress"],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
const egressAllow = {
|
|
40
|
+
apiVersion: "networking.k8s.io/v1",
|
|
41
|
+
kind: "NetworkPolicy",
|
|
42
|
+
metadata: {
|
|
43
|
+
name: "paperclip-egress-allow",
|
|
44
|
+
namespace: input.namespace,
|
|
45
|
+
labels: { "paperclip.io/managed-by": "paperclip-k8s-plugin" },
|
|
46
|
+
},
|
|
47
|
+
spec: {
|
|
48
|
+
podSelector: { matchLabels: { "paperclip.io/role": "agent" } },
|
|
49
|
+
policyTypes: ["Egress"],
|
|
50
|
+
egress: [
|
|
51
|
+
{
|
|
52
|
+
to: [
|
|
53
|
+
{
|
|
54
|
+
namespaceSelector: { matchLabels: { "kubernetes.io/metadata.name": "kube-system" } },
|
|
55
|
+
podSelector: { matchLabels: { "k8s-app": "kube-dns" } },
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
ports: [
|
|
59
|
+
{ protocol: "UDP", port: 53 },
|
|
60
|
+
{ protocol: "TCP", port: 53 },
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
to: [
|
|
65
|
+
{
|
|
66
|
+
namespaceSelector: { matchLabels: { "kubernetes.io/metadata.name": input.paperclipServerNamespace } },
|
|
67
|
+
podSelector: { matchLabels: { app: "paperclip-server" } },
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
ports: [{ protocol: "TCP", port: 3100 }],
|
|
71
|
+
},
|
|
72
|
+
// NOTE: operator-supplied CIDRs are intentionally NOT port-scoped —
|
|
73
|
+
// operators may need them for non-HTTP services (e.g. private VCS
|
|
74
|
+
// mirrors, S3 endpoints, internal artifact registries). Operators
|
|
75
|
+
// should keep CIDRs as specific as possible. For HTTP/HTTPS-only
|
|
76
|
+
// LLM endpoints, the public-IPv4 fallback below is port-scoped
|
|
77
|
+
// (TCP 80/443).
|
|
78
|
+
...input.egressAllowCidrs.map((cidr) => ({
|
|
79
|
+
to: [{ ipBlock: { cidr } }],
|
|
80
|
+
})),
|
|
81
|
+
// Standard-NetworkPolicy fallback for FQDN-based egress. If the
|
|
82
|
+
// adapter requires FQDNs (e.g. api.anthropic.com) and the
|
|
83
|
+
// operator didn't supply explicit CIDRs, allow public IPv4 with
|
|
84
|
+
// private/link-local/loopback/multicast carved out. This makes
|
|
85
|
+
// the default `egressMode: "standard"` config functional out of
|
|
86
|
+
// the box for cloud LLM APIs without inadvertently exposing
|
|
87
|
+
// cluster internals or link-local metadata endpoints. Operators
|
|
88
|
+
// who want exact FQDN enforcement should use `egressMode: "cilium"`.
|
|
89
|
+
...(input.egressAllowCidrs.length === 0 &&
|
|
90
|
+
(input.egressAllowFqdns?.length ?? 0) > 0
|
|
91
|
+
? [
|
|
92
|
+
{
|
|
93
|
+
to: [
|
|
94
|
+
{
|
|
95
|
+
ipBlock: {
|
|
96
|
+
cidr: "0.0.0.0/0",
|
|
97
|
+
except: PRIVATE_AND_LINK_LOCAL_EXCEPT_CIDRS,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
ports: [
|
|
102
|
+
{ protocol: "TCP", port: 443 },
|
|
103
|
+
{ protocol: "TCP", port: 80 },
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
]
|
|
107
|
+
: []),
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
return [denyAll, egressAllow];
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=network-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-policy.js","sourceRoot":"","sources":["../src/network-policy.ts"],"names":[],"mappings":"AAiBA;;;;;;GAMG;AACH,MAAM,mCAAmC,GAAG;IAC1C,WAAW;IACX,YAAY;IACZ,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,aAAa;CACd,CAAC;AAEF,uEAAuE;AACvE,sEAAsE;AACtE,4EAA4E;AAC5E,wEAAwE;AACxE,wEAAwE;AACxE,sEAAsE;AACtE,YAAY;AACZ,MAAM,UAAU,2BAA2B,CAAC,KAA8B;IACxE,MAAM,OAAO,GAAG;QACd,UAAU,EAAE,sBAAsB;QAClC,IAAI,EAAE,eAAe;QACrB,QAAQ,EAAE;YACR,IAAI,EAAE,oBAAoB;YAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,EAAE,yBAAyB,EAAE,sBAAsB,EAAE;SAC9D;QACD,IAAI,EAAE;YACJ,WAAW,EAAE,EAAE;YACf,WAAW,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC;SACnC;KACF,CAAC;IAEF,MAAM,WAAW,GAA4B;QAC3C,UAAU,EAAE,sBAAsB;QAClC,IAAI,EAAE,eAAe;QACrB,QAAQ,EAAE;YACR,IAAI,EAAE,wBAAwB;YAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,EAAE,yBAAyB,EAAE,sBAAsB,EAAE;SAC9D;QACD,IAAI,EAAE;YACJ,WAAW,EAAE,EAAE,WAAW,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE;YAC9D,WAAW,EAAE,CAAC,QAAQ,CAAC;YACvB,MAAM,EAAE;gBACN;oBACE,EAAE,EAAE;wBACF;4BACE,iBAAiB,EAAE,EAAE,WAAW,EAAE,EAAE,6BAA6B,EAAE,aAAa,EAAE,EAAE;4BACpF,WAAW,EAAE,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE;yBACxD;qBACF;oBACD,KAAK,EAAE;wBACL,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;wBAC7B,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;qBAC9B;iBACF;gBACD;oBACE,EAAE,EAAE;wBACF;4BACE,iBAAiB,EAAE,EAAE,WAAW,EAAE,EAAE,6BAA6B,EAAE,KAAK,CAAC,wBAAwB,EAAE,EAAE;4BACrG,WAAW,EAAE,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,EAAE;yBAC1D;qBACF;oBACD,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;iBACzC;gBACD,oEAAoE;gBACpE,kEAAkE;gBAClE,kEAAkE;gBAClE,iEAAiE;gBACjE,+DAA+D;gBAC/D,gBAAgB;gBAChB,GAAG,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACvC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC;iBAC5B,CAAC,CAAC;gBACH,gEAAgE;gBAChE,0DAA0D;gBAC1D,gEAAgE;gBAChE,+DAA+D;gBAC/D,gEAAgE;gBAChE,4DAA4D;gBAC5D,gEAAgE;gBAChE,qEAAqE;gBACrE,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC;oBACrC,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;oBACzC,CAAC,CAAC;wBACE;4BACE,EAAE,EAAE;gCACF;oCACE,OAAO,EAAE;wCACP,IAAI,EAAE,WAAW;wCACjB,MAAM,EAAE,mCAAmC;qCAC5C;iCACF;6BACF;4BACD,KAAK,EAAE;gCACL,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE;gCAC9B,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;6BAC9B;yBACF;qBACF;oBACH,CAAC,CAAC,EAAE,CAAC;aACR;SACF;KACF,CAAC;IAEF,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAChC,CAAC"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AA+GA,QAAA,MAAM,MAAM,mDA8uBV,CAAC;AAEH,eAAe,MAAM,CAAC"}
|