@homeflare/distilled-proxmox 0.3.0 → 0.3.2
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 +37 -10
- package/dist/config-not-found.test.d.ts +2 -0
- package/dist/config-not-found.test.d.ts.map +1 -0
- package/dist/config-not-found.test.js +125 -0
- package/dist/config-not-found.test.js.map +1 -0
- package/dist/errors.d.ts +2 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/lxc-config-errors.test.d.ts +2 -0
- package/dist/lxc-config-errors.test.d.ts.map +1 -0
- package/dist/lxc-config-errors.test.js +48 -0
- package/dist/lxc-config-errors.test.js.map +1 -0
- package/dist/protocol-form.d.ts +18 -0
- package/dist/protocol-form.d.ts.map +1 -0
- package/dist/protocol-form.js +37 -0
- package/dist/protocol-form.js.map +1 -0
- package/dist/protocol-form.test.d.ts +2 -0
- package/dist/protocol-form.test.d.ts.map +1 -0
- package/dist/protocol-form.test.js +68 -0
- package/dist/protocol-form.test.js.map +1 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +25 -2
- package/dist/protocol.js.map +1 -1
- package/dist/replication-firewall-errors.test.d.ts +2 -0
- package/dist/replication-firewall-errors.test.d.ts.map +1 -0
- package/dist/replication-firewall-errors.test.js +76 -0
- package/dist/replication-firewall-errors.test.js.map +1 -0
- package/dist/services/cluster.d.ts +50 -10
- package/dist/services/cluster.d.ts.map +1 -1
- package/dist/services/cluster.js +50 -10
- package/dist/services/cluster.js.map +1 -1
- package/dist/services/nodes.d.ts +25 -5
- package/dist/services/nodes.d.ts.map +1 -1
- package/dist/services/nodes.js +24 -5
- package/dist/services/nodes.js.map +1 -1
- package/dist/services/pools.d.ts +16 -6
- package/dist/services/pools.d.ts.map +1 -1
- package/dist/services/pools.js +18 -6
- package/dist/services/pools.js.map +1 -1
- package/package.json +1 -1
- package/src/config-not-found.test.ts +202 -0
- package/src/errors.ts +4 -12
- package/src/lxc-config-errors.test.ts +100 -0
- package/src/protocol-form.test.ts +102 -0
- package/src/protocol-form.ts +49 -0
- package/src/protocol.ts +30 -2
- package/src/replication-firewall-errors.test.ts +126 -0
- package/src/services/cluster.ts +97 -20
- package/src/services/nodes.ts +39 -10
- package/src/services/pools.ts +27 -12
package/dist/services/pools.d.ts
CHANGED
|
@@ -2,6 +2,16 @@ import * as S from "@distilled.cloud/core/schema";
|
|
|
2
2
|
import * as API from "@distilled.cloud/core/api";
|
|
3
3
|
import { type ProxmoxOpError, type ProxmoxOpContext } from "../protocol.ts";
|
|
4
4
|
export type { ProxmoxOpError, ProxmoxOpContext };
|
|
5
|
+
declare const PoolNotFound_base: S.Class<PoolNotFound, S.TaggedStruct<"PoolNotFound", {
|
|
6
|
+
readonly message: any;
|
|
7
|
+
}>, import("effect/Cause").YieldableError> & (new (...args: any[]) => {
|
|
8
|
+
"@distilled.cloud/error/categories": {
|
|
9
|
+
BadRequestError: true;
|
|
10
|
+
};
|
|
11
|
+
});
|
|
12
|
+
/** The resource pool does not exist. pve-manager 9.2.11, f6997e698c7933ea8e62319e2bf1bf7262daa56a, PVE/API2/Pool.pm:106,327,512 throws pool '<poolid>' does not exist in the read, update and delete handlers. Deprecated item routes delegate to them. The wire status is 500; a nonempty pool refusal or missing parent during create is a different error and must not match. */
|
|
13
|
+
export declare class PoolNotFound extends /*@__PURE__*/ PoolNotFound_base {
|
|
14
|
+
}
|
|
5
15
|
export interface CreatePoolRequest {
|
|
6
16
|
comment?: string;
|
|
7
17
|
poolid: string;
|
|
@@ -112,22 +122,22 @@ export declare const PutPoolsResponse: S.Schema<PutPoolsResponse>;
|
|
|
112
122
|
export type CreatePoolError = ProxmoxOpError;
|
|
113
123
|
/** Create new pool. (root-privileged endpoint) */
|
|
114
124
|
export declare const createPool: API.OperationMethod<CreatePoolRequest, CreatePoolResponse, CreatePoolError, ProxmoxOpContext>;
|
|
115
|
-
export type DeletePoolError = ProxmoxOpError;
|
|
125
|
+
export type DeletePoolError = PoolNotFound | ProxmoxOpError;
|
|
116
126
|
/** Delete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}'). (root-privileged endpoint) */
|
|
117
127
|
export declare const deletePool: API.OperationMethod<DeletePoolRequest, DeletePoolResponse, DeletePoolError, ProxmoxOpContext>;
|
|
118
|
-
export type DeletePoolsError = ProxmoxOpError;
|
|
128
|
+
export type DeletePoolsError = PoolNotFound | ProxmoxOpError;
|
|
119
129
|
/** Delete pool. (root-privileged endpoint) */
|
|
120
130
|
export declare const deletePools: API.OperationMethod<DeletePoolsRequest, DeletePoolsResponse, DeletePoolsError, ProxmoxOpContext>;
|
|
121
|
-
export type GetPoolError = ProxmoxOpError;
|
|
131
|
+
export type GetPoolError = PoolNotFound | ProxmoxOpError;
|
|
122
132
|
/** Get pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}'). */
|
|
123
133
|
export declare const getPool: API.OperationMethod<GetPoolRequest, GetPoolResponse, GetPoolError, ProxmoxOpContext>;
|
|
124
|
-
export type ListPoolsError = ProxmoxOpError;
|
|
134
|
+
export type ListPoolsError = PoolNotFound | ProxmoxOpError;
|
|
125
135
|
/** List pools or get pool configuration. */
|
|
126
136
|
export declare const listPools: API.OperationMethod<ListPoolsRequest, ListPoolsResponse, ListPoolsError, ProxmoxOpContext>;
|
|
127
|
-
export type PutPoolError = ProxmoxOpError;
|
|
137
|
+
export type PutPoolError = PoolNotFound | ProxmoxOpError;
|
|
128
138
|
/** Update pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead). (root-privileged endpoint) */
|
|
129
139
|
export declare const putPool: API.OperationMethod<PutPoolRequest, PutPoolResponse, PutPoolError, ProxmoxOpContext>;
|
|
130
|
-
export type PutPoolsError = ProxmoxOpError;
|
|
140
|
+
export type PutPoolsError = PoolNotFound | ProxmoxOpError;
|
|
131
141
|
/** Update pool. (root-privileged endpoint) */
|
|
132
142
|
export declare const putPools: API.OperationMethod<PutPoolsRequest, PutPoolsResponse, PutPoolsError, ProxmoxOpContext>;
|
|
133
143
|
//# sourceMappingURL=pools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pools.d.ts","sourceRoot":"","sources":["../../src/services/pools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,8BAA8B,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"pools.d.ts","sourceRoot":"","sources":["../../src/services/pools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,8BAA8B,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,2BAA2B,CAAC;AAGjD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAGxB,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC;;;;;;;;AAEjD,oXAAoX;AACpX,qBAAa,YACX,SAAQ,aAAa,CAAC,iBAUrB;CAAG;AAEN,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,eAAO,MAAM,iBAAiB,EAcjB,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzC,MAAM,WAAW,kBAAkB;CAAG;AACtC,eAAO,MAAM,kBAAkB,EAIlB,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE1C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,eAAO,MAAM,iBAAiB,EAMjB,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzC,MAAM,WAAW,kBAAkB;CAAG;AACtC,eAAO,MAAM,kBAAkB,EAIlB,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,eAAO,MAAM,kBAAkB,EAMlB,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE1C,MAAM,WAAW,mBAAmB;CAAG;AACvC,eAAO,MAAM,mBAAmB,EAInB,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAE3C,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAC5D,eAAO,MAAM,kBAAkB,KAAW,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,kBAAkB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;CAC3C;AACD,eAAO,MAAM,cAAc,EAK4B,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AAEhF,MAAM,MAAM,8BAA8B,GACtC,MAAM,GACN,KAAK,GACL,QAAQ,GACR,SAAS,CAAC;AACd,eAAO,MAAM,8BAA8B,KAAW,CAAC;AAEvD,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,8BAA8B,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AACD,eAAO,MAAM,0BAA0B,EAU1B,CAAC,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAElD,MAAM,MAAM,0BAA0B,GAAG,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAC3E,eAAO,MAAM,0BAA0B,EAE3B,CAAC,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,0BAA0B,CAAC;CACrC;AACD,eAAO,MAAM,eAAe,EAOf,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;AAEvC,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAC9D,eAAO,MAAM,oBAAoB,KAAW,CAAC;AAE7C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,oBAAoB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;CAC7C;AACD,eAAO,MAAM,gBAAgB,EAOhB,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAExC,MAAM,MAAM,wCAAwC,GAChD,MAAM,GACN,KAAK,GACL,QAAQ,GACR,SAAS,CAAC;AACd,eAAO,MAAM,wCAAwC,KAAW,CAAC;AAEjE,MAAM,WAAW,oCAAoC;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,wCAAwC,CAAC;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AACD,eAAO,MAAM,oCAAoC,EAWpC,CAAC,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC;AAE5D,MAAM,MAAM,oCAAoC,GAC9C,KAAK,CAAC,oCAAoC,CAAC,CAAC;AAC9C,eAAO,MAAM,oCAAoC,EAErC,CAAC,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC;AAE3D,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,oCAAoC,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,eAAO,MAAM,yBAAyB,EAQzB,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;AAEjD,MAAM,MAAM,yBAAyB,GAAG,KAAK,CAAC,yBAAyB,CAAC,CAAC;AACzE,eAAO,MAAM,yBAAyB,EAE1B,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;AAEhD,MAAM,MAAM,iBAAiB,GAAG,yBAAyB,CAAC;AAC1D,eAAO,MAAM,iBAAiB,EAIjB,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzC,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,mIAAmI;IACnI,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AACD,eAAO,MAAM,cAAc,EAgB4B,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AAEhF,MAAM,WAAW,eAAe;CAAG;AACnC,eAAO,MAAM,eAAe,EAIf,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,mIAAmI;IACnI,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AACD,eAAO,MAAM,eAAe,EAkBf,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;AAEvC,MAAM,WAAW,gBAAgB;CAAG;AACpC,eAAO,MAAM,gBAAgB,EAIhB,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAExC,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC;AAC7C,kDAAkD;AAClD,eAAO,MAAM,UAAU,EAAE,GAAG,CAAC,eAAe,CAC1C,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,CAOf,CAAC;AAEJ,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,cAAc,CAAC;AAC5D,8HAA8H;AAC9H,eAAO,MAAM,UAAU,EAAE,GAAG,CAAC,eAAe,CAC1C,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,CAOf,CAAC;AAEJ,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,cAAc,CAAC;AAC7D,8CAA8C;AAC9C,eAAO,MAAM,WAAW,EAAE,GAAG,CAAC,eAAe,CAC3C,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,CAOf,CAAC;AAEJ,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,cAAc,CAAC;AACzD,2GAA2G;AAC3G,eAAO,MAAM,OAAO,EAAE,GAAG,CAAC,eAAe,CACvC,cAAc,EACd,eAAe,EACf,YAAY,EACZ,gBAAgB,CAOf,CAAC;AAEJ,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,cAAc,CAAC;AAC3D,4CAA4C;AAC5C,eAAO,MAAM,SAAS,EAAE,GAAG,CAAC,eAAe,CACzC,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,CAOf,CAAC;AAEJ,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,cAAc,CAAC;AACzD,yIAAyI;AACzI,eAAO,MAAM,OAAO,EAAE,GAAG,CAAC,eAAe,CACvC,cAAc,EACd,eAAe,EACf,YAAY,EACZ,gBAAgB,CAOf,CAAC;AAEJ,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,CAAC;AAC1D,8CAA8C;AAC9C,eAAO,MAAM,QAAQ,EAAE,GAAG,CAAC,eAAe,CACxC,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,CAOf,CAAC"}
|
package/dist/services/pools.js
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
// AUTO-GENERATED by scripts/generate.ts from .generated-specs (apidata.js, via scripts/apidoc.ts — see its header). Do not edit.
|
|
2
2
|
import * as S from "@distilled.cloud/core/schema";
|
|
3
3
|
import * as API from "@distilled.cloud/core/api";
|
|
4
|
+
import * as C from "@distilled.cloud/core/category";
|
|
4
5
|
import * as T from "../traits.js";
|
|
5
6
|
import { ProxmoxProtocol, } from "../protocol.js";
|
|
6
7
|
import * as Retry from "../retry.js";
|
|
8
|
+
/** The resource pool does not exist. pve-manager 9.2.11, f6997e698c7933ea8e62319e2bf1bf7262daa56a, PVE/API2/Pool.pm:106,327,512 throws pool '<poolid>' does not exist in the read, update and delete handlers. Deprecated item routes delegate to them. The wire status is 500; a nonempty pool refusal or missing parent during create is a different error and must not match. */
|
|
9
|
+
export class PoolNotFound extends /*@__PURE__*/ /*@__PURE__*/ T.applyErrorMatchers(
|
|
10
|
+
/*@__PURE__*/ S.TaggedError()("PoolNotFound", {
|
|
11
|
+
message: S.String,
|
|
12
|
+
}).pipe(C.withBadRequestError), [
|
|
13
|
+
{
|
|
14
|
+
status: 500,
|
|
15
|
+
message: { matches: "^pool '[^']+' does not exist\\n?$" },
|
|
16
|
+
},
|
|
17
|
+
]) {
|
|
18
|
+
}
|
|
7
19
|
export const CreatePoolRequest = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
8
20
|
comment: S.optional(S.String),
|
|
9
21
|
poolid: S.String,
|
|
@@ -131,7 +143,7 @@ export const createPool = /*@__PURE__*/ API.make(() => ({
|
|
|
131
143
|
export const deletePool = /*@__PURE__*/ API.make(() => ({
|
|
132
144
|
input: DeletePoolRequest,
|
|
133
145
|
output: DeletePoolResponse,
|
|
134
|
-
errors: [],
|
|
146
|
+
errors: [PoolNotFound],
|
|
135
147
|
protocol: ProxmoxProtocol,
|
|
136
148
|
retry: Retry.Retry,
|
|
137
149
|
}));
|
|
@@ -139,7 +151,7 @@ export const deletePool = /*@__PURE__*/ API.make(() => ({
|
|
|
139
151
|
export const deletePools = /*@__PURE__*/ API.make(() => ({
|
|
140
152
|
input: DeletePoolsRequest,
|
|
141
153
|
output: DeletePoolsResponse,
|
|
142
|
-
errors: [],
|
|
154
|
+
errors: [PoolNotFound],
|
|
143
155
|
protocol: ProxmoxProtocol,
|
|
144
156
|
retry: Retry.Retry,
|
|
145
157
|
}));
|
|
@@ -147,7 +159,7 @@ export const deletePools = /*@__PURE__*/ API.make(() => ({
|
|
|
147
159
|
export const getPool = /*@__PURE__*/ API.make(() => ({
|
|
148
160
|
input: GetPoolRequest,
|
|
149
161
|
output: GetPoolResponse,
|
|
150
|
-
errors: [],
|
|
162
|
+
errors: [PoolNotFound],
|
|
151
163
|
protocol: ProxmoxProtocol,
|
|
152
164
|
retry: Retry.Retry,
|
|
153
165
|
}));
|
|
@@ -155,7 +167,7 @@ export const getPool = /*@__PURE__*/ API.make(() => ({
|
|
|
155
167
|
export const listPools = /*@__PURE__*/ API.make(() => ({
|
|
156
168
|
input: ListPoolsRequest,
|
|
157
169
|
output: ListPoolsResponse,
|
|
158
|
-
errors: [],
|
|
170
|
+
errors: [PoolNotFound],
|
|
159
171
|
protocol: ProxmoxProtocol,
|
|
160
172
|
retry: Retry.Retry,
|
|
161
173
|
}));
|
|
@@ -163,7 +175,7 @@ export const listPools = /*@__PURE__*/ API.make(() => ({
|
|
|
163
175
|
export const putPool = /*@__PURE__*/ API.make(() => ({
|
|
164
176
|
input: PutPoolRequest,
|
|
165
177
|
output: PutPoolResponse,
|
|
166
|
-
errors: [],
|
|
178
|
+
errors: [PoolNotFound],
|
|
167
179
|
protocol: ProxmoxProtocol,
|
|
168
180
|
retry: Retry.Retry,
|
|
169
181
|
}));
|
|
@@ -171,7 +183,7 @@ export const putPool = /*@__PURE__*/ API.make(() => ({
|
|
|
171
183
|
export const putPools = /*@__PURE__*/ API.make(() => ({
|
|
172
184
|
input: PutPoolsRequest,
|
|
173
185
|
output: PutPoolsResponse,
|
|
174
|
-
errors: [],
|
|
186
|
+
errors: [PoolNotFound],
|
|
175
187
|
protocol: ProxmoxProtocol,
|
|
176
188
|
retry: Retry.Retry,
|
|
177
189
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pools.js","sourceRoot":"","sources":["../../src/services/pools.ts"],"names":[],"mappings":"AAAA,iIAAiI;AACjI,OAAO,KAAK,CAAC,MAAM,8BAA8B,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,2BAA2B,CAAC;AACjD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EACL,eAAe,GAGhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,KAAK,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"pools.js","sourceRoot":"","sources":["../../src/services/pools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homeflare/distilled-proxmox",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
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,202 @@
|
|
|
1
|
+
/** PVE 9.2.11 vendor-source fixtures; missing BackupJob GET also measured 2026-09-24. */
|
|
2
|
+
import { describe, expect, test } from "bun:test";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Layer from "effect/Layer";
|
|
5
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
6
|
+
import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
|
|
7
|
+
import { credentials } from "./credentials.ts";
|
|
8
|
+
import type { ProxmoxOpContext } from "./protocol.ts";
|
|
9
|
+
import * as Retry from "./retry.ts";
|
|
10
|
+
import * as pools from "./services/pools.ts";
|
|
11
|
+
import * as cluster from "./services/cluster.ts";
|
|
12
|
+
import * as nodes from "./services/nodes.ts";
|
|
13
|
+
|
|
14
|
+
const call = <A, E>(
|
|
15
|
+
op: Effect.Effect<A, E, ProxmoxOpContext>,
|
|
16
|
+
status: number,
|
|
17
|
+
body: unknown,
|
|
18
|
+
) =>
|
|
19
|
+
Effect.runPromise(
|
|
20
|
+
op.pipe(
|
|
21
|
+
Retry.none,
|
|
22
|
+
Effect.provide(
|
|
23
|
+
credentials({
|
|
24
|
+
baseUrl: "https://pve.test:8006",
|
|
25
|
+
tokenId: "test@pve!test",
|
|
26
|
+
secret: "fake",
|
|
27
|
+
}),
|
|
28
|
+
),
|
|
29
|
+
Effect.provide(
|
|
30
|
+
Layer.succeed(
|
|
31
|
+
HttpClient.HttpClient,
|
|
32
|
+
HttpClient.make((request) =>
|
|
33
|
+
Effect.succeed(
|
|
34
|
+
HttpClientResponse.fromWeb(
|
|
35
|
+
request,
|
|
36
|
+
Response.json(body, { status }),
|
|
37
|
+
),
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
),
|
|
42
|
+
Effect.flip,
|
|
43
|
+
),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
describe("precise config absence tags", () => {
|
|
47
|
+
for (const [name, op] of [
|
|
48
|
+
["item read", pools.getPool({ poolid: "absent" })],
|
|
49
|
+
["index read", pools.listPools({ poolid: "absent" })],
|
|
50
|
+
["item update", pools.putPool({ poolid: "absent" })],
|
|
51
|
+
["collection update", pools.putPools({ poolid: "absent" })],
|
|
52
|
+
["item delete", pools.deletePool({ poolid: "absent" })],
|
|
53
|
+
["collection delete", pools.deletePools({ poolid: "absent" })],
|
|
54
|
+
] as const) {
|
|
55
|
+
test(`Pool ${name}`, async () => {
|
|
56
|
+
expect(
|
|
57
|
+
await call(op, 500, {
|
|
58
|
+
data: null,
|
|
59
|
+
message: "pool 'absent' does not exist\n",
|
|
60
|
+
}),
|
|
61
|
+
).toMatchObject({ _tag: "PoolNotFound" });
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
for (const [name, op] of [
|
|
65
|
+
["read", cluster.getClusterBackup({ id: "absent" })],
|
|
66
|
+
["delete", cluster.deleteClusterBackup({ id: "absent" })],
|
|
67
|
+
["volumes", cluster.getClusterBackupIncludedVolumes({ id: "absent" })],
|
|
68
|
+
] as const) {
|
|
69
|
+
test(`BackupJob ${name}`, async () => {
|
|
70
|
+
expect(
|
|
71
|
+
await call(op, 400, {
|
|
72
|
+
data: null,
|
|
73
|
+
message: "Parameter verification failed.\n",
|
|
74
|
+
errors: { id: "No such job 'absent'" },
|
|
75
|
+
}),
|
|
76
|
+
).toMatchObject({ _tag: "BackupJobNotFound" });
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
test("common HTTP failures remain in every operation's typed error union", async () => {
|
|
80
|
+
const op = pools.getPool({ poolid: "absent" }).pipe(
|
|
81
|
+
Effect.catchTag("NotFound", () =>
|
|
82
|
+
Effect.fail({ _tag: "HandledNotFound" } as const),
|
|
83
|
+
),
|
|
84
|
+
Effect.catchTag("Forbidden", () =>
|
|
85
|
+
Effect.fail({ _tag: "HandledForbidden" } as const),
|
|
86
|
+
),
|
|
87
|
+
);
|
|
88
|
+
expect(
|
|
89
|
+
await call(op, 404, { message: "missing", data: null }),
|
|
90
|
+
).toMatchObject({ _tag: "HandledNotFound" });
|
|
91
|
+
expect(
|
|
92
|
+
await call(op, 403, { message: "denied", data: null }),
|
|
93
|
+
).toMatchObject({ _tag: "HandledForbidden" });
|
|
94
|
+
});
|
|
95
|
+
test("MetricServer read and update have distinct absence messages", async () => {
|
|
96
|
+
expect(
|
|
97
|
+
await call(cluster.getClusterMetricsServer({ id: "absent" }), 500, {
|
|
98
|
+
data: null,
|
|
99
|
+
message: "status server entry 'absent' does not exist\n",
|
|
100
|
+
}),
|
|
101
|
+
).toMatchObject({ _tag: "MetricServerNotFound" });
|
|
102
|
+
expect(
|
|
103
|
+
await call(
|
|
104
|
+
cluster.putClusterMetricsServer({
|
|
105
|
+
id: "absent",
|
|
106
|
+
server: "localhost",
|
|
107
|
+
port: "8086",
|
|
108
|
+
}),
|
|
109
|
+
500,
|
|
110
|
+
{
|
|
111
|
+
data: null,
|
|
112
|
+
message: "no such server 'absent'\n",
|
|
113
|
+
},
|
|
114
|
+
),
|
|
115
|
+
).toMatchObject({ _tag: "MetricServerNotFound" });
|
|
116
|
+
});
|
|
117
|
+
test("unrelated, multi-field, and differently named validation are not absence", async () => {
|
|
118
|
+
for (const errors of [
|
|
119
|
+
{ id: "invalid configuration ID" },
|
|
120
|
+
{ id: "No such job 'absent'", schedule: "invalid schedule" },
|
|
121
|
+
{ comment: "No such job 'absent'" },
|
|
122
|
+
]) {
|
|
123
|
+
expect(
|
|
124
|
+
await call(cluster.getClusterBackup({ id: "absent" }), 400, {
|
|
125
|
+
data: null,
|
|
126
|
+
message: "Parameter verification failed.\n",
|
|
127
|
+
errors,
|
|
128
|
+
}),
|
|
129
|
+
).toMatchObject({ _tag: "ParameterVerificationFailed", errors });
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
test("a pool containing guests and a generic server failure propagate", async () => {
|
|
133
|
+
for (const message of [
|
|
134
|
+
"pool 'absent' is not empty (contains VM 100)\n",
|
|
135
|
+
"unrelated failure",
|
|
136
|
+
]) {
|
|
137
|
+
expect(
|
|
138
|
+
await call(pools.deletePool({ poolid: "absent" }), 500, {
|
|
139
|
+
data: null,
|
|
140
|
+
message,
|
|
141
|
+
}),
|
|
142
|
+
).toMatchObject({ _tag: "InternalServerError" });
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
test("missing backup text is not attached to unrelated operations", async () => {
|
|
146
|
+
expect(
|
|
147
|
+
await call(cluster.deleteClusterMetricsServer({ id: "absent" }), 400, {
|
|
148
|
+
data: null,
|
|
149
|
+
message: "Parameter verification failed.\n",
|
|
150
|
+
errors: { id: "No such job 'absent'" },
|
|
151
|
+
}),
|
|
152
|
+
).toMatchObject({ _tag: "ParameterVerificationFailed" });
|
|
153
|
+
});
|
|
154
|
+
test("network absence is the exact sole iface error on GET and PUT", async () => {
|
|
155
|
+
const body = {
|
|
156
|
+
data: null,
|
|
157
|
+
message: "Parameter verification failed.\n",
|
|
158
|
+
errors: { iface: "interface does not exist" },
|
|
159
|
+
};
|
|
160
|
+
expect(
|
|
161
|
+
await call(
|
|
162
|
+
nodes.getNodeNetwork({ node: "n2", iface: "vmbr9" }),
|
|
163
|
+
400,
|
|
164
|
+
body,
|
|
165
|
+
),
|
|
166
|
+
).toMatchObject({ _tag: "NetworkInterfaceNotFound" });
|
|
167
|
+
// ⛔ RETAG REGRESSION'S OWN CASE — PVE's `update_network` (PUT) raises the byte-identical
|
|
168
|
+
// 400 (Network.pm:750) that `network_config` (GET) raises (:852); a consumer's catchTag
|
|
169
|
+
// keyed on this tag must see the same absence signal from either operation.
|
|
170
|
+
expect(
|
|
171
|
+
await call(
|
|
172
|
+
nodes.putNodeNetwork2({ node: "n2", iface: "vmbr9", type: "bridge" }),
|
|
173
|
+
400,
|
|
174
|
+
body,
|
|
175
|
+
),
|
|
176
|
+
).toMatchObject({ _tag: "NetworkInterfaceNotFound" });
|
|
177
|
+
for (const errors of [
|
|
178
|
+
{ iface: "invalid interface name" },
|
|
179
|
+
{ iface: "interface does not exist", type: "invalid type" },
|
|
180
|
+
{ other: "interface does not exist" },
|
|
181
|
+
]) {
|
|
182
|
+
expect(
|
|
183
|
+
await call(nodes.getNodeNetwork({ node: "n2", iface: "vmbr9" }), 400, {
|
|
184
|
+
...body,
|
|
185
|
+
errors,
|
|
186
|
+
}),
|
|
187
|
+
).toMatchObject({ _tag: "ParameterVerificationFailed", errors });
|
|
188
|
+
}
|
|
189
|
+
for (const [status, tag] of [
|
|
190
|
+
[403, "Forbidden"],
|
|
191
|
+
[500, "InternalServerError"],
|
|
192
|
+
] as const) {
|
|
193
|
+
expect(
|
|
194
|
+
await call(
|
|
195
|
+
nodes.getNodeNetwork({ node: "n2", iface: "vmbr9" }),
|
|
196
|
+
status,
|
|
197
|
+
body,
|
|
198
|
+
),
|
|
199
|
+
).toMatchObject({ _tag: tag });
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
});
|
package/src/errors.ts
CHANGED
|
@@ -52,16 +52,9 @@ export {
|
|
|
52
52
|
DEFAULT_ERRORS,
|
|
53
53
|
API_ERRORS,
|
|
54
54
|
} from "@distilled.cloud/core/errors";
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
// of this package typechecking under `verbatimModuleSyntax`, not by this
|
|
59
|
-
// package's own `tsc -b` — see `docs/distilled-interim.md`'s "prove it in
|
|
60
|
-
// both places" step for why that gap exists at all.
|
|
61
|
-
import type {
|
|
62
|
-
BadRequest,
|
|
63
|
-
DefaultErrors as CoreDefaultErrors,
|
|
64
|
-
} from "@distilled.cloud/core/errors";
|
|
55
|
+
// Re-exports do not bind names locally. The operation union must cover every
|
|
56
|
+
// class the package protocol can return through core's HTTP_STATUS_MAP.
|
|
57
|
+
import type { API_ERRORS } from "@distilled.cloud/core/errors";
|
|
65
58
|
|
|
66
59
|
import * as Schema from "effect/Schema";
|
|
67
60
|
import * as Category from "@distilled.cloud/core/category";
|
|
@@ -153,7 +146,6 @@ export type ClientErrors = UnknownProxmoxError | ProxmoxParseError;
|
|
|
153
146
|
* task-polling.json` adds it to.
|
|
154
147
|
*/
|
|
155
148
|
export type DefaultErrors =
|
|
156
|
-
|
|
|
157
|
-
| BadRequest
|
|
149
|
+
| InstanceType<(typeof API_ERRORS)[number]>
|
|
158
150
|
| ParameterVerificationFailed
|
|
159
151
|
| ClientErrors;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exact installed pve-container6.1.13/libpve-guest-common-perl6.0.5 absence; never generic500.
|
|
3
|
+
* ⛔ ATTACHED TO GET, PUT AND DELETE — all three call `AbstractConfig::load_config` first
|
|
4
|
+
* (patches/nodes/lxc-config-errors.json's own provenance) and raise byte-identical text; a
|
|
5
|
+
* PUT/DELETE against a container config a caller believes exists gets the same typed absence
|
|
6
|
+
* a GET would, not a generic 500 a retry policy or catchTag could mistake for transient.
|
|
7
|
+
*/
|
|
8
|
+
import { expect, test } from "bun:test";
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
11
|
+
import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
|
|
12
|
+
import { credentials } from "./credentials.ts";
|
|
13
|
+
import type { ProxmoxOpContext } from "./protocol.ts";
|
|
14
|
+
import * as Retry from "./retry.ts";
|
|
15
|
+
import * as nodes from "./services/nodes.ts";
|
|
16
|
+
|
|
17
|
+
const missing =
|
|
18
|
+
"Configuration file 'nodes/pve-test/lxc/900.conf' does not exist\n";
|
|
19
|
+
const call = <A, E>(
|
|
20
|
+
op: Effect.Effect<A, E, ProxmoxOpContext>,
|
|
21
|
+
status: number,
|
|
22
|
+
message?: string,
|
|
23
|
+
) =>
|
|
24
|
+
Effect.runPromise(
|
|
25
|
+
op.pipe(
|
|
26
|
+
Retry.none,
|
|
27
|
+
Effect.provide(
|
|
28
|
+
credentials({
|
|
29
|
+
baseUrl: "https://pve.test:8006",
|
|
30
|
+
tokenId: "test@pve!test",
|
|
31
|
+
secret: "fake",
|
|
32
|
+
}),
|
|
33
|
+
),
|
|
34
|
+
Effect.provideService(
|
|
35
|
+
HttpClient.HttpClient,
|
|
36
|
+
HttpClient.make((request) =>
|
|
37
|
+
Effect.succeed(
|
|
38
|
+
HttpClientResponse.fromWeb(
|
|
39
|
+
request,
|
|
40
|
+
Response.json({ data: null, message }, { status }),
|
|
41
|
+
),
|
|
42
|
+
),
|
|
43
|
+
),
|
|
44
|
+
),
|
|
45
|
+
Effect.flip,
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
test("only exact container-config absence on GET becomes LxcConfigNotFound", async () => {
|
|
50
|
+
const get = () => nodes.getNodeLxcConfig({ node: "pve-test", vmid: "900" });
|
|
51
|
+
expect(await call(get(), 500, missing)).toMatchObject({
|
|
52
|
+
_tag: "LxcConfigNotFound",
|
|
53
|
+
});
|
|
54
|
+
for (const message of [
|
|
55
|
+
undefined,
|
|
56
|
+
"got timeout\n",
|
|
57
|
+
missing.replace("lxc", "qemu-server"),
|
|
58
|
+
missing + "other error",
|
|
59
|
+
]) {
|
|
60
|
+
expect(await call(get(), 500, message)).toMatchObject({
|
|
61
|
+
_tag: "InternalServerError",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
expect(await call(get(), 403, missing)).toMatchObject({ _tag: "Forbidden" });
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("the same exact absence on PUT and DELETE also becomes LxcConfigNotFound", async () => {
|
|
68
|
+
expect(
|
|
69
|
+
await call(
|
|
70
|
+
nodes.putNodeLxcConfig({ node: "pve-test", vmid: "900" }),
|
|
71
|
+
500,
|
|
72
|
+
missing,
|
|
73
|
+
),
|
|
74
|
+
).toMatchObject({ _tag: "LxcConfigNotFound" });
|
|
75
|
+
expect(
|
|
76
|
+
await call(
|
|
77
|
+
nodes.deleteNodeLxc({ node: "pve-test", vmid: "900" }),
|
|
78
|
+
500,
|
|
79
|
+
missing,
|
|
80
|
+
),
|
|
81
|
+
).toMatchObject({ _tag: "LxcConfigNotFound" });
|
|
82
|
+
// ⛔ STILL NOT ABSENCE ON PUT/DELETE EITHER — a generic failure on the write paths must stay
|
|
83
|
+
// generic, exactly like the GET-only assertions above.
|
|
84
|
+
for (const message of ["got timeout\n", missing + "other error"]) {
|
|
85
|
+
expect(
|
|
86
|
+
await call(
|
|
87
|
+
nodes.putNodeLxcConfig({ node: "pve-test", vmid: "900" }),
|
|
88
|
+
500,
|
|
89
|
+
message,
|
|
90
|
+
),
|
|
91
|
+
).toMatchObject({ _tag: "InternalServerError" });
|
|
92
|
+
expect(
|
|
93
|
+
await call(
|
|
94
|
+
nodes.deleteNodeLxc({ node: "pve-test", vmid: "900" }),
|
|
95
|
+
500,
|
|
96
|
+
message,
|
|
97
|
+
),
|
|
98
|
+
).toMatchObject({ _tag: "InternalServerError" });
|
|
99
|
+
}
|
|
100
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/** PVE 9.2.11 schema arrays must survive the vendor's repeated-key decoder. */
|
|
2
|
+
import { expect, test } from "bun:test";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Layer from "effect/Layer";
|
|
5
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
6
|
+
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
7
|
+
import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
|
|
8
|
+
import { credentials } from "./credentials.ts";
|
|
9
|
+
import type { ProxmoxOpContext } from "./protocol.ts";
|
|
10
|
+
import * as Retry from "./retry.ts";
|
|
11
|
+
import * as cluster from "./services/cluster.ts";
|
|
12
|
+
import * as nodes from "./services/nodes.ts";
|
|
13
|
+
|
|
14
|
+
const capture = async <A, E>(op: Effect.Effect<A, E, ProxmoxOpContext>) => {
|
|
15
|
+
const requests: HttpClientRequest.HttpClientRequest[] = [];
|
|
16
|
+
await Effect.runPromise(
|
|
17
|
+
op.pipe(
|
|
18
|
+
Retry.none,
|
|
19
|
+
Effect.provide(
|
|
20
|
+
credentials({
|
|
21
|
+
baseUrl: "https://pve.test:8006",
|
|
22
|
+
tokenId: "test@pve!test",
|
|
23
|
+
secret: "fake",
|
|
24
|
+
}),
|
|
25
|
+
),
|
|
26
|
+
Effect.provide(
|
|
27
|
+
Layer.succeed(
|
|
28
|
+
HttpClient.HttpClient,
|
|
29
|
+
HttpClient.make((request) => {
|
|
30
|
+
requests.push(request);
|
|
31
|
+
return Effect.succeed(
|
|
32
|
+
HttpClientResponse.fromWeb(
|
|
33
|
+
request,
|
|
34
|
+
Response.json({ data: null }),
|
|
35
|
+
),
|
|
36
|
+
);
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
);
|
|
42
|
+
const request = requests[0]!;
|
|
43
|
+
const form =
|
|
44
|
+
request.body._tag === "Uint8Array"
|
|
45
|
+
? new URLSearchParams(new TextDecoder().decode(request.body.body))
|
|
46
|
+
: new URLSearchParams();
|
|
47
|
+
return { request, form };
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
test("matcher arrays repeat the wire key; commas within a rule stay inside that item", async () => {
|
|
51
|
+
const { request, form } = await capture(
|
|
52
|
+
cluster.createClusterNotificationMatcher({
|
|
53
|
+
name: "matcher",
|
|
54
|
+
target: ["mail", "webhook"],
|
|
55
|
+
match_field: ["exact:type=vzdump", "regex:hostname=one,two"],
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
58
|
+
expect(request.method).toBe("POST");
|
|
59
|
+
expect(form.getAll("target")).toEqual(["mail", "webhook"]);
|
|
60
|
+
expect(form.getAll("match-field")).toEqual([
|
|
61
|
+
"exact:type=vzdump",
|
|
62
|
+
"regex:hostname=one,two",
|
|
63
|
+
]);
|
|
64
|
+
expect([...form.keys()].some((key) => key.includes("["))).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("webhook property-string headers remain separate values", async () => {
|
|
68
|
+
const headers = ["name=X-One,value=YQ==", "name=X-Two,value=Yg=="];
|
|
69
|
+
const { form } = await capture(
|
|
70
|
+
cluster.createClusterNotificationEndpointWebhook({
|
|
71
|
+
name: "webhook",
|
|
72
|
+
method: "post",
|
|
73
|
+
url: "https://example.com/hook",
|
|
74
|
+
header: headers,
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
expect(form.getAll("header")).toEqual(headers);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("array delete fields repeat while scalar comma lists remain scalar", async () => {
|
|
81
|
+
const { form } = await capture(
|
|
82
|
+
cluster.putClusterNotificationMatcher({
|
|
83
|
+
name: "matcher",
|
|
84
|
+
delete: ["match-field", "match-calendar"],
|
|
85
|
+
}),
|
|
86
|
+
);
|
|
87
|
+
expect(form.getAll("delete")).toEqual(["match-field", "match-calendar"]);
|
|
88
|
+
const scalar = await capture(
|
|
89
|
+
cluster.putClusterBackup({ id: "job", vmid: "100,101" }),
|
|
90
|
+
);
|
|
91
|
+
expect(scalar.form.getAll("vmid")).toEqual(["100,101"]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("DELETE stays bodyless and its flags stay query parameters", async () => {
|
|
95
|
+
const { request, form } = await capture(
|
|
96
|
+
nodes.deleteNodeCephFs({ node: "node", name: "fs", remove_pools: "1" }),
|
|
97
|
+
);
|
|
98
|
+
expect(request.method).toBe("DELETE");
|
|
99
|
+
expect(request.body._tag).toBe("Empty");
|
|
100
|
+
expect(new URL(request.url).searchParams.get("remove-pools")).toBe("1");
|
|
101
|
+
expect([...form]).toEqual([]);
|
|
102
|
+
});
|