@homeflare/alchemy 0.30.0 → 0.31.1
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 +22 -0
- package/dist/discord/application-command.d.ts +52 -0
- package/dist/discord/application-command.d.ts.map +1 -0
- package/dist/discord/command-form.d.ts +62 -0
- package/dist/discord/command-form.d.ts.map +1 -0
- package/dist/discord/credentials.d.ts +35 -0
- package/dist/discord/credentials.d.ts.map +1 -0
- package/dist/discord/fake-discord.d.ts +44 -0
- package/dist/discord/fake-discord.d.ts.map +1 -0
- package/dist/discord/guild-application-command.d.ts +53 -0
- package/dist/discord/guild-application-command.d.ts.map +1 -0
- package/dist/discord/index.d.ts +12 -0
- package/dist/discord/index.d.ts.map +1 -0
- package/dist/discord/index.js +193 -0
- package/dist/discord/index.js.map +15 -0
- package/dist/discord/providers.d.ts +15 -0
- package/dist/discord/providers.d.ts.map +1 -0
- package/dist/discord/resource.d.ts +75 -0
- package/dist/discord/resource.d.ts.map +1 -0
- package/dist/proxmox/acl-wire.d.ts +26 -0
- package/dist/proxmox/acl-wire.d.ts.map +1 -0
- package/dist/proxmox/acl.d.ts.map +1 -1
- package/dist/proxmox/api-token-form.d.ts +28 -26
- package/dist/proxmox/api-token-form.d.ts.map +1 -1
- package/dist/proxmox/api-token.d.ts +48 -89
- package/dist/proxmox/api-token.d.ts.map +1 -1
- package/dist/proxmox/ceph-fs-wire.d.ts +2 -2
- package/dist/proxmox/ceph-fs-wire.d.ts.map +1 -1
- package/dist/proxmox/ceph-osd-tree.d.ts +1 -1
- package/dist/proxmox/ceph-osd-tree.d.ts.map +1 -1
- package/dist/proxmox/ceph-osd-write.d.ts +2 -2
- package/dist/proxmox/ceph-osd-write.d.ts.map +1 -1
- package/dist/proxmox/ceph-pool-settle.d.ts +1 -1
- package/dist/proxmox/ceph-pool-settle.d.ts.map +1 -1
- package/dist/proxmox/client.d.ts +2 -2
- package/dist/proxmox/client.d.ts.map +1 -1
- package/dist/proxmox/credential-errors.d.ts +27 -0
- package/dist/proxmox/credential-errors.d.ts.map +1 -0
- package/dist/proxmox/credentials.d.ts +0 -38
- package/dist/proxmox/credentials.d.ts.map +1 -1
- package/dist/proxmox/distilled-guard.d.ts +31 -0
- package/dist/proxmox/distilled-guard.d.ts.map +1 -0
- package/dist/proxmox/distilled-pve.d.ts +11 -4
- package/dist/proxmox/distilled-pve.d.ts.map +1 -1
- package/dist/proxmox/generated/constraints/index.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-access.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-access.d.ts.map +1 -1
- package/dist/proxmox/generated/constraints/pve-cluster-backup.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-cluster-ceph.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-cluster-firewall.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-cluster-ha.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-cluster-metrics.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-cluster-notifications.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-cluster-replication.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-cluster-sdn.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-nodes-ceph.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-nodes-disks.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-nodes-lxc.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-nodes-network.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-nodes-qemu.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-pools.d.ts +1 -1
- package/dist/proxmox/generated/constraints/pve-storage.d.ts +1 -1
- package/dist/proxmox/group-wire.d.ts +29 -0
- package/dist/proxmox/group-wire.d.ts.map +1 -0
- package/dist/proxmox/group.d.ts +20 -24
- package/dist/proxmox/group.d.ts.map +1 -1
- package/dist/proxmox/index.js +725 -509
- package/dist/proxmox/index.js.map +40 -33
- package/dist/proxmox/lease-cache.d.ts +1 -1
- package/dist/proxmox/lease-cache.d.ts.map +1 -1
- package/dist/proxmox/lxc-lifecycle.d.ts +5 -5
- package/dist/proxmox/lxc-lifecycle.d.ts.map +1 -1
- package/dist/proxmox/mint.d.ts +50 -0
- package/dist/proxmox/mint.d.ts.map +1 -0
- package/dist/proxmox/network-apply-read.d.ts +2 -2
- package/dist/proxmox/network-apply-read.d.ts.map +1 -1
- package/dist/proxmox/pbs-notification-target-lifecycle.d.ts +2 -2
- package/dist/proxmox/pbs-sync-job-form.d.ts +2 -2
- package/dist/proxmox/provision-cli-fake.d.ts.map +1 -1
- package/dist/proxmox/resource.d.ts +4 -4
- package/dist/proxmox/role-wire.d.ts +28 -0
- package/dist/proxmox/role-wire.d.ts.map +1 -0
- package/dist/proxmox/role.d.ts +36 -52
- package/dist/proxmox/role.d.ts.map +1 -1
- package/dist/proxmox/sdn-apply-read.d.ts +1 -1
- package/dist/proxmox/sdn-apply-read.d.ts.map +1 -1
- package/dist/proxmox/unreadable-read.d.ts +50 -0
- package/dist/proxmox/unreadable-read.d.ts.map +1 -0
- package/dist/proxmox/user-wire.d.ts +18 -0
- package/dist/proxmox/user-wire.d.ts.map +1 -0
- package/dist/proxmox/user.d.ts +25 -32
- package/dist/proxmox/user.d.ts.map +1 -1
- package/dist/proxmox/zfs-pool-write.d.ts +2 -2
- package/dist/proxmox/zfs-pool-write.d.ts.map +1 -1
- package/docs/credentials.md +9 -0
- package/docs/discord.md +129 -0
- package/docs/upstream-conformance.md +17 -1
- package/package.json +5 -1
- package/src/discord/application-command.test.ts +103 -0
- package/src/discord/application-command.ts +109 -0
- package/src/discord/command-form.test.ts +144 -0
- package/src/discord/command-form.ts +133 -0
- package/src/discord/credentials.ts +36 -0
- package/src/discord/fake-discord.ts +70 -0
- package/src/discord/guild-application-command.test.ts +215 -0
- package/src/discord/guild-application-command.ts +129 -0
- package/src/discord/index.ts +31 -0
- package/src/discord/providers.ts +18 -0
- package/src/discord/resource.ts +164 -0
- package/src/discord/retry.test.ts +74 -0
- package/src/proxmox/acl-wire.ts +83 -0
- package/src/proxmox/acl.ts +29 -82
- package/src/proxmox/adopt-noop.test.ts +18 -0
- package/src/proxmox/api-token-adopt.test.ts +28 -12
- package/src/proxmox/api-token-form.ts +50 -93
- package/src/proxmox/api-token.ts +149 -135
- package/src/proxmox/client.ts +2 -7
- package/src/proxmox/constraints-forms.test.ts +7 -27
- package/src/proxmox/credential-errors.ts +33 -0
- package/src/proxmox/credentials.test.ts +29 -3
- package/src/proxmox/credentials.ts +4 -134
- package/src/proxmox/distilled-guard.ts +42 -0
- package/src/proxmox/distilled-pve.ts +15 -4
- package/src/proxmox/generated/constraints/index.ts +1 -1
- package/src/proxmox/generated/constraints/pve-access.ts +1 -4
- package/src/proxmox/generated/constraints/pve-cluster-backup.ts +1 -1
- package/src/proxmox/generated/constraints/pve-cluster-ceph.ts +1 -1
- package/src/proxmox/generated/constraints/pve-cluster-firewall.ts +1 -1
- package/src/proxmox/generated/constraints/pve-cluster-ha.ts +1 -1
- package/src/proxmox/generated/constraints/pve-cluster-metrics.ts +1 -1
- package/src/proxmox/generated/constraints/pve-cluster-notifications.ts +1 -1
- package/src/proxmox/generated/constraints/pve-cluster-replication.ts +1 -1
- package/src/proxmox/generated/constraints/pve-cluster-sdn.ts +1 -1
- package/src/proxmox/generated/constraints/pve-nodes-ceph.ts +1 -1
- package/src/proxmox/generated/constraints/pve-nodes-disks.ts +1 -1
- package/src/proxmox/generated/constraints/pve-nodes-lxc.ts +1 -1
- package/src/proxmox/generated/constraints/pve-nodes-network.ts +1 -1
- package/src/proxmox/generated/constraints/pve-nodes-qemu.ts +1 -1
- package/src/proxmox/generated/constraints/pve-pools.ts +1 -1
- package/src/proxmox/generated/constraints/pve-storage.ts +1 -1
- package/src/proxmox/group-wire.ts +63 -0
- package/src/proxmox/group.test.ts +110 -0
- package/src/proxmox/group.ts +135 -105
- package/src/proxmox/lease-cache.ts +2 -1
- package/src/proxmox/lxc-lifecycle.ts +2 -1
- package/src/proxmox/mint.ts +158 -0
- package/src/proxmox/network-apply.ts +1 -1
- package/src/proxmox/provision-cli-fake.ts +11 -0
- package/src/proxmox/provision-declare.test.ts +6 -1
- package/src/proxmox/role-wire.ts +49 -0
- package/src/proxmox/role.test.ts +89 -0
- package/src/proxmox/role.ts +147 -106
- package/src/proxmox/unreadable-read.test.ts +83 -0
- package/src/proxmox/unreadable-read.ts +60 -0
- package/src/proxmox/user-wire.ts +112 -0
- package/src/proxmox/user.test.ts +142 -0
- package/src/proxmox/user.ts +132 -129
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { Input } from 'alchemy/Input';
|
|
2
|
+
import type { DiscordOpContext } from '@distilled.cloud/discord/Protocol';
|
|
3
|
+
import * as Effect from 'effect/Effect';
|
|
4
|
+
import type * as HttpClient from 'effect/unstable/http/HttpClient';
|
|
5
|
+
/**
|
|
6
|
+
* What every stack must still provide after `discordHandlers` bakes in `CredentialsFromEnv`
|
|
7
|
+
* (below): the transport. `DiscordOpContext` is `Credentials | HttpClient.HttpClient`, so once
|
|
8
|
+
* `Credentials` is supplied, `HttpClient.HttpClient` is what remains — mirroring
|
|
9
|
+
* `../netbox/resource.ts#NetboxRequirements`.
|
|
10
|
+
*/
|
|
11
|
+
export type DiscordRequirements = HttpClient.HttpClient;
|
|
12
|
+
/** Every Discord command resource's identity key, regardless of scope. */
|
|
13
|
+
export interface DiscordCommandIdentity {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* One Discord command object's distilled calls. `Live` is whatever the SDK decodes
|
|
18
|
+
* (`ApplicationCommandResponse`); `E` is left to each resource file to declare, so a call site's
|
|
19
|
+
* precise error union (in practice always `DiscordOpError` — see `protocol.ts` — because every
|
|
20
|
+
* generated Discord operation shares one error channel) flows straight through.
|
|
21
|
+
*/
|
|
22
|
+
export type DiscordSpec<Props extends DiscordCommandIdentity, Live, Attributes extends object, E> = {
|
|
23
|
+
/** Locate the live command by its declared name within this spec's scope (app, or app+guild). */
|
|
24
|
+
readonly fetchByName: (props: Props) => Effect.Effect<Live | undefined, E, DiscordOpContext>;
|
|
25
|
+
readonly attributes: (live: Live) => Attributes;
|
|
26
|
+
readonly matches: (attributes: Attributes, props: Props) => boolean;
|
|
27
|
+
readonly upsertBody: (props: Props) => Record<string, unknown>;
|
|
28
|
+
/** POST create-or-overwrite — see the upsert note above. */
|
|
29
|
+
readonly upsert: (props: Props, body: Record<string, unknown>) => Effect.Effect<Live, E, DiscordOpContext>;
|
|
30
|
+
readonly destroy: (props: Props, live: Live) => Effect.Effect<unknown, E, DiscordOpContext>;
|
|
31
|
+
/** For error messages and test descriptions. */
|
|
32
|
+
readonly describe: (props: Props) => string;
|
|
33
|
+
};
|
|
34
|
+
export declare const discordOperations: <Props extends DiscordCommandIdentity, Live, Attributes extends object, E>(spec: DiscordSpec<Props, Live, Attributes, E>) => {
|
|
35
|
+
read: ({ olds, output }: {
|
|
36
|
+
olds: Props;
|
|
37
|
+
output: Attributes | undefined;
|
|
38
|
+
}) => Effect.Effect<Attributes | undefined, E, DiscordOpContext>;
|
|
39
|
+
diff: (news: Input<Props>, output: Attributes | undefined) => Effect.Effect<{
|
|
40
|
+
readonly action: 'update';
|
|
41
|
+
} | {
|
|
42
|
+
readonly action: 'noop';
|
|
43
|
+
} | undefined, E, DiscordOpContext>;
|
|
44
|
+
reconcile: (news: Props) => Effect.Effect<Attributes, E, DiscordOpContext>;
|
|
45
|
+
destroy: (olds: Props) => Effect.Effect<void, E, DiscordOpContext>;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The four provider handlers for a spec'd Discord command, wired once.
|
|
49
|
+
*
|
|
50
|
+
* ★ CREDENTIALS ARE PROVIDED HERE, ONCE. `CredentialsFromEnv` resolves `DISCORD_BOT_TOKEN` /
|
|
51
|
+
* `DISCORD_TOKEN` on the calling fiber per request (credentials.ts), so this closure keeps that
|
|
52
|
+
* laziness — nothing is captured at module load.
|
|
53
|
+
*/
|
|
54
|
+
export declare const discordHandlers: <Props extends DiscordCommandIdentity, Live, Attributes extends object, E>(spec: DiscordSpec<Props, Live, Attributes, E>) => {
|
|
55
|
+
list: () => Effect.Effect<never[], never, never>;
|
|
56
|
+
read: ({ olds, output }: {
|
|
57
|
+
olds: Props;
|
|
58
|
+
output: Attributes | undefined;
|
|
59
|
+
}) => Effect.Effect<Attributes | undefined, E, HttpClient.HttpClient>;
|
|
60
|
+
diff: ({ news, output }: {
|
|
61
|
+
news: Input<Props>;
|
|
62
|
+
output: Attributes | undefined;
|
|
63
|
+
}) => Effect.Effect<{
|
|
64
|
+
readonly action: 'update';
|
|
65
|
+
} | {
|
|
66
|
+
readonly action: 'noop';
|
|
67
|
+
} | undefined, E, HttpClient.HttpClient>;
|
|
68
|
+
reconcile: ({ news }: {
|
|
69
|
+
news: Props;
|
|
70
|
+
}) => Effect.Effect<Attributes, E, HttpClient.HttpClient>;
|
|
71
|
+
delete: ({ olds }: {
|
|
72
|
+
olds: Props;
|
|
73
|
+
}) => Effect.Effect<void, E, HttpClient.HttpClient>;
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/discord/resource.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAGnE;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,UAAU,CAAC;AAExD,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CACrB,KAAK,SAAS,sBAAsB,EACpC,IAAI,EACJ,UAAU,SAAS,MAAM,EACzB,CAAC,IACC;IACF,iGAAiG;IACjG,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,SAAS,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC7F,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,UAAU,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;IACpE,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/D,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,CACf,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC5F,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC;CAC7C,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,KAAK,SAAS,sBAAsB,EACpC,IAAI,EACJ,UAAU,SAAS,MAAM,EACzB,CAAC,QAEK,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAE7C,IAAI,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE;IAYxE,IAAI,SAAS,KAAK,CAAC,KAAK,CAAC,UAAU,UAAU,GAAG,SAAS;yBAIZ,QAAQ;;yBAElC,MAAM;;IAIzB,SAAS,SAAS,KAAK;IAiBvB,OAAO,SAAS,KAAK;CAMrB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,SAAS,sBAAsB,EACpC,IAAI,EACJ,UAAU,SAAS,MAAM,EACzB,CAAC,QAEK,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAM3C,IAAI;IACJ,IAAI,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE;IAExE,IAAI,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE;yBArDpC,QAAQ;;yBAElC,MAAM;;IAqDvB,SAAS,aAAa;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE;IACrC,MAAM,aAAa;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE;CAErC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Proxmox.Acl`'s wire shape: PVE's PUT form, identity, and how a live row becomes attributes.
|
|
3
|
+
* Split out of acl.ts (2026-09-24) to keep that file under the 250-line cap once the cries-wolf
|
|
4
|
+
* fix needed real space — the api-token.ts/api-token-form.ts seam, same reasoning: this file
|
|
5
|
+
* answers "what does PVE store", acl.ts answers "when has it changed" and drives the provider.
|
|
6
|
+
*/
|
|
7
|
+
import type * as access from '@distilled.cloud/proxmox/access';
|
|
8
|
+
import type { AclAttributes, AclProps } from './acl.ts';
|
|
9
|
+
/** ⚠️ PVE normalises ACL paths (collapses repeated slashes, strips the trailing one, adds a leading one). */
|
|
10
|
+
export declare const normalize: (raw: string) => string;
|
|
11
|
+
/** The tuple PVE keys a grant by, as PUT's fields. */
|
|
12
|
+
export declare const tuple: (props: AclProps) => access.PutAccessAclRequest;
|
|
13
|
+
/** Create and update are one call: the tuple plus the single mutable field. */
|
|
14
|
+
export declare const bind: (props: AclProps) => access.PutAccessAclRequest;
|
|
15
|
+
/**
|
|
16
|
+
* ⚠️ ALWAYS PRESENCE-CHECKED. `bind`'s output IS the create form (there is no separate,
|
|
17
|
+
* narrower update form for this family — see acl.ts's header), so the vendor's
|
|
18
|
+
* required-parameter check is never wrong to run; the two separate create/update passes the
|
|
19
|
+
* generic factory ran elsewhere collapse to one call here without losing coverage.
|
|
20
|
+
*/
|
|
21
|
+
export declare const guardWrite: (props: AclProps) => import("effect/Effect").Effect<void, never, never>;
|
|
22
|
+
/** What a change of this string means: not an edit, a different grant. */
|
|
23
|
+
export declare const identity: (grant: Pick<AclAttributes, 'path' | 'roleid' | 'type' | 'ugid'>) => string;
|
|
24
|
+
export declare const attributesOf: (rows: readonly access.ListAccessAclResponseBodyItem[], props: AclProps) => AclAttributes;
|
|
25
|
+
export declare const matches: (attributes: AclAttributes, props: AclProps) => boolean;
|
|
26
|
+
//# sourceMappingURL=acl-wire.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acl-wire.d.ts","sourceRoot":"","sources":["../../src/proxmox/acl-wire.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,KAAK,MAAM,MAAM,iCAAiC,CAAC;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAExD,6GAA6G;AAC7G,eAAO,MAAM,SAAS,QAAS,MAAM,WAAmD,CAAC;AAQzF,sDAAsD;AACtD,eAAO,MAAM,KAAK,UAAW,QAAQ,KAAG,MAAM,CAAC,mBAI7C,CAAC;AAEH,+EAA+E;AAC/E,eAAO,MAAM,IAAI,UAAW,QAAQ,KAAG,MAAM,CAAC,mBAG5C,CAAC;AAMH;;;;;GAKG;AACH,eAAO,MAAM,UAAU,UAAW,QAAQ,uDAAmD,CAAC;AAE9F,0EAA0E;AAC1E,eAAO,MAAM,QAAQ,UAAW,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC,WACf,CAAC;AAoB1E,eAAO,MAAM,YAAY,SACjB,SAAS,MAAM,CAAC,6BAA6B,EAAE,SAC9C,QAAQ,KACd,aAUF,CAAC;AAEF,eAAO,MAAM,OAAO,eAAgB,aAAa,SAAS,QAAQ,YACQ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acl.d.ts","sourceRoot":"","sources":["../../src/proxmox/acl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAI7C,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"acl.d.ts","sourceRoot":"","sources":["../../src/proxmox/acl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAI7C,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAStE,4FAA4F;AAC5F,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAExD,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,IAAI,EAAE,cAAc,CAAC;IACrB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,MAAM,EAAE,MAAM,CAAC;IACf,8FAA8F;IAC9F,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,+FAA+F;IAC/F,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,UAAW,SAAQ,QAAQ,CAC1C,aAAa,EACb,QAAQ,EACR,aAAa,EACb,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ,eAAO,MAAM,UAAU,6CAAsC,CAAC;AAmB9D,eAAO,MAAM,kBAAkB,gIA6E5B,CAAC"}
|
|
@@ -15,9 +15,14 @@ import type { ApiTokenAttributes, ApiTokenProps } from './api-token.ts';
|
|
|
15
15
|
* `update_token_info`, read over SSH on node-b on 2026-09-13. The two disagree in exactly the place
|
|
16
16
|
* that costs a forever-diff: the schema gives `expire` the default "same as user", and the code
|
|
17
17
|
* never implements it. api-token.ts records what that means.
|
|
18
|
+
*
|
|
19
|
+
* ★ MIGRATED OFF THE GENERATED `generated/pve.ts` PARAM TYPES ONTO `@distilled.cloud/proxmox`'s
|
|
20
|
+
* typed `access.PutAccessUserTokenRequest`/`access.GetAccessUserTokenResponse` (2026-09-24) —
|
|
21
|
+
* the same three fields, still form-urlencoded strings on the wire; distilled's generator
|
|
22
|
+
* reads the identical vendor schema `generated/pve.ts` came from.
|
|
18
23
|
*/
|
|
19
|
-
import type
|
|
20
|
-
|
|
24
|
+
import type * as access from '@distilled.cloud/proxmox/access';
|
|
25
|
+
export declare const API_TOKEN_UPDATE = "pve:PUT /access/users/{userid}/token/{tokenid}";
|
|
21
26
|
/**
|
|
22
27
|
* `<userid>!<tokenid>` — the name the rest of PVE calls this object by.
|
|
23
28
|
*
|
|
@@ -32,12 +37,8 @@ import type { PveSpec } from './resource.ts';
|
|
|
32
37
|
*/
|
|
33
38
|
export declare const fullTokenid: (props: ApiTokenProps) => string;
|
|
34
39
|
/**
|
|
35
|
-
* Everything a token has, in the form PVE wants.
|
|
36
|
-
*
|
|
37
|
-
* ⛔ `userid` AND `tokenid` ARE NOT IN IT, and that is not an omission. Both are path segments of
|
|
38
|
-
* `access/users/{userid}/token/{tokenid}` — which is the path the POST goes to as well as the
|
|
39
|
-
* PUT — so a second copy in the body can only ever disagree with the path it was sent to.
|
|
40
|
-
* metric-server.ts omits its `id` for the same reason and says so there.
|
|
40
|
+
* Everything a token has, in the form PVE wants. Update sends exactly this (this family never
|
|
41
|
+
* creates — see api-token.ts's header).
|
|
41
42
|
*
|
|
42
43
|
* ⚠️ EVERY FIELD IS SENT ON EVERY WRITE, THE EMPTY COMMENT INCLUDED, BECAUSE A PUT MERGES.
|
|
43
44
|
* MEASURED in `update_token_info`: `$token->{comment} = $param->{comment} if defined(...)`
|
|
@@ -48,23 +49,24 @@ export declare const fullTokenid: (props: ApiTokenProps) => string;
|
|
|
48
49
|
* literally `my $deletable = { comment => 1 };`, and anything else answers
|
|
49
50
|
* "unknown option '<k>'" — so `expire` and `privsep` have no clear path at all, which is the
|
|
50
51
|
* other half of why both are required props rather than optional ones.
|
|
51
|
-
*
|
|
52
|
-
* ⚠️ `flag()` FROM values.ts IS DELIBERATELY NOT USED FOR `privsep`. Its entire job is turning an
|
|
53
|
-
* UNDECLARED boolean into `undefined` so the field is omitted from the form; `privsep` is a
|
|
54
|
-
* required prop precisely so that it is never undeclared, so there is nothing for it to do and
|
|
55
|
-
* its `string | undefined` return would have to be asserted away to fit `Record<string,string>`.
|
|
56
|
-
* An assertion here would be a claim about the prop that the type already makes properly.
|
|
57
|
-
*
|
|
58
|
-
* ★ TYPED AGAINST THE GENERATED PUT AND POST PARAMS, NOT `Record<string, string>`, since
|
|
59
|
-
* 2026-09-23 — the `notification-matcher-form.ts` pattern: `Pick` rather than the whole type,
|
|
60
|
-
* because neither `AccessUsersUseridTokenTokenidPutParams` nor …`PostParams` (generated/pve.ts)
|
|
61
|
-
* carries `userid`/`tokenid` (they are path segments — see the ⛔ above) and Put alone also
|
|
62
|
-
* carries `delete`/`regenerate`, which this family never sends. A schema drift on any of the
|
|
63
|
-
* three fields this function DOES send fails `tsc` here rather than surfacing as a 400 on a live
|
|
64
|
-
* cluster; api-token.test.ts pins the assignment both ways (Put and Post) without a cast.
|
|
65
|
-
* `expire` is written as a template literal, not `String(...)`, because the generated type is
|
|
66
|
-
* `` `${number}` ``, not `string` — `String(n)` widens to plain `string` and would not typecheck.
|
|
67
52
|
*/
|
|
68
|
-
export declare const shape: (props: ApiTokenProps) =>
|
|
69
|
-
|
|
53
|
+
export declare const shape: (props: ApiTokenProps) => access.PutAccessUserTokenRequest;
|
|
54
|
+
/**
|
|
55
|
+
* ★ NOTHING PVE REPORTS HERE IS UNWRITABLE, WHICH IS UNUSUAL IN THIS PACKAGE. The GET returns
|
|
56
|
+
* exactly `comment`, `expire` and `privsep`; PUT accepts exactly those three.
|
|
57
|
+
* ⛔ `undefined` WHEN NEITHER FLAG IS THERE, BECAUSE BOTH ARE ALWAYS THERE FOR A REAL TOKEN.
|
|
58
|
+
* `user.cfg` materialises `expire` and `privsep` for every token it stores, so an answer
|
|
59
|
+
* carrying neither is not a token — the same "distilled unwraps a missing object's `{"data":
|
|
60
|
+
* null}` to `{}`" trap group.ts's header measures, checked here the way this guard already was
|
|
61
|
+
* before the distilled migration (api-token.ts's ⛔ on the create refusal cites the same
|
|
62
|
+
* MEASURED schema). Without this guard `bool`/`int` would invent one out of their fallbacks and
|
|
63
|
+
* the read-back guard in `reconcile` could never fire.
|
|
64
|
+
*/
|
|
65
|
+
export declare const attributesOf: (live: access.GetAccessUserTokenResponse, props: ApiTokenProps) => ApiTokenAttributes | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* ⚠️ EXACTLY THE THREE FIELDS A PUT CAN PUT BACK, WHICH IS ALSO EXACTLY WHAT THE GET REPORTS.
|
|
68
|
+
* MEASURED (pre-migration, replaying against four live token shapes — see the old PR): all
|
|
69
|
+
* answer noop; flipping `privsep` answers update; an empty body answers absent.
|
|
70
|
+
*/
|
|
71
|
+
export declare const matches: (attributes: ApiTokenAttributes, props: ApiTokenProps) => boolean;
|
|
70
72
|
//# sourceMappingURL=api-token-form.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-token-form.d.ts","sourceRoot":"","sources":["../../src/proxmox/api-token-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACxE
|
|
1
|
+
{"version":3,"file":"api-token-form.d.ts","sourceRoot":"","sources":["../../src/proxmox/api-token-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACxE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,KAAK,MAAM,MAAM,iCAAiC,CAAC;AAG/D,eAAO,MAAM,gBAAgB,mDAAmD,CAAC;AAEjF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,UAAW,aAAa,WAAuC,CAAC;AAExF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,KAAK,UAAW,aAAa,KAAG,MAAM,CAAC,yBAMlD,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,SACjB,MAAM,CAAC,0BAA0B,SAChC,aAAa,KACnB,kBAAkB,GAAG,SAYvB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,OAAO,eAAgB,kBAAkB,SAAS,aAAa,YAGtC,CAAC"}
|
|
@@ -2,17 +2,15 @@
|
|
|
2
2
|
* `Proxmox.ApiToken` — a PVE API token: the thing a service actually authenticates as.
|
|
3
3
|
*
|
|
4
4
|
* ⛔ THE SECRET EXISTS FOR ONE HTTP RESPONSE AND THEN NOWHERE. MEASURED from the cluster's own
|
|
5
|
-
* schema
|
|
6
|
-
*
|
|
7
|
-
* "
|
|
8
|
-
*
|
|
9
|
-
* `GET /access/users/metrics@pve/token/exporter` answers `{"expire":0,"privsep":0}`. PVE says
|
|
10
|
-
* it plainly on the POST: the value "needs to be stored as it cannot be retrieved afterwards".
|
|
5
|
+
* schema: POST returns `["full-tokenid","info","value"]`; PUT returns `["comment","expire",
|
|
6
|
+
* "full-tokenid","privsep","value"]` with `value` present ONLY when `regenerate` was set; GET
|
|
7
|
+
* returns `["comment","expire","privsep"]` and never the secret. PVE says it plainly on the
|
|
8
|
+
* POST: the value "needs to be stored as it cannot be retrieved afterwards".
|
|
11
9
|
*
|
|
12
10
|
* ⛔ SO A TOKEN THIS RESOURCE CREATES IS UNUSABLE, AND SAYING SO IS THE POINT OF THIS BLOCK. The
|
|
13
11
|
* secret may not become an attribute: Alchemy persists attributes UNENCRYPTED, and this estate's
|
|
14
|
-
* state store is a Postgres dumped nightly (the ⛔ in credentials.ts). So `reconcile`
|
|
15
|
-
*
|
|
12
|
+
* state store is a Postgres dumped nightly (the ⛔ in credentials.ts). So `reconcile` refuses
|
|
13
|
+
* before any POST, and what would land is a live credential in `/etc/pve/user.cfg` whose secret
|
|
16
14
|
* nobody holds. No `regenerate` rescues it, because a regenerated value is discarded the same
|
|
17
15
|
* way. The only escape is an operator who captured the value out of band — which this provider
|
|
18
16
|
* gives them no way to do.
|
|
@@ -20,48 +18,37 @@
|
|
|
20
18
|
* whole of a token's policy, and declaring them is real work: it is how `expire` stops being
|
|
21
19
|
* whatever somebody typed in 2024. Mint NEW tokens where the secret can be caught — OpenBao's
|
|
22
20
|
* `proxmox-c1` mount, or a human at `pveum user token add`.
|
|
23
|
-
* ⛔ ★ CORRECTED 2026-09-23 — THIS PARAGRAPH PREVIOUSLY SAID "THE CREATE PATH IS LEFT REACHABLE
|
|
24
|
-
* RATHER THAN STUBBED… the honest arrangement is a create that works". THAT CONTRADICTED THE
|
|
25
|
-
* `reconcile` BELOW, WHICH REFUSES: `handlers.reconcile` calls `Effect.die` by name when `read`
|
|
26
|
-
* answers absent, before any POST — metadata-only per decision 9 (2026-09-23), exported on the
|
|
27
|
-
* barrel as an adopt-and-manage-only Resource. A create that silently did nothing WOULD be the
|
|
28
|
-
* lie resource.ts's ★ describes for a stubbed delete; refusing loudly, by name, with the two
|
|
29
|
-
* ways to get a usable token, is the honest arrangement instead — see the ★ further down and
|
|
30
|
-
* api-token-adopt.test.ts's absent-token row, which pins the refusal and zero writes.
|
|
31
21
|
*
|
|
32
22
|
* ⛔ THERE IS NO `regenerate` PROP, AND IT IS NOT AN OVERSIGHT. PVE's own description: "All users
|
|
33
23
|
* of the previous secret will lose access after this operation." A prop for it would revoke a
|
|
34
24
|
* live credential during a deploy whose plan said `update`, and hand back a replacement this
|
|
35
|
-
* provider is obliged to throw away — breakage with no recovery.
|
|
36
|
-
* that owns the lease, or to a human who is watching.
|
|
25
|
+
* provider is obliged to throw away — breakage with no recovery.
|
|
37
26
|
*
|
|
38
27
|
* ⚠️ THERE IS A SECOND WRITER TO THESE OBJECTS AND IT IS THE ONE THIS PROVIDER RUNS ON. OpenBao's
|
|
39
|
-
* `proxmox-c1` engine mints PVE tokens under `hf-read@pve` and `hf-provision@pve`
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* one object by accident — but they share the USER: `hf-read@pve` held three live leases when
|
|
45
|
-
* this was written, and `Proxmox.User` deleting that account takes every one of them with it.
|
|
46
|
-
* ⛔ DO NOT DECLARE A TOKEN UNDER A MINT USER. `expire` is what makes that dangerous rather than
|
|
47
|
-
* untidy: point this resource at a lease token with the wrong expire and a 300-second
|
|
48
|
-
* credential becomes a permanent one — and on `hf-provision@pve` that credential carries
|
|
49
|
-
* `Permissions.Modify` at `/`. docs/privileges.md records what those 27 privileges buy.
|
|
28
|
+
* `proxmox-c1` engine mints PVE tokens under `hf-read@pve` and `hf-provision@pve` with an id it
|
|
29
|
+
* CHOOSES (`hf-<role>-<actor>-<entity6>-<stamp>-<nonce>`), so the two systems cannot collide on
|
|
30
|
+
* one object by accident — but they share the USER, and `Proxmox.User` deleting that account
|
|
31
|
+
* takes every one of its tokens with it. ⛔ DO NOT DECLARE A TOKEN UNDER A MINT USER: `expire`
|
|
32
|
+
* is what makes that dangerous — a 300-second lease token becomes a permanent one.
|
|
50
33
|
*
|
|
51
34
|
* ⚠️ PRIVILEGES, AND THE READ LANE CANNOT DO IT. MEASURED: all four methods on this path check
|
|
52
35
|
* `['or', ['userid-param','self'], ['userid-group', ['User.Modify']]]` — with no `Sys.Audit`
|
|
53
|
-
* alternative
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
36
|
+
* alternative — so the 3600s read lease reaches at most its OWN account's tokens and is refused
|
|
37
|
+
* for every other userid. `readRole: 'provision'` below, for the same reason storage.ts,
|
|
38
|
+
* sdn-zone.ts and sdn-vnet.ts set it, at the same cost: every plan mints a 300s non-renewable
|
|
39
|
+
* provision lease just to read.
|
|
40
|
+
*
|
|
41
|
+
* ★ MIGRATED OFF `client.ts`'s generic `pve()`/`pveHandlers`/`pveOperations` ONTO
|
|
42
|
+
* `@distilled.cloud/proxmox`'s typed `access.getAccessUserToken`/`putAccessUserToken`/
|
|
43
|
+
* `deleteAccessUserToken` (2026-09-24, decision 43's proxmox walk-down, the last access-family
|
|
44
|
+
* resource). There is no `createAccessUserToken` call anywhere in this file — the create branch
|
|
45
|
+
* was already provably unreachable before the migration (`reconcile` dies on an absent read
|
|
46
|
+
* before any create path runs), so nothing calls distilled's POST-shaped `updateAccessUserToken`
|
|
47
|
+
* operation either; see api-token-form.ts for why the generator gave it that name.
|
|
61
48
|
*/
|
|
62
49
|
import { Resource } from 'alchemy';
|
|
63
50
|
import * as Provider from 'alchemy/Provider';
|
|
64
|
-
import {
|
|
51
|
+
import type { PveRequirements, WithTarget } from './resource-spec.ts';
|
|
65
52
|
export interface ApiTokenProps extends WithTarget {
|
|
66
53
|
/**
|
|
67
54
|
* The account that owns the token, realm-qualified: `iac@pve`, `root@pam`. Identity.
|
|
@@ -75,57 +62,36 @@ export interface ApiTokenProps extends WithTarget {
|
|
|
75
62
|
/**
|
|
76
63
|
* The token's own name, unique within the account. Identity.
|
|
77
64
|
*
|
|
78
|
-
* ⚠️ PVE HAS NO RENAME
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* is what keeps it from looking like an omission.
|
|
88
|
-
* ⚠️ PATTERN `[A-Za-z][A-Za-z0-9.\-_]+`: a letter first, two characters minimum. The schema
|
|
89
|
-
* declares no maxLength; the OpenBao plugin assumes a conservative 64 rather than finding the
|
|
90
|
-
* real limit in production, and so should anything else.
|
|
65
|
+
* ⚠️ PVE HAS NO RENAME. Editing this prop (or `userid`) points `path` at a DIFFERENT token,
|
|
66
|
+
* which reads as absent and is then created — leaving the old token LIVE, invisible to the
|
|
67
|
+
* plan, while the new one is the unusable kind described at the top. Rename by declaring a
|
|
68
|
+
* delete and a create.
|
|
69
|
+
* ⛔ `diff` IS NOT OVERRIDDEN TO SAY `replace` THE WAY acl.ts DOES: there, replace removes a
|
|
70
|
+
* grant that can be rebuilt from its own tuple; here it would DELETE a live token —
|
|
71
|
+
* destroying an irrecoverable secret — to tidy up a name. Leaving the old token standing is
|
|
72
|
+
* the lesser harm.
|
|
73
|
+
* ⚠️ PATTERN `[A-Za-z][A-Za-z0-9.\-_]+`: a letter first, two characters minimum.
|
|
91
74
|
*/
|
|
92
75
|
tokenid: string;
|
|
93
|
-
/**
|
|
94
|
-
* Free text in `pveum user token list` and the UI. Empty is how it is cleared — see `shape`.
|
|
95
|
-
* ⚠️ ANY CHARACTER IS SAFE HERE, MEASURED, and it was worth checking: `user.cfg` is a
|
|
96
|
-
* colon-delimited line, so a comment holding a colon or a newline is the obvious place for a
|
|
97
|
-
* round-trip to lose a character and diff forever. PVE escapes it — `encode_text` turns
|
|
98
|
-
* `a:b\nc%d` into `a%3Ab%0Ac%25d` and `decode_text` gives it back byte for byte.
|
|
99
|
-
*/
|
|
76
|
+
/** Free text in `pveum user token list` and the UI. Empty is how it is cleared — see `shape`. */
|
|
100
77
|
comment?: string;
|
|
101
78
|
/**
|
|
102
79
|
* Seconds since the epoch, or 0 for "never expires".
|
|
103
80
|
*
|
|
104
81
|
* ⛔ REQUIRED, AND THE SCHEMA WILL TELL YOU IT NEED NOT BE. It declares the default "same as
|
|
105
82
|
* user", and the code never implements it: `generate_token` writes `expire` only when the
|
|
106
|
-
* parameter is defined,
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* back `"expire":0`. So "same as user" is documentation of an intention, not behaviour.
|
|
110
|
-
* ⛔ WHICH IS WHY IT IS NOT OPTIONAL-DEFAULTING-TO-0. That spelling reads identically and is far
|
|
111
|
-
* worse: an omitted `expire` would then quietly WRITE 0 over a live deadline, turning an
|
|
112
|
-
* expiring credential into a permanent one, and the plan would call it an update. Requiring
|
|
113
|
-
* the field makes "this token never expires" a sentence somebody had to type.
|
|
83
|
+
* parameter is defined, and the parser does `$expire = 0 if !$expire`. Required, so "this
|
|
84
|
+
* token never expires" is a sentence somebody had to type, rather than an omission that would
|
|
85
|
+
* quietly WRITE 0 over a live deadline.
|
|
114
86
|
*/
|
|
115
87
|
expire: number;
|
|
116
88
|
/**
|
|
117
89
|
* True keeps the token's privileges separate from its owner's — it gets NOTHING until an ACL
|
|
118
90
|
* names `fullTokenid`. False gives it the owner's privileges entire.
|
|
119
91
|
*
|
|
120
|
-
* ⛔ REQUIRED FOR THE SAME REASON AS `expire`, AND THE BLAST RADIUS IS LARGER.
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* preserve. Were this optional, adopting a live token without mentioning `privsep` would plan
|
|
124
|
-
* an update to 1 and STRIP a working credential of every privilege it has, silently: PVE
|
|
125
|
-
* returns 401/403 to the service, nothing errors here, and `iac@pve!apply` simply stops
|
|
126
|
-
* working. Required, so adopting a token is a sentence that states what it is.
|
|
127
|
-
* ⚠️ AND `false` IS NOT A SHRUG. It is a token with its owner's whole privilege set; under a
|
|
128
|
-
* provisioning account that is the account's full authority with a separate secret.
|
|
92
|
+
* ⛔ REQUIRED FOR THE SAME REASON AS `expire`, AND THE BLAST RADIUS IS LARGER. Were this
|
|
93
|
+
* optional, adopting a live token without mentioning `privsep` would plan an update to 1 and
|
|
94
|
+
* STRIP a working credential of every privilege it has, silently.
|
|
129
95
|
*/
|
|
130
96
|
privsep: boolean;
|
|
131
97
|
}
|
|
@@ -142,23 +108,16 @@ export interface ProxmoxApiToken extends Resource<'Proxmox.ApiToken', ApiTokenPr
|
|
|
142
108
|
}
|
|
143
109
|
/**
|
|
144
110
|
* ★ `retain` BY DEFAULT, AND THIS IS THE PLAINEST CASE FOR IT IN THE PACKAGE. A token's contents
|
|
145
|
-
* are one irreplaceable secret: delete it and the value is gone,
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* exporter feeding VictoriaMetrics), `agent@pve!executor`, `iac@pve!apply`, `iac@pve!ro`,
|
|
149
|
-
* `app@pve!app` and `mint@pve!engine` — the last being the parent credential the
|
|
150
|
-
* OpenBao mount itself authenticates with, so orphaning that one would stop every plan in this
|
|
151
|
-
* package, this resource included. `delete` is FULLY IMPLEMENTED (DELETE is a real method on
|
|
152
|
-
* this path, measured) and runs the moment a caller opts in with `.pipe(RemovalPolicy.destroy())`.
|
|
153
|
-
* See the ★ in resource.ts, which explains the convention once.
|
|
111
|
+
* are one irreplaceable secret: delete it and the value is gone, and every holder loses access
|
|
112
|
+
* the instant `cfs_write_file` returns — with no error raised anywhere near them. `delete` is
|
|
113
|
+
* FULLY IMPLEMENTED and runs the moment a caller opts in with `.pipe(RemovalPolicy.destroy())`.
|
|
154
114
|
*/
|
|
155
115
|
export declare const ProxmoxApiToken: import("alchemy").ResourceClass<ProxmoxApiToken>;
|
|
156
116
|
/**
|
|
157
|
-
* ⛔
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
* would report drift against a credential that was never its to hold.
|
|
117
|
+
* ⛔ THIS FAMILY ADOPTS AND MANAGES TOKENS; IT REFUSES TO MINT ONE — see the header. `reconcile`
|
|
118
|
+
* refuses by name before any write when the read finds nothing, so the create path this
|
|
119
|
+
* family's spec would otherwise need never runs, and no `createAccessUserToken`-shaped call
|
|
120
|
+
* exists in this file at all.
|
|
162
121
|
*/
|
|
163
122
|
export declare const ProxmoxApiTokenProvider: () => import("effect/Layer").Layer<Provider.Provider<ProxmoxApiToken>, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
164
123
|
//# sourceMappingURL=api-token.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../src/proxmox/api-token.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../src/proxmox/api-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAK7C,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAStE,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;OAYG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,8FAA8F;IAC9F,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAKlB;AAED,MAAM,WAAW,eAAgB,SAAQ,QAAQ,CAC/C,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,eAAe,kDAE1B,CAAC;AAaH;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,qIAgFjC,CAAC"}
|
|
@@ -80,7 +80,7 @@ export declare const createForm: (props: CephFsProps) => Record<string, string>;
|
|
|
80
80
|
* ⚠️ BOTH WRITES CHECK `Sys.Modify` ON `/` -- the root, with the breadth metric-server.ts warns
|
|
81
81
|
* about: granting it buys datacenter options and every other cluster-wide config write too.
|
|
82
82
|
*/
|
|
83
|
-
export declare const createFs: (props: CephFsProps) => Effect.Effect<undefined, Error, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
83
|
+
export declare const createFs: (props: CephFsProps) => Effect.Effect<undefined, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
84
84
|
/**
|
|
85
85
|
* DELETE the filesystem, then wait for the worker.
|
|
86
86
|
*
|
|
@@ -91,7 +91,7 @@ export declare const createFs: (props: CephFsProps) => Effect.Effect<undefined,
|
|
|
91
91
|
* fails with "ceph pools '<name>_data' and/or '<name>_metadata' already exist" -- that refusal is
|
|
92
92
|
* a BRAKE, not a bug, and it is the last thing standing between a mis-typed rename and the data.
|
|
93
93
|
*/
|
|
94
|
-
export declare const destroyFs: (props: CephFsProps) => Effect.Effect<void, Error, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
94
|
+
export declare const destroyFs: (props: CephFsProps) => Effect.Effect<void, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
95
95
|
/**
|
|
96
96
|
* The two read-back failures, as messages rather than as guesses.
|
|
97
97
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ceph-fs-wire.d.ts","sourceRoot":"","sources":["../../src/proxmox/ceph-fs-wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKlE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,SACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SACtB,WAAW,KACjB,gBAAgB,GAAG,SAkBrB,CAAC;AAaF,6FAA6F;AAC7F,eAAO,MAAM,UAAU,UAAW,WAAW,WAAgD,CAAC;AAM9F;;;GAGG;AACH,eAAO,MAAM,UAAU,UAAW,WAAW,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAGnE,CAAC;AA2DH;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,UAAW,WAAW,
|
|
1
|
+
{"version":3,"file":"ceph-fs-wire.d.ts","sourceRoot":"","sources":["../../src/proxmox/ceph-fs-wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKlE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,SACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SACtB,WAAW,KACjB,gBAAgB,GAAG,SAkBrB,CAAC;AAaF,6FAA6F;AAC7F,eAAO,MAAM,UAAU,UAAW,WAAW,WAAgD,CAAC;AAM9F;;;GAGG;AACH,eAAO,MAAM,UAAU,UAAW,WAAW,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAGnE,CAAC;AA2DH;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,UAAW,WAAW,iJAiBvC,CAAC;AAEL;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,UAAW,WAAW,4IAQxC,CAAC;AAEL;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,UAAW,WAAW,UAK1C,CAAC;AAEJ,eAAO,MAAM,YAAY,UAAW,WAAW,UAK5C,CAAC"}
|
|
@@ -149,6 +149,6 @@ export declare const osdAttributes: (leaf: CrushNode, props: CephOsdProps) => Ce
|
|
|
149
149
|
* added. ⚠️ A 404 or a 403 both arrive here as `undefined`: see the ⛔ on `readRole` in
|
|
150
150
|
* resource.ts for why that distinction is invisible and what it costs.
|
|
151
151
|
*/
|
|
152
|
-
export declare const readOsd: (props: CephOsdProps) => Effect.Effect<CephOsdAttributes | undefined, Error, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
152
|
+
export declare const readOsd: (props: CephOsdProps) => Effect.Effect<CephOsdAttributes | undefined, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
153
153
|
export {};
|
|
154
154
|
//# sourceMappingURL=ceph-osd-tree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ceph-osd-tree.d.ts","sourceRoot":"","sources":["../../src/proxmox/ceph-osd-tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAIlD,iFAAiF;AACjF,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAOzC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,SAAS,SAAU,SAAS,KAAG,SAAS,EAQpD,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,OAAO,SAAU,SAAS,SAAS,MAAM,0BACiB,CAAC;AAExE,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,EAAE,EAAE,OAAO,CAAC;IACZ,8FAA8F;IAC9F,YAAY,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,QAAQ,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,GAAG,EAAE,MAAM,CAAC;IACZ,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,SAAU,SAAS,SAAS,YAAY,KAAG,iBAanE,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,UAAW,YAAY,
|
|
1
|
+
{"version":3,"file":"ceph-osd-tree.d.ts","sourceRoot":"","sources":["../../src/proxmox/ceph-osd-tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAIlD,iFAAiF;AACjF,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAOzC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,SAAS,SAAU,SAAS,KAAG,SAAS,EAQpD,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,OAAO,SAAU,SAAS,SAAS,MAAM,0BACiB,CAAC;AAExE,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,EAAE,EAAE,OAAO,CAAC;IACZ,8FAA8F;IAC9F,YAAY,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,QAAQ,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,GAAG,EAAE,MAAM,CAAC;IACZ,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,SAAU,SAAS,SAAS,YAAY,KAAG,iBAanE,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,UAAW,YAAY,qKAMxC,CAAC"}
|
|
@@ -32,7 +32,7 @@ export declare const OSD_CREATE_ENDPOINT: EndpointKey;
|
|
|
32
32
|
* ⚠️ `dev` is `string | undefined` on the props and non-optional here: `createOsd` refuses first.
|
|
33
33
|
*/
|
|
34
34
|
export declare const createOsdForm: (props: CephOsdProps, dev: string) => Record<string, string>;
|
|
35
|
-
export declare const createOsd: (news: CephOsdProps) => Effect.Effect<import("./ceph-osd-tree.ts").CephOsdAttributes, Error, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
35
|
+
export declare const createOsd: (news: CephOsdProps) => Effect.Effect<import("./ceph-osd-tree.ts").CephOsdAttributes, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
36
36
|
/**
|
|
37
37
|
* ⛔ REMOVING THE DECLARATION REMOVES THE ASSERTION, NOT THE REPLICA, AND THAT ASYMMETRY IS THE
|
|
38
38
|
* POINT. `DELETE /nodes/{node}/ceph/osd/{osdid}` takes a replica out of a live pool — with
|
|
@@ -51,5 +51,5 @@ export declare const createOsd: (news: CephOsdProps) => Effect.Effect<import("./
|
|
|
51
51
|
* ⚠️ `cleanup` DEFAULTS TO FALSE, so the logical volumes survive and the disk can be re-added
|
|
52
52
|
* without a rebuild. Ceph still starts backfilling the missing copies the moment the OSD goes.
|
|
53
53
|
*/
|
|
54
|
-
export declare const destroyOsd: (olds: CephOsdProps) => Effect.Effect<unknown, Error, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
54
|
+
export declare const destroyOsd: (olds: CephOsdProps) => Effect.Effect<unknown, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
55
55
|
//# sourceMappingURL=ceph-osd-write.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ceph-osd-write.d.ts","sourceRoot":"","sources":["../../src/proxmox/ceph-osd-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAA+C,CAAC;AAIlF;;;GAGG;AACH,eAAO,MAAM,aAAa,UAAW,YAAY,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAGpF,CAAC;AAEH,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"ceph-osd-write.d.ts","sourceRoot":"","sources":["../../src/proxmox/ceph-osd-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAA+C,CAAC;AAIlF;;;GAGG;AACH,eAAO,MAAM,aAAa,UAAW,YAAY,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAGpF,CAAC;AAEH,eAAO,MAAM,SAAS,2MA6BpB,CAAC;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,SAAU,YAAY,+IAO1C,CAAC"}
|
|
@@ -24,7 +24,7 @@ export type PoolRead = (props: CephPoolProps) => Effect.Effect<CephPoolAttribute
|
|
|
24
24
|
* An empty list is trusted: the collection 403s when the role is too narrow rather than
|
|
25
25
|
* filtering, so `[]` really does mean a cluster with no pools.
|
|
26
26
|
*/
|
|
27
|
-
export declare const confirmAbsent: (props: CephPoolProps, collection: string, describe: string) => Effect.Effect<void, Error, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
27
|
+
export declare const confirmAbsent: (props: CephPoolProps, collection: string, describe: string) => Effect.Effect<void, Error | import("./credential-errors.ts").PveCredentialDenied, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
28
28
|
/**
|
|
29
29
|
* Wait for the cluster to agree, then answer the last thing it said.
|
|
30
30
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ceph-pool-settle.d.ts","sourceRoot":"","sources":["../../src/proxmox/ceph-pool-settle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,CACrB,KAAK,EAAE,aAAa,KACjB,MAAM,CAAC,MAAM,CAAC,kBAAkB,GAAG,SAAS,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;AAE3E;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,UAAW,aAAa,cAAc,MAAM,YAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"ceph-pool-settle.d.ts","sourceRoot":"","sources":["../../src/proxmox/ceph-pool-settle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,CACrB,KAAK,EAAE,aAAa,KACjB,MAAM,CAAC,MAAM,CAAC,kBAAkB,GAAG,SAAS,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;AAE3E;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,UAAW,aAAa,cAAc,MAAM,YAAY,MAAM,4IAcrF,CAAC;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,UACV,aAAa,QACd,QAAQ,QACR,CAAC,IAAI,EAAE,kBAAkB,GAAG,SAAS,KAAK,OAAO,+GASrD,CAAC"}
|
package/dist/proxmox/client.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import * as Effect from 'effect/Effect';
|
|
16
16
|
import * as HttpClient from 'effect/unstable/http/HttpClient';
|
|
17
|
-
import {
|
|
17
|
+
import type { ApiTarget, PveCredential, PveRole, PveTarget } from './credentials.ts';
|
|
18
18
|
export declare class PveError extends Error {
|
|
19
19
|
readonly status: number;
|
|
20
20
|
readonly method: string;
|
|
@@ -60,5 +60,5 @@ export declare const pveEnvelopeWith: (target: PveTarget, credential: PveCredent
|
|
|
60
60
|
* node that received the PUT. Any member serves any task path; the privilege skip is keyed on
|
|
61
61
|
* whether the caller IS the task's owner.
|
|
62
62
|
*/
|
|
63
|
-
export declare const pve: <T>(target: ApiTarget, role: PveRole, method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, form?: PveForm) => Effect.Effect<T | undefined, Error, HttpClient.HttpClient>;
|
|
63
|
+
export declare const pve: <T>(target: ApiTarget, role: PveRole, method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, form?: PveForm) => Effect.Effect<T | undefined, Error | import("./credential-errors.ts").PveCredentialDenied, HttpClient.HttpClient>;
|
|
64
64
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/proxmox/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAE9D,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/proxmox/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAKrF,qBAAa,QAAS,SAAQ,KAAK;IAE/B,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAHvB,YACW,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EAIf;CACF;AAcD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC;AA8FjE,uFAAuF;AACvF,eAAO,MAAM,OAAO,GAAI,CAAC,UACf,SAAS,cACL,aAAa,UACjB,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,QACnC,MAAM,SACL,OAAO,kEAgBZ,CAAC;AAEL;;;;;GAKG;AACH,eAAO,MAAM,eAAe,WAClB,SAAS,cACL,aAAa,UACjB,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,QACnC,MAAM,4EAmBV,CAAC;AAEL;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,GAAG,GAAI,CAAC,UACX,SAAS,QACX,OAAO,UACL,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,QACnC,MAAM,SACL,OAAO,sHAKZ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PveRole } from './credentials.ts';
|
|
2
|
+
declare const PveCredentialDenied_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
3
|
+
readonly _tag: "PveCredentialDenied";
|
|
4
|
+
} & Readonly<A>;
|
|
5
|
+
/**
|
|
6
|
+
* OpenBao answered 403 to `GET /v1/<mount>/creds/<role>`: this identity's AppRole has no grant
|
|
7
|
+
* for `role` on `mount` — measured 2026-09-24 as "the agent lane cannot mint `provision`" (the
|
|
8
|
+
* lane's policy grants `read` but not `provision`). A TYPED tag, not the plain `Error` every
|
|
9
|
+
* other mint failure still is (404 no such role/mount, 503 sealed, a network failure), because
|
|
10
|
+
* this ONE case means "refused, not evidence of anything about the object" — a family's
|
|
11
|
+
* `readOrUnreadable` (unreadable-read.ts) `catchTag`s exactly this, never any other mint
|
|
12
|
+
* failure, which stays a hard error precisely because it is NOT a scoped refusal.
|
|
13
|
+
*
|
|
14
|
+
* ⛔ WHY NOT EVERY NON-2xx: A 503 (sealed) or a 404 (misconfigured mount/role) is the estate
|
|
15
|
+
* BROKEN, not this identity being narrowly scoped — folding those into "unreadable, report
|
|
16
|
+
* noop" would hide a real outage behind a quiet, misleadingly reassuring plan. Only 403 is
|
|
17
|
+
* "this identity, this role, denied" and safe to read as "cannot see, not evidence of absence".
|
|
18
|
+
*/
|
|
19
|
+
export declare class PveCredentialDenied extends PveCredentialDenied_base<{
|
|
20
|
+
readonly mount: string;
|
|
21
|
+
readonly role: PveRole;
|
|
22
|
+
readonly detail: string;
|
|
23
|
+
}> {
|
|
24
|
+
get message(): string;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=credential-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-errors.d.ts","sourceRoot":"","sources":["../../src/proxmox/credential-errors.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;;;;AAEhD;;;;;;;;;;;;;GAaG;AACH,qBAAa,mBAAoB,SAAQ,yBAAwC;IAC/E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF"}
|