@homeflare/distilled-proxmox 0.3.2 → 0.3.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/README.md +6 -0
- package/dist/network-changes.test.d.ts +2 -0
- package/dist/network-changes.test.d.ts.map +1 -0
- package/dist/network-changes.test.js +42 -0
- package/dist/network-changes.test.js.map +1 -0
- package/dist/not-found-errors.test.js +23 -0
- package/dist/not-found-errors.test.js.map +1 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +10 -1
- package/dist/protocol.js.map +1 -1
- package/dist/qemu-config-absence.test.d.ts +2 -0
- package/dist/qemu-config-absence.test.d.ts.map +1 -0
- package/dist/qemu-config-absence.test.js +41 -0
- package/dist/qemu-config-absence.test.js.map +1 -0
- package/dist/services/cluster.d.ts +23 -3
- package/dist/services/cluster.d.ts.map +1 -1
- package/dist/services/cluster.js +23 -3
- package/dist/services/cluster.js.map +1 -1
- package/dist/services/nodes.d.ts +19 -3
- package/dist/services/nodes.d.ts.map +1 -1
- package/dist/services/nodes.js +25 -3
- package/dist/services/nodes.js.map +1 -1
- package/package.json +1 -1
- package/src/network-changes.test.ts +60 -0
- package/src/not-found-errors.test.ts +38 -0
- package/src/protocol.ts +10 -1
- package/src/qemu-config-absence.test.ts +75 -0
- package/src/services/cluster.ts +32 -6
- package/src/services/nodes.ts +42 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homeflare/distilled-proxmox",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Interim npm home for @distilled.cloud/proxmox — see docs/distilled-interim.md. Not published upstream yet; the kit aliases @distilled.cloud/proxmox onto this package until it is.",
|
|
5
5
|
"homepage": "https://github.com/taslabs-net/homeflare-kit/tree/main/packages/distilled-proxmox#readme",
|
|
6
6
|
"bugs": "https://github.com/taslabs-net/homeflare-kit/issues",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interfaces diff is a sibling of `data`. Generic unwrapping must not drop it,
|
|
3
|
+
* and a response without that sibling must still unwrap.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, expect, test } from "bun:test";
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import * as Layer from "effect/Layer";
|
|
8
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
9
|
+
import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
|
|
10
|
+
import { credentials } from "./credentials.ts";
|
|
11
|
+
import type { ProxmoxOpContext } from "./protocol.ts";
|
|
12
|
+
import * as Retry from "./retry.ts";
|
|
13
|
+
import { getNodeTime, listNodeNetwork } from "./services/nodes.ts";
|
|
14
|
+
|
|
15
|
+
const creds = credentials({
|
|
16
|
+
tokenId: "root@pam!test",
|
|
17
|
+
secret: "test-secret",
|
|
18
|
+
baseUrl: "https://pve.test:8006",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const http = (body: unknown) =>
|
|
22
|
+
Layer.succeed(
|
|
23
|
+
HttpClient.HttpClient,
|
|
24
|
+
HttpClient.make((request) =>
|
|
25
|
+
Effect.succeed(
|
|
26
|
+
HttpClientResponse.fromWeb(request, Response.json(body, { status: 200 })),
|
|
27
|
+
),
|
|
28
|
+
),
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const run = <A, E>(op: Effect.Effect<A, E, ProxmoxOpContext>, body: unknown) =>
|
|
32
|
+
Effect.runPromise(op.pipe(Retry.none, Effect.provide(Layer.mergeAll(http(body), creds))));
|
|
33
|
+
|
|
34
|
+
describe("network changes sibling", () => {
|
|
35
|
+
test("a staged interfaces diff survives beside data", async () => {
|
|
36
|
+
const changes = "--- a\n+++ b\n+wpa-psk secret-value\n";
|
|
37
|
+
const live = await run(
|
|
38
|
+
listNodeNetwork({ node: "pve1" }),
|
|
39
|
+
{ data: [{ iface: "vmbr0", type: "bridge" }], changes },
|
|
40
|
+
);
|
|
41
|
+
expect(live).toEqual({
|
|
42
|
+
data: [{ iface: "vmbr0", type: "bridge" }],
|
|
43
|
+
changes,
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("no changes sibling still unwraps to the interface list", async () => {
|
|
48
|
+
const live = await run(listNodeNetwork({ node: "pve1" }), {
|
|
49
|
+
data: [{ iface: "vmbr0", type: "bridge" }],
|
|
50
|
+
});
|
|
51
|
+
expect(live).toEqual([{ iface: "vmbr0", type: "bridge" }]);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("another operation still unwraps data and ignores no sibling", async () => {
|
|
55
|
+
const live = await run(getNodeTime({ node: "pve1" }), {
|
|
56
|
+
data: { time: 1_700_000_000 },
|
|
57
|
+
});
|
|
58
|
+
expect(live).toMatchObject({ time: 1_700_000_000 });
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -27,6 +27,13 @@ import {
|
|
|
27
27
|
deleteNodeCephFs,
|
|
28
28
|
getNodeCephPoolStatus,
|
|
29
29
|
} from "./services/nodes.ts";
|
|
30
|
+
import {
|
|
31
|
+
deleteClusterHaResource,
|
|
32
|
+
getClusterHaResource,
|
|
33
|
+
getClusterHaRule,
|
|
34
|
+
HaResourceNotFound,
|
|
35
|
+
HaRuleNotFound,
|
|
36
|
+
} from "./services/cluster.ts";
|
|
30
37
|
import { getStorage, StorageNotFound } from "./services/storage.ts";
|
|
31
38
|
|
|
32
39
|
const testCredentials = credentials({
|
|
@@ -101,6 +108,37 @@ describe("WI-3 typed not-found errors decode from PVE's real wire shape", () =>
|
|
|
101
108
|
expect(error).toBeInstanceOf(CephPoolNotFound);
|
|
102
109
|
});
|
|
103
110
|
|
|
111
|
+
test("a missing HA resource's 500 decodes to HaResourceNotFound", async () => {
|
|
112
|
+
const error = await flipped(getClusterHaResource({ sid: "ct:101" }), 500, {
|
|
113
|
+
message: "no such resource 'ct:101'\n",
|
|
114
|
+
});
|
|
115
|
+
expect(error).toBeInstanceOf(HaResourceNotFound);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("deleting an unmanaged HA resource's 500 decodes to HaResourceNotFound", async () => {
|
|
119
|
+
const error = await flipped(
|
|
120
|
+
deleteClusterHaResource({ sid: "vm:100" }),
|
|
121
|
+
500,
|
|
122
|
+
{ message: "cannot delete service 'vm:100', not HA managed!\n" },
|
|
123
|
+
);
|
|
124
|
+
expect(error).toBeInstanceOf(HaResourceNotFound);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("a missing HA rule's 500 decodes to HaRuleNotFound", async () => {
|
|
128
|
+
const error = await flipped(getClusterHaRule({ rule: "keep-apart" }), 500, {
|
|
129
|
+
message: "no such ha rule 'keep-apart'\n",
|
|
130
|
+
});
|
|
131
|
+
expect(error).toBeInstanceOf(HaRuleNotFound);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("a nearby HA sentence does not become absence", async () => {
|
|
135
|
+
const error = await flipped(getClusterHaResource({ sid: "ct:101" }), 500, {
|
|
136
|
+
message:
|
|
137
|
+
"service 'ct:101' in error state, must be disabled and fixed first\n",
|
|
138
|
+
});
|
|
139
|
+
expect(error).not.toBeInstanceOf(HaResourceNotFound);
|
|
140
|
+
});
|
|
141
|
+
|
|
104
142
|
test("a missing Ceph filesystem's 500 (on destroy) decodes to CephFsNotFound", async () => {
|
|
105
143
|
const error = await flipped(
|
|
106
144
|
deleteNodeCephFs({ node: "n2", name: "ghost-fs" }),
|
package/src/protocol.ts
CHANGED
|
@@ -174,13 +174,22 @@ export const ProxmoxProtocol: Layer.Layer<API.Protocol> = withPveFormArrays(
|
|
|
174
174
|
// Unwrap PVE's `{"data": …}` envelope BEFORE the schema-driven decode —
|
|
175
175
|
// see the module header. `data` is `null`/absent for a Unit-output
|
|
176
176
|
// operation; `?? {}` is core's own convention for "no body".
|
|
177
|
+
// ⛔ `changes` is a sibling, not a field of `data`. PVE/HTTPServer.pm copies
|
|
178
|
+
// `$rpcenv->get_result_attrib('changes')` beside `data`. Network.pm sets
|
|
179
|
+
// that attrib to the interfaces diff. Dropping it makes a pending reload
|
|
180
|
+
// invisible. Only a string sibling is preserved; every other envelope
|
|
181
|
+
// still unwraps. The network list schema is the union that can decode it.
|
|
177
182
|
transformResponse: (body) => {
|
|
178
183
|
if (
|
|
179
184
|
body !== null &&
|
|
180
185
|
typeof body === "object" &&
|
|
181
186
|
"data" in (body as Record<string, unknown>)
|
|
182
187
|
) {
|
|
183
|
-
|
|
188
|
+
const record = body as Record<string, unknown>;
|
|
189
|
+
if (typeof record.changes === "string") {
|
|
190
|
+
return { changes: record.changes, data: record.data ?? [] };
|
|
191
|
+
}
|
|
192
|
+
return record.data ?? {};
|
|
184
193
|
}
|
|
185
194
|
return body;
|
|
186
195
|
},
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QEMU absence is the config-file sentence from AbstractConfig, not every 500.
|
|
3
|
+
* qemu-server Qemu.pm routes GET/PUT through `{vmid}/config` and DELETE through `{vmid}`.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, expect, test } from "bun:test";
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import * as Layer from "effect/Layer";
|
|
8
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
9
|
+
import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
|
|
10
|
+
import { credentials } from "./credentials.ts";
|
|
11
|
+
import type { ProxmoxOpContext } from "./protocol.ts";
|
|
12
|
+
import * as Retry from "./retry.ts";
|
|
13
|
+
import { deleteNodeQemu, getNodeQemuConfig } from "./services/nodes.ts";
|
|
14
|
+
|
|
15
|
+
const call = <A, E>(
|
|
16
|
+
op: Effect.Effect<A, E, ProxmoxOpContext>,
|
|
17
|
+
status: number,
|
|
18
|
+
body: unknown,
|
|
19
|
+
) =>
|
|
20
|
+
Effect.runPromise(
|
|
21
|
+
op.pipe(
|
|
22
|
+
Retry.none,
|
|
23
|
+
Effect.provide(
|
|
24
|
+
credentials({
|
|
25
|
+
baseUrl: "https://pve.test:8006",
|
|
26
|
+
tokenId: "test@pve!test",
|
|
27
|
+
secret: "fake",
|
|
28
|
+
}),
|
|
29
|
+
),
|
|
30
|
+
Effect.provide(
|
|
31
|
+
Layer.succeed(
|
|
32
|
+
HttpClient.HttpClient,
|
|
33
|
+
HttpClient.make((request) =>
|
|
34
|
+
Effect.succeed(
|
|
35
|
+
HttpClientResponse.fromWeb(
|
|
36
|
+
request,
|
|
37
|
+
Response.json(body, { status }),
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
),
|
|
42
|
+
),
|
|
43
|
+
Effect.flip,
|
|
44
|
+
),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const missing = {
|
|
48
|
+
data: null,
|
|
49
|
+
message: "Configuration file 'nodes/pve1/qemu-server/150.conf' does not exist\n",
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
describe("QEMU config absence", () => {
|
|
53
|
+
test("config GET and guest DELETE share the missing-file tag", async () => {
|
|
54
|
+
expect(
|
|
55
|
+
await call(getNodeQemuConfig({ node: "pve1", vmid: "150" }), 500, missing),
|
|
56
|
+
).toMatchObject({ _tag: "QemuConfigNotFound" });
|
|
57
|
+
expect(
|
|
58
|
+
await call(deleteNodeQemu({ node: "pve1", vmid: "150" }), 500, missing),
|
|
59
|
+
).toMatchObject({ _tag: "QemuConfigNotFound" });
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("a container path, a running guest, and a bare 500 stay unrelated", async () => {
|
|
63
|
+
for (const message of [
|
|
64
|
+
"Configuration file 'nodes/pve1/lxc/150.conf' does not exist\n",
|
|
65
|
+
"VM 150 is running - destroy failed\n",
|
|
66
|
+
"unrelated failure",
|
|
67
|
+
]) {
|
|
68
|
+
const error = await call(getNodeQemuConfig({ node: "pve1", vmid: "150" }), 500, {
|
|
69
|
+
data: null,
|
|
70
|
+
message,
|
|
71
|
+
});
|
|
72
|
+
expect(error).toMatchObject({ _tag: "InternalServerError" });
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
package/src/services/cluster.ts
CHANGED
|
@@ -33,6 +33,32 @@ export class FirewallAliasNotFound
|
|
|
33
33
|
[{ status: 400, message: { matches: "^no such alias$" } }],
|
|
34
34
|
) {}
|
|
35
35
|
|
|
36
|
+
/** The HA resource does not exist. pve-ha-manager 5.2.5, 28c31e4124ab2440753e7bf843c4dba97637aed8, PVE/API2/HA/Resources.pm:27 (GET, via the read method at line 179) raises no such resource '<sid>', and line 320 (DELETE) raises cannot delete service '<sid>', not HA managed. Both are wire 500. PUT does not raise either sentence and is not attached. */
|
|
37
|
+
export class HaResourceNotFound
|
|
38
|
+
extends /*@__PURE__*/ T.applyErrorMatchers(
|
|
39
|
+
/*@__PURE__*/ S.TaggedError<HaResourceNotFound>()("HaResourceNotFound", {
|
|
40
|
+
message: S.String,
|
|
41
|
+
}).pipe(C.withBadRequestError),
|
|
42
|
+
[
|
|
43
|
+
{ status: 500, message: { matches: "^no such resource '[^']+'\\n?$" } },
|
|
44
|
+
{
|
|
45
|
+
status: 500,
|
|
46
|
+
message: {
|
|
47
|
+
matches: "^cannot delete service '[^']+', not HA managed!\\n?$",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
) {}
|
|
52
|
+
|
|
53
|
+
/** The HA rule does not exist. pve-ha-manager 5.2.5, 28c31e4124ab2440753e7bf843c4dba97637aed8, PVE/API2/HA/Rules.pm:25 (GET, via the read method at line 247) raises no such ha rule '<ruleid>' as a wire 500. DELETE removes the id with no absence check and is not attached. PUT of a missing rule raises a different sentence and is not this tag. */
|
|
54
|
+
export class HaRuleNotFound
|
|
55
|
+
extends /*@__PURE__*/ T.applyErrorMatchers(
|
|
56
|
+
/*@__PURE__*/ S.TaggedError<HaRuleNotFound>()("HaRuleNotFound", {
|
|
57
|
+
message: S.String,
|
|
58
|
+
}).pipe(C.withBadRequestError),
|
|
59
|
+
[{ status: 500, message: { matches: "^no such ha rule '[^']+'\\n?$" } }],
|
|
60
|
+
) {}
|
|
61
|
+
|
|
36
62
|
/** The metrics server does not exist. pve-manager 9.2.11, f6997e698c7933ea8e62319e2bf1bf7262daa56a, PVE/API2/Cluster/MetricServer.pm:136 throws status server entry '<id>' does not exist on GET, and line 228 throws no such server '<id>' on PUT. Both are wire 500. DELETE dereferences the plugin config without an explicit absence check and is not declared to return this tag. */
|
|
37
63
|
export class MetricServerNotFound
|
|
38
64
|
extends /*@__PURE__*/ T.applyErrorMatchers(
|
|
@@ -15366,7 +15392,7 @@ export const deleteClusterHaGroup: API.OperationMethod<
|
|
|
15366
15392
|
retry: Retry.Retry,
|
|
15367
15393
|
}));
|
|
15368
15394
|
|
|
15369
|
-
export type DeleteClusterHaResourceError = ProxmoxOpError;
|
|
15395
|
+
export type DeleteClusterHaResourceError = HaResourceNotFound | ProxmoxOpError;
|
|
15370
15396
|
/** Delete resource configuration. (root-privileged endpoint) */
|
|
15371
15397
|
export const deleteClusterHaResource: API.OperationMethod<
|
|
15372
15398
|
DeleteClusterHaResourceRequest,
|
|
@@ -15376,7 +15402,7 @@ export const deleteClusterHaResource: API.OperationMethod<
|
|
|
15376
15402
|
> = /*@__PURE__*/ API.make(() => ({
|
|
15377
15403
|
input: DeleteClusterHaResourceRequest,
|
|
15378
15404
|
output: DeleteClusterHaResourceResponse,
|
|
15379
|
-
errors: [],
|
|
15405
|
+
errors: [HaResourceNotFound],
|
|
15380
15406
|
protocol: ProxmoxProtocol,
|
|
15381
15407
|
retry: Retry.Retry,
|
|
15382
15408
|
}));
|
|
@@ -16107,7 +16133,7 @@ export const getClusterHaGroup: API.OperationMethod<
|
|
|
16107
16133
|
retry: Retry.Retry,
|
|
16108
16134
|
}));
|
|
16109
16135
|
|
|
16110
|
-
export type GetClusterHaResourceError = ProxmoxOpError;
|
|
16136
|
+
export type GetClusterHaResourceError = HaResourceNotFound | ProxmoxOpError;
|
|
16111
16137
|
/** Read resource configuration. */
|
|
16112
16138
|
export const getClusterHaResource: API.OperationMethod<
|
|
16113
16139
|
GetClusterHaResourceRequest,
|
|
@@ -16117,12 +16143,12 @@ export const getClusterHaResource: API.OperationMethod<
|
|
|
16117
16143
|
> = /*@__PURE__*/ API.make(() => ({
|
|
16118
16144
|
input: GetClusterHaResourceRequest,
|
|
16119
16145
|
output: GetClusterHaResourceResponse,
|
|
16120
|
-
errors: [],
|
|
16146
|
+
errors: [HaResourceNotFound],
|
|
16121
16147
|
protocol: ProxmoxProtocol,
|
|
16122
16148
|
retry: Retry.Retry,
|
|
16123
16149
|
}));
|
|
16124
16150
|
|
|
16125
|
-
export type GetClusterHaRuleError = ProxmoxOpError;
|
|
16151
|
+
export type GetClusterHaRuleError = HaRuleNotFound | ProxmoxOpError;
|
|
16126
16152
|
/** Read HA rule. */
|
|
16127
16153
|
export const getClusterHaRule: API.OperationMethod<
|
|
16128
16154
|
GetClusterHaRuleRequest,
|
|
@@ -16132,7 +16158,7 @@ export const getClusterHaRule: API.OperationMethod<
|
|
|
16132
16158
|
> = /*@__PURE__*/ API.make(() => ({
|
|
16133
16159
|
input: GetClusterHaRuleRequest,
|
|
16134
16160
|
output: GetClusterHaRuleResponse,
|
|
16135
|
-
errors: [],
|
|
16161
|
+
errors: [HaRuleNotFound],
|
|
16136
16162
|
protocol: ProxmoxProtocol,
|
|
16137
16163
|
retry: Retry.Retry,
|
|
16138
16164
|
}));
|
package/src/services/nodes.ts
CHANGED
|
@@ -67,6 +67,23 @@ export class LxcConfigNotFound
|
|
|
67
67
|
],
|
|
68
68
|
) {}
|
|
69
69
|
|
|
70
|
+
/** qemu-server PVE/API2/Qemu.pm vm_config GET and destroy_vm both call QemuConfig->load_config. pve-guest-common AbstractConfig.pm load_config dies when the cfs file is missing: Configuration file '$cfspath' does not exist. QemuConfig's path is nodes/$node/qemu-server/$vmid.conf, HTTP 500. A missing file on this node is not a free cluster-wide vmid. */
|
|
71
|
+
export class QemuConfigNotFound
|
|
72
|
+
extends /*@__PURE__*/ T.applyErrorMatchers(
|
|
73
|
+
/*@__PURE__*/ S.TaggedError<QemuConfigNotFound>()("QemuConfigNotFound", {
|
|
74
|
+
message: S.String,
|
|
75
|
+
}).pipe(C.withBadRequestError),
|
|
76
|
+
[
|
|
77
|
+
{
|
|
78
|
+
status: 500,
|
|
79
|
+
message: {
|
|
80
|
+
matches:
|
|
81
|
+
"^Configuration file 'nodes/[^/']+/qemu-server/[0-9]+\\.conf' does not exist\\n?$",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
) {}
|
|
86
|
+
|
|
70
87
|
/** pve-manager 9.2.11, PVE/API2/Network.pm. GET (network_config) and PUT (update_network) both raise HTTP 400 with exactly errors.iface = interface does not exist -- verified against the live n2 source on 2026-09-25. DELETE (delete_network) raises it too but is left untyped: no generated deleteNodeNetwork2 caller exists yet. Only the exact sole-field detail is normalized for operation matching; all other validation errors remain ParameterVerificationFailed. Attached to GET and PUT. */
|
|
71
88
|
export class NetworkInterfaceNotFound
|
|
72
89
|
extends /*@__PURE__*/ T.applyErrorMatchers(
|
|
@@ -12574,9 +12591,28 @@ export const ListNodeNetworkResponseBodyList = /*@__PURE__*/ S.Array(
|
|
|
12574
12591
|
ListNodeNetworkResponseBodyItem,
|
|
12575
12592
|
) as any as S.Schema<ListNodeNetworkResponseBodyList>;
|
|
12576
12593
|
|
|
12577
|
-
|
|
12594
|
+
/** Present only when PVE staged an interfaces diff. The string can contain secrets. */
|
|
12595
|
+
export interface ListNodeNetworkPendingResponse {
|
|
12596
|
+
data: ListNodeNetworkResponseBodyList;
|
|
12597
|
+
changes: string;
|
|
12598
|
+
}
|
|
12599
|
+
export const ListNodeNetworkPendingResponse = /*@__PURE__*/ S.suspend(() =>
|
|
12600
|
+
S.Struct({
|
|
12601
|
+
data: ListNodeNetworkResponseBodyList,
|
|
12602
|
+
changes: S.String,
|
|
12603
|
+
}),
|
|
12604
|
+
).annotate({
|
|
12605
|
+
identifier: "ListNodeNetworkPendingResponse",
|
|
12606
|
+
}) as any as S.Schema<ListNodeNetworkPendingResponse>;
|
|
12607
|
+
|
|
12608
|
+
export type ListNodeNetworkResponse =
|
|
12609
|
+
| ListNodeNetworkResponseBodyList
|
|
12610
|
+
| ListNodeNetworkPendingResponse;
|
|
12578
12611
|
export const ListNodeNetworkResponse = /*@__PURE__*/ S.suspend(() =>
|
|
12579
|
-
|
|
12612
|
+
S.Union([
|
|
12613
|
+
ListNodeNetworkResponseBodyList.pipe(T.RawResponseRoot()),
|
|
12614
|
+
ListNodeNetworkPendingResponse,
|
|
12615
|
+
]),
|
|
12580
12616
|
).annotate({
|
|
12581
12617
|
identifier: "ListNodeNetworkResponse",
|
|
12582
12618
|
}) as any as S.Schema<ListNodeNetworkResponse>;
|
|
@@ -21547,7 +21583,7 @@ export const deleteNodeNetwork2: API.OperationMethod<
|
|
|
21547
21583
|
retry: Retry.Retry,
|
|
21548
21584
|
}));
|
|
21549
21585
|
|
|
21550
|
-
export type DeleteNodeQemuError = ProxmoxOpError;
|
|
21586
|
+
export type DeleteNodeQemuError = QemuConfigNotFound | ProxmoxOpError;
|
|
21551
21587
|
/** Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules (root-privileged endpoint) */
|
|
21552
21588
|
export const deleteNodeQemu: API.OperationMethod<
|
|
21553
21589
|
DeleteNodeQemuRequest,
|
|
@@ -21557,7 +21593,7 @@ export const deleteNodeQemu: API.OperationMethod<
|
|
|
21557
21593
|
> = /*@__PURE__*/ API.make(() => ({
|
|
21558
21594
|
input: DeleteNodeQemuRequest,
|
|
21559
21595
|
output: DeleteNodeQemuResponse,
|
|
21560
|
-
errors: [],
|
|
21596
|
+
errors: [QemuConfigNotFound],
|
|
21561
21597
|
protocol: ProxmoxProtocol,
|
|
21562
21598
|
retry: Retry.Retry,
|
|
21563
21599
|
}));
|
|
@@ -22566,7 +22602,7 @@ export const getNodeQemuCloudinitDump: API.OperationMethod<
|
|
|
22566
22602
|
retry: Retry.Retry,
|
|
22567
22603
|
}));
|
|
22568
22604
|
|
|
22569
|
-
export type GetNodeQemuConfigError = ProxmoxOpError;
|
|
22605
|
+
export type GetNodeQemuConfigError = QemuConfigNotFound | ProxmoxOpError;
|
|
22570
22606
|
/** Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead. */
|
|
22571
22607
|
export const getNodeQemuConfig: API.OperationMethod<
|
|
22572
22608
|
GetNodeQemuConfigRequest,
|
|
@@ -22576,7 +22612,7 @@ export const getNodeQemuConfig: API.OperationMethod<
|
|
|
22576
22612
|
> = /*@__PURE__*/ API.make(() => ({
|
|
22577
22613
|
input: GetNodeQemuConfigRequest,
|
|
22578
22614
|
output: GetNodeQemuConfigResponse,
|
|
22579
|
-
errors: [],
|
|
22615
|
+
errors: [QemuConfigNotFound],
|
|
22580
22616
|
protocol: ProxmoxProtocol,
|
|
22581
22617
|
retry: Retry.Retry,
|
|
22582
22618
|
}));
|