@homeflare/distilled-proxmox 0.3.3 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homeflare/distilled-proxmox",
3
- "version": "0.3.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",
@@ -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" }),
@@ -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
  }));