@alibaba-group/opensandbox 0.1.4 → 0.1.6
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/README.md +102 -34
- package/dist/{chunk-OYTPXLWE.js → chunk-AFWIGM3C.js} +139 -29
- package/dist/chunk-AFWIGM3C.js.map +1 -0
- package/dist/cjs/index.cjs +277 -53
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/internal.cjs +137 -28
- package/dist/cjs/internal.cjs.map +1 -1
- package/dist/index.d.ts +33 -8
- package/dist/index.js +140 -25
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +292 -15
- package/dist/internal.js +1 -1
- package/dist/{sandboxes-Dc0G4ShU.d.ts → sandboxes-C-AZxcv6.d.ts} +234 -158
- package/package.json +4 -2
- package/src/adapters/commandsAdapter.ts +189 -27
- package/src/adapters/egressAdapter.ts +46 -0
- package/src/adapters/sandboxesAdapter.ts +8 -3
- package/src/api/egress.ts +184 -0
- package/src/api/execd.ts +216 -1
- package/src/api/lifecycle.ts +59 -13
- package/src/core/constants.ts +2 -1
- package/src/core/exceptions.ts +5 -4
- package/src/factory/adapterFactory.ts +13 -1
- package/src/factory/defaultAdapterFactory.ts +27 -2
- package/src/index.ts +3 -1
- package/src/models/execd.ts +12 -0
- package/src/models/execution.ts +2 -1
- package/src/models/sandboxes.ts +52 -7
- package/src/openapi/egressClient.ts +45 -0
- package/src/sandbox.ts +102 -25
- package/src/services/egress.ts +27 -0
- package/src/services/execdCommands.ts +27 -1
- package/src/services/sandboxes.ts +1 -1
- package/dist/chunk-OYTPXLWE.js.map +0 -1
|
@@ -33,14 +33,31 @@ function joinUrl(baseUrl: string, pathname: string): string {
|
|
|
33
33
|
return `${base}${path}`;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/** Request body for POST /command (from generated spec; includes uid, gid, envs). */
|
|
36
37
|
type ApiRunCommandRequest =
|
|
37
38
|
ExecdPaths["/command"]["post"]["requestBody"]["content"]["application/json"];
|
|
38
39
|
type ApiCommandStatusOk =
|
|
39
40
|
ExecdPaths["/command/status/{id}"]["get"]["responses"][200]["content"]["application/json"];
|
|
40
41
|
type ApiCommandLogsOk =
|
|
41
42
|
ExecdPaths["/command/{id}/logs"]["get"]["responses"][200]["content"]["text/plain"];
|
|
43
|
+
type ApiCreateSessionRequest =
|
|
44
|
+
NonNullable<ExecdPaths["/session"]["post"]["requestBody"]>["content"]["application/json"];
|
|
45
|
+
type ApiCreateSessionOk =
|
|
46
|
+
ExecdPaths["/session"]["post"]["responses"][200]["content"]["application/json"];
|
|
47
|
+
type ApiRunInSessionRequest =
|
|
48
|
+
ExecdPaths["/session/{sessionId}/run"]["post"]["requestBody"]["content"]["application/json"];
|
|
49
|
+
|
|
50
|
+
interface StreamingExecutionSpec<TBody> {
|
|
51
|
+
pathname: string;
|
|
52
|
+
body: TBody;
|
|
53
|
+
fallbackErrorMessage: string;
|
|
54
|
+
}
|
|
42
55
|
|
|
43
56
|
function toRunCommandRequest(command: string, opts?: RunCommandOpts): ApiRunCommandRequest {
|
|
57
|
+
if (opts?.gid != null && opts.uid == null) {
|
|
58
|
+
throw new Error("uid is required when gid is provided");
|
|
59
|
+
}
|
|
60
|
+
|
|
44
61
|
const body: ApiRunCommandRequest = {
|
|
45
62
|
command,
|
|
46
63
|
cwd: opts?.workingDirectory,
|
|
@@ -49,9 +66,51 @@ function toRunCommandRequest(command: string, opts?: RunCommandOpts): ApiRunComm
|
|
|
49
66
|
if (opts?.timeoutSeconds != null) {
|
|
50
67
|
body.timeout = Math.round(opts.timeoutSeconds * 1000);
|
|
51
68
|
}
|
|
69
|
+
if (opts?.uid != null) {
|
|
70
|
+
body.uid = opts.uid;
|
|
71
|
+
}
|
|
72
|
+
if (opts?.gid != null) {
|
|
73
|
+
body.gid = opts.gid;
|
|
74
|
+
}
|
|
75
|
+
if (opts?.envs != null) {
|
|
76
|
+
body.envs = opts.envs;
|
|
77
|
+
}
|
|
78
|
+
return body;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function toRunInSessionRequest(
|
|
82
|
+
command: string,
|
|
83
|
+
opts?: { workingDirectory?: string; timeoutSeconds?: number },
|
|
84
|
+
): ApiRunInSessionRequest {
|
|
85
|
+
const body: ApiRunInSessionRequest = {
|
|
86
|
+
command,
|
|
87
|
+
};
|
|
88
|
+
if (opts?.workingDirectory != null) {
|
|
89
|
+
body.cwd = opts.workingDirectory;
|
|
90
|
+
}
|
|
91
|
+
if (opts?.timeoutSeconds != null) {
|
|
92
|
+
body.timeout = Math.round(opts.timeoutSeconds * 1000);
|
|
93
|
+
}
|
|
52
94
|
return body;
|
|
53
95
|
}
|
|
54
96
|
|
|
97
|
+
function inferForegroundExitCode(execution: CommandExecution): number | null {
|
|
98
|
+
const errorValue = execution.error?.value?.trim();
|
|
99
|
+
const parsedExitCode =
|
|
100
|
+
errorValue && /^-?\d+$/.test(errorValue) ? Number(errorValue) : Number.NaN;
|
|
101
|
+
return execution.error != null
|
|
102
|
+
? (Number.isFinite(parsedExitCode) ? parsedExitCode : null)
|
|
103
|
+
: execution.complete
|
|
104
|
+
? 0
|
|
105
|
+
: null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function assertNonBlank(value: string, field: string): void {
|
|
109
|
+
if (!value.trim()) {
|
|
110
|
+
throw new Error(`${field} cannot be empty`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
55
114
|
function parseOptionalDate(value: unknown, field: string): Date | undefined {
|
|
56
115
|
if (value == null) return undefined;
|
|
57
116
|
if (value instanceof Date) return value;
|
|
@@ -84,6 +143,79 @@ export class CommandsAdapter implements ExecdCommands {
|
|
|
84
143
|
this.fetch = opts.fetch ?? fetch;
|
|
85
144
|
}
|
|
86
145
|
|
|
146
|
+
private buildRunStreamSpec(
|
|
147
|
+
command: string,
|
|
148
|
+
opts?: RunCommandOpts,
|
|
149
|
+
): StreamingExecutionSpec<ApiRunCommandRequest> {
|
|
150
|
+
assertNonBlank(command, "command");
|
|
151
|
+
return {
|
|
152
|
+
pathname: "/command",
|
|
153
|
+
body: toRunCommandRequest(command, opts),
|
|
154
|
+
fallbackErrorMessage: "Run command failed",
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private buildRunInSessionStreamSpec(
|
|
159
|
+
sessionId: string,
|
|
160
|
+
command: string,
|
|
161
|
+
opts?: { workingDirectory?: string; timeoutSeconds?: number },
|
|
162
|
+
): StreamingExecutionSpec<ApiRunInSessionRequest> {
|
|
163
|
+
assertNonBlank(sessionId, "sessionId");
|
|
164
|
+
assertNonBlank(command, "command");
|
|
165
|
+
return {
|
|
166
|
+
pathname: `/session/${encodeURIComponent(sessionId)}/run`,
|
|
167
|
+
body: toRunInSessionRequest(command, opts),
|
|
168
|
+
fallbackErrorMessage: "Run in session failed",
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private async *streamExecution<TBody>(
|
|
173
|
+
spec: StreamingExecutionSpec<TBody>,
|
|
174
|
+
signal?: AbortSignal,
|
|
175
|
+
): AsyncIterable<ServerStreamEvent> {
|
|
176
|
+
const url = joinUrl(this.opts.baseUrl, spec.pathname);
|
|
177
|
+
const res = await this.fetch(url, {
|
|
178
|
+
method: "POST",
|
|
179
|
+
headers: {
|
|
180
|
+
accept: "text/event-stream",
|
|
181
|
+
"content-type": "application/json",
|
|
182
|
+
...(this.opts.headers ?? {}),
|
|
183
|
+
},
|
|
184
|
+
body: JSON.stringify(spec.body),
|
|
185
|
+
signal,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
for await (const ev of parseJsonEventStream<ServerStreamEvent>(res, {
|
|
189
|
+
fallbackErrorMessage: spec.fallbackErrorMessage,
|
|
190
|
+
})) {
|
|
191
|
+
yield ev;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private async consumeExecutionStream(
|
|
196
|
+
stream: AsyncIterable<ServerStreamEvent>,
|
|
197
|
+
handlers?: ExecutionHandlers,
|
|
198
|
+
inferExitCode = false,
|
|
199
|
+
): Promise<CommandExecution> {
|
|
200
|
+
const execution: CommandExecution = {
|
|
201
|
+
logs: { stdout: [], stderr: [] },
|
|
202
|
+
result: [],
|
|
203
|
+
};
|
|
204
|
+
const dispatcher = new ExecutionEventDispatcher(execution, handlers);
|
|
205
|
+
for await (const ev of stream) {
|
|
206
|
+
if (ev.type === "init" && (ev.text ?? "") === "" && execution.id) {
|
|
207
|
+
(ev as { text?: string }).text = execution.id;
|
|
208
|
+
}
|
|
209
|
+
await dispatcher.dispatch(ev as any);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (inferExitCode) {
|
|
213
|
+
execution.exitCode = inferForegroundExitCode(execution);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return execution;
|
|
217
|
+
}
|
|
218
|
+
|
|
87
219
|
async interrupt(sessionId: string): Promise<void> {
|
|
88
220
|
const { error, response } = await this.client.DELETE("/command", {
|
|
89
221
|
params: { query: { id: sessionId } },
|
|
@@ -134,21 +266,10 @@ export class CommandsAdapter implements ExecdCommands {
|
|
|
134
266
|
opts?: RunCommandOpts,
|
|
135
267
|
signal?: AbortSignal,
|
|
136
268
|
): AsyncIterable<ServerStreamEvent> {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const res = await this.fetch(url, {
|
|
141
|
-
method: "POST",
|
|
142
|
-
headers: {
|
|
143
|
-
"accept": "text/event-stream",
|
|
144
|
-
"content-type": "application/json",
|
|
145
|
-
...(this.opts.headers ?? {}),
|
|
146
|
-
},
|
|
147
|
-
body,
|
|
269
|
+
for await (const ev of this.streamExecution(
|
|
270
|
+
this.buildRunStreamSpec(command, opts),
|
|
148
271
|
signal,
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
for await (const ev of parseJsonEventStream<ServerStreamEvent>(res, { fallbackErrorMessage: "Run command failed" })) {
|
|
272
|
+
)) {
|
|
152
273
|
yield ev;
|
|
153
274
|
}
|
|
154
275
|
}
|
|
@@ -159,19 +280,60 @@ export class CommandsAdapter implements ExecdCommands {
|
|
|
159
280
|
handlers?: ExecutionHandlers,
|
|
160
281
|
signal?: AbortSignal,
|
|
161
282
|
): Promise<CommandExecution> {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
283
|
+
return this.consumeExecutionStream(
|
|
284
|
+
this.runStream(command, opts, signal),
|
|
285
|
+
handlers,
|
|
286
|
+
!opts?.background,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
async createSession(options?: { workingDirectory?: string }): Promise<string> {
|
|
291
|
+
const body: ApiCreateSessionRequest =
|
|
292
|
+
options?.workingDirectory != null ? { cwd: options.workingDirectory } : {};
|
|
293
|
+
const { data, error, response } = await this.client.POST("/session", {
|
|
294
|
+
body,
|
|
295
|
+
});
|
|
296
|
+
throwOnOpenApiFetchError({ error, response }, "Create session failed");
|
|
297
|
+
const ok = data as ApiCreateSessionOk | undefined;
|
|
298
|
+
if (!ok || typeof (ok as { session_id?: string }).session_id !== "string") {
|
|
299
|
+
throw new Error("Create session failed: unexpected response shape");
|
|
173
300
|
}
|
|
301
|
+
return (ok as { session_id: string }).session_id;
|
|
302
|
+
}
|
|
174
303
|
|
|
175
|
-
|
|
304
|
+
async *runInSessionStream(
|
|
305
|
+
sessionId: string,
|
|
306
|
+
command: string,
|
|
307
|
+
opts?: { workingDirectory?: string; timeoutSeconds?: number },
|
|
308
|
+
signal?: AbortSignal,
|
|
309
|
+
): AsyncIterable<ServerStreamEvent> {
|
|
310
|
+
for await (const ev of this.streamExecution(
|
|
311
|
+
this.buildRunInSessionStreamSpec(sessionId, command, opts),
|
|
312
|
+
signal,
|
|
313
|
+
)) {
|
|
314
|
+
yield ev;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
async runInSession(
|
|
319
|
+
sessionId: string,
|
|
320
|
+
command: string,
|
|
321
|
+
options?: { workingDirectory?: string; timeoutSeconds?: number },
|
|
322
|
+
handlers?: ExecutionHandlers,
|
|
323
|
+
signal?: AbortSignal,
|
|
324
|
+
): Promise<CommandExecution> {
|
|
325
|
+
return this.consumeExecutionStream(
|
|
326
|
+
this.runInSessionStream(sessionId, command, options, signal),
|
|
327
|
+
handlers,
|
|
328
|
+
true,
|
|
329
|
+
);
|
|
176
330
|
}
|
|
177
|
-
|
|
331
|
+
|
|
332
|
+
async deleteSession(sessionId: string): Promise<void> {
|
|
333
|
+
const { error, response } = await this.client.DELETE(
|
|
334
|
+
"/session/{sessionId}",
|
|
335
|
+
{ params: { path: { sessionId } } },
|
|
336
|
+
);
|
|
337
|
+
throwOnOpenApiFetchError({ error, response }, "Delete session failed");
|
|
338
|
+
}
|
|
339
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Copyright 2026 Alibaba Group Holding Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import type { EgressClient } from "../openapi/egressClient.js";
|
|
16
|
+
import { throwOnOpenApiFetchError } from "./openapiError.js";
|
|
17
|
+
import type { paths as EgressPaths } from "../api/egress.js";
|
|
18
|
+
import type { NetworkPolicy, NetworkRule } from "../models/sandboxes.js";
|
|
19
|
+
import type { Egress } from "../services/egress.js";
|
|
20
|
+
|
|
21
|
+
type ApiGetPolicyOk =
|
|
22
|
+
EgressPaths["/policy"]["get"]["responses"][200]["content"]["application/json"];
|
|
23
|
+
type ApiPatchRulesRequest =
|
|
24
|
+
EgressPaths["/policy"]["patch"]["requestBody"]["content"]["application/json"];
|
|
25
|
+
|
|
26
|
+
export class EgressAdapter implements Egress {
|
|
27
|
+
constructor(private readonly client: EgressClient) {}
|
|
28
|
+
|
|
29
|
+
async getPolicy(): Promise<NetworkPolicy> {
|
|
30
|
+
const { data, error, response } = await this.client.GET("/policy");
|
|
31
|
+
throwOnOpenApiFetchError({ error, response }, "Get sandbox egress policy failed");
|
|
32
|
+
const raw = data as ApiGetPolicyOk | undefined;
|
|
33
|
+
if (!raw || typeof raw !== "object" || !raw.policy || typeof raw.policy !== "object") {
|
|
34
|
+
throw new Error("Get sandbox egress policy failed: unexpected response shape");
|
|
35
|
+
}
|
|
36
|
+
return raw.policy as NetworkPolicy;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async patchRules(rules: NetworkRule[]): Promise<void> {
|
|
40
|
+
const body: ApiPatchRulesRequest = rules as unknown as ApiPatchRulesRequest;
|
|
41
|
+
const { error, response } = await this.client.PATCH("/policy", {
|
|
42
|
+
body,
|
|
43
|
+
});
|
|
44
|
+
throwOnOpenApiFetchError({ error, response }, "Patch sandbox egress rules failed");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -69,11 +69,16 @@ export class SandboxesAdapter implements Sandboxes {
|
|
|
69
69
|
return d;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
private parseOptionalIsoDate(field: string, v: unknown): Date | null {
|
|
73
|
+
if (v == null) return null;
|
|
74
|
+
return this.parseIsoDate(field, v);
|
|
75
|
+
}
|
|
76
|
+
|
|
72
77
|
private mapSandboxInfo(raw: ApiGetSandboxOk): SandboxInfo {
|
|
73
78
|
return {
|
|
74
79
|
...(raw ?? {}),
|
|
75
80
|
createdAt: this.parseIsoDate("createdAt", raw?.createdAt),
|
|
76
|
-
expiresAt: this.
|
|
81
|
+
expiresAt: this.parseOptionalIsoDate("expiresAt", raw?.expiresAt),
|
|
77
82
|
} as SandboxInfo;
|
|
78
83
|
}
|
|
79
84
|
|
|
@@ -91,7 +96,7 @@ export class SandboxesAdapter implements Sandboxes {
|
|
|
91
96
|
return {
|
|
92
97
|
...(raw ?? {}),
|
|
93
98
|
createdAt: this.parseIsoDate("createdAt", raw?.createdAt),
|
|
94
|
-
expiresAt: this.
|
|
99
|
+
expiresAt: this.parseOptionalIsoDate("expiresAt", raw?.expiresAt),
|
|
95
100
|
} as CreateSandboxResponse;
|
|
96
101
|
}
|
|
97
102
|
|
|
@@ -188,4 +193,4 @@ export class SandboxesAdapter implements Sandboxes {
|
|
|
188
193
|
}
|
|
189
194
|
return ok as unknown as Endpoint;
|
|
190
195
|
}
|
|
191
|
-
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// Copyright 2026 Alibaba Group Holding Ltd..
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* This file was auto-generated by openapi-typescript.
|
|
17
|
+
* Do not make direct changes to the file.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export interface paths {
|
|
21
|
+
"/policy": {
|
|
22
|
+
parameters: {
|
|
23
|
+
query?: never;
|
|
24
|
+
header?: never;
|
|
25
|
+
path?: never;
|
|
26
|
+
cookie?: never;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Get current egress policy
|
|
30
|
+
* @description Returns the currently enforced egress policy and the sidecar's derived
|
|
31
|
+
* runtime mode metadata.
|
|
32
|
+
*/
|
|
33
|
+
get: {
|
|
34
|
+
parameters: {
|
|
35
|
+
query?: never;
|
|
36
|
+
header?: never;
|
|
37
|
+
path?: never;
|
|
38
|
+
cookie?: never;
|
|
39
|
+
};
|
|
40
|
+
requestBody?: never;
|
|
41
|
+
responses: {
|
|
42
|
+
/** @description Current policy returned successfully. */
|
|
43
|
+
200: {
|
|
44
|
+
headers: {
|
|
45
|
+
[name: string]: unknown;
|
|
46
|
+
};
|
|
47
|
+
content: {
|
|
48
|
+
"application/json": components["schemas"]["PolicyStatusResponse"];
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
401: components["responses"]["Unauthorized"];
|
|
52
|
+
500: components["responses"]["InternalServerError"];
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
put?: never;
|
|
56
|
+
post?: never;
|
|
57
|
+
delete?: never;
|
|
58
|
+
options?: never;
|
|
59
|
+
head?: never;
|
|
60
|
+
/**
|
|
61
|
+
* Patch egress rules
|
|
62
|
+
* @description Merge incoming egress rules with the currently enforced policy.
|
|
63
|
+
*
|
|
64
|
+
* This endpoint uses merge semantics:
|
|
65
|
+
* - Existing rules remain unless overridden by incoming rules.
|
|
66
|
+
* - Incoming rules are applied with higher priority than existing rules.
|
|
67
|
+
* - If multiple incoming rules refer to the same `target`, the first one wins.
|
|
68
|
+
*/
|
|
69
|
+
patch: {
|
|
70
|
+
parameters: {
|
|
71
|
+
query?: never;
|
|
72
|
+
header?: never;
|
|
73
|
+
path?: never;
|
|
74
|
+
cookie?: never;
|
|
75
|
+
};
|
|
76
|
+
requestBody: {
|
|
77
|
+
content: {
|
|
78
|
+
"application/json": components["schemas"]["NetworkRule"][];
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
responses: {
|
|
82
|
+
/** @description Patch applied successfully. */
|
|
83
|
+
200: {
|
|
84
|
+
headers: {
|
|
85
|
+
[name: string]: unknown;
|
|
86
|
+
};
|
|
87
|
+
content: {
|
|
88
|
+
"application/json": components["schemas"]["PolicyStatusResponse"];
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
400: components["responses"]["BadRequest"];
|
|
92
|
+
401: components["responses"]["Unauthorized"];
|
|
93
|
+
500: components["responses"]["InternalServerError"];
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
trace?: never;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export type webhooks = Record<string, never>;
|
|
100
|
+
export interface components {
|
|
101
|
+
schemas: {
|
|
102
|
+
PolicyStatusResponse: {
|
|
103
|
+
/**
|
|
104
|
+
* @description Operation status reported by the sidecar.
|
|
105
|
+
* @example ok
|
|
106
|
+
*/
|
|
107
|
+
status?: string;
|
|
108
|
+
/**
|
|
109
|
+
* @description Derived runtime mode for the current policy.
|
|
110
|
+
* @example deny_all
|
|
111
|
+
*/
|
|
112
|
+
mode?: string;
|
|
113
|
+
/**
|
|
114
|
+
* @description Egress sidecar enforcement backend mode.
|
|
115
|
+
* @example dns
|
|
116
|
+
*/
|
|
117
|
+
enforcementMode?: string;
|
|
118
|
+
/** @description Optional human-readable reason when the sidecar returns extra context. */
|
|
119
|
+
reason?: string;
|
|
120
|
+
policy?: components["schemas"]["NetworkPolicy"];
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* @description Egress network policy matching the sidecar `/policy` request body.
|
|
124
|
+
* If `defaultAction` is omitted, the sidecar defaults to "deny"; passing an empty
|
|
125
|
+
* object or null results in allow-all behavior at startup.
|
|
126
|
+
*/
|
|
127
|
+
NetworkPolicy: {
|
|
128
|
+
/**
|
|
129
|
+
* @description Default action when no egress rule matches. Defaults to "deny".
|
|
130
|
+
* @enum {string}
|
|
131
|
+
*/
|
|
132
|
+
defaultAction?: "allow" | "deny";
|
|
133
|
+
/** @description List of egress rules evaluated in order. */
|
|
134
|
+
egress?: components["schemas"]["NetworkRule"][];
|
|
135
|
+
};
|
|
136
|
+
NetworkRule: {
|
|
137
|
+
/**
|
|
138
|
+
* @description Whether to allow or deny matching targets.
|
|
139
|
+
* @enum {string}
|
|
140
|
+
*/
|
|
141
|
+
action: "allow" | "deny";
|
|
142
|
+
/**
|
|
143
|
+
* @description FQDN or wildcard domain (e.g., "example.com", "*.example.com").
|
|
144
|
+
* IP/CIDR not yet supported in the egress MVP.
|
|
145
|
+
*/
|
|
146
|
+
target: string;
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
responses: {
|
|
150
|
+
/** @description The request was invalid or malformed. */
|
|
151
|
+
BadRequest: {
|
|
152
|
+
headers: {
|
|
153
|
+
[name: string]: unknown;
|
|
154
|
+
};
|
|
155
|
+
content: {
|
|
156
|
+
"text/plain": string;
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
/** @description Authentication failed for the egress sidecar. */
|
|
160
|
+
Unauthorized: {
|
|
161
|
+
headers: {
|
|
162
|
+
[name: string]: unknown;
|
|
163
|
+
};
|
|
164
|
+
content: {
|
|
165
|
+
"text/plain": string;
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
/** @description The sidecar failed to apply or fetch policy state. */
|
|
169
|
+
InternalServerError: {
|
|
170
|
+
headers: {
|
|
171
|
+
[name: string]: unknown;
|
|
172
|
+
};
|
|
173
|
+
content: {
|
|
174
|
+
"text/plain": string;
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
parameters: never;
|
|
179
|
+
requestBodies: never;
|
|
180
|
+
headers: never;
|
|
181
|
+
pathItems: never;
|
|
182
|
+
}
|
|
183
|
+
export type $defs = Record<string, never>;
|
|
184
|
+
export type operations = Record<string, never>;
|