@zincapp/znvault-cli 4.7.1 → 4.8.0

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.
Files changed (35) hide show
  1. package/dist/commands/dynamic-secrets/types.d.ts +3 -0
  2. package/dist/commands/dynamic-secrets/types.d.ts.map +1 -1
  3. package/dist/commands/mysql/alias.d.ts +26 -0
  4. package/dist/commands/mysql/alias.d.ts.map +1 -0
  5. package/dist/commands/mysql/alias.js +56 -0
  6. package/dist/commands/mysql/alias.js.map +1 -0
  7. package/dist/commands/mysql/broker.d.ts +38 -0
  8. package/dist/commands/mysql/broker.d.ts.map +1 -0
  9. package/dist/commands/mysql/broker.js +171 -0
  10. package/dist/commands/mysql/broker.js.map +1 -0
  11. package/dist/commands/mysql/index.d.ts +33 -0
  12. package/dist/commands/mysql/index.d.ts.map +1 -0
  13. package/dist/commands/mysql/index.js +207 -0
  14. package/dist/commands/mysql/index.js.map +1 -0
  15. package/dist/commands/mysql/mycnf.d.ts +40 -0
  16. package/dist/commands/mysql/mycnf.d.ts.map +1 -0
  17. package/dist/commands/mysql/mycnf.js +136 -0
  18. package/dist/commands/mysql/mycnf.js.map +1 -0
  19. package/dist/commands/mysql/resolve.d.ts +18 -0
  20. package/dist/commands/mysql/resolve.d.ts.map +1 -0
  21. package/dist/commands/mysql/resolve.js +108 -0
  22. package/dist/commands/mysql/resolve.js.map +1 -0
  23. package/dist/commands/mysql/run.d.ts +156 -0
  24. package/dist/commands/mysql/run.d.ts.map +1 -0
  25. package/dist/commands/mysql/run.js +300 -0
  26. package/dist/commands/mysql/run.js.map +1 -0
  27. package/dist/commands/mysql/types.d.ts +29 -0
  28. package/dist/commands/mysql/types.d.ts.map +1 -0
  29. package/dist/commands/mysql/types.js +7 -0
  30. package/dist/commands/mysql/types.js.map +1 -0
  31. package/dist/index.js +2 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/lib/config/types.d.ts +4 -0
  34. package/dist/lib/config/types.d.ts.map +1 -1
  35. package/package.json +1 -1
@@ -63,6 +63,9 @@ export interface GeneratedCredential {
63
63
  maxExpiresAt: string;
64
64
  ttlSeconds: number;
65
65
  renewalCount: number;
66
+ host?: string;
67
+ port?: number;
68
+ database?: string;
66
69
  }
67
70
  export interface TestConnectionResult {
68
71
  success: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/commands/dynamic-secrets/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/commands/dynamic-secrets/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Add or overwrite a MySQL alias in the active profile.
3
+ */
4
+ export declare function addAlias(name: string, connection: string, role: string): void;
5
+ /**
6
+ * Get a MySQL alias from the active profile.
7
+ * Returns undefined if the alias does not exist.
8
+ */
9
+ export declare function getAlias(name: string): {
10
+ connection: string;
11
+ role: string;
12
+ } | undefined;
13
+ /**
14
+ * List all MySQL aliases in the active profile.
15
+ */
16
+ export declare function listAliases(): Array<{
17
+ name: string;
18
+ connection: string;
19
+ role: string;
20
+ }>;
21
+ /**
22
+ * Remove a MySQL alias from the active profile.
23
+ * No-op if the alias does not exist.
24
+ */
25
+ export declare function removeAlias(name: string): void;
26
+ //# sourceMappingURL=alias.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alias.d.ts","sourceRoot":"","sources":["../../../src/commands/mysql/alias.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAM7E;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAGvF;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAQvF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAO9C"}
@@ -0,0 +1,56 @@
1
+ // src/commands/mysql/alias.ts
2
+ /**
3
+ * Per-profile MySQL alias store.
4
+ *
5
+ * Aliases map a short name (e.g. "staging-rw") to a dynamic-secrets connection
6
+ * name and role name so that `znvault mysql exec staging-rw` can be used instead
7
+ * of spelling out the full --connection / --role flags every time.
8
+ *
9
+ * Aliases are stored under the active profile in the CLI config:
10
+ * profile.mysqlAliases: Record<string, { connection: string; role: string }>
11
+ */
12
+ import { getCurrentProfile, saveProfile } from '../../lib/config/profile.js';
13
+ import { getActiveProfileName } from '../../lib/config/profile.js';
14
+ /**
15
+ * Add or overwrite a MySQL alias in the active profile.
16
+ */
17
+ export function addAlias(name, connection, role) {
18
+ const profileName = getActiveProfileName();
19
+ const profile = getCurrentProfile();
20
+ const aliases = profile.mysqlAliases ?? {};
21
+ aliases[name] = { connection, role };
22
+ saveProfile(profileName, { ...profile, mysqlAliases: aliases });
23
+ }
24
+ /**
25
+ * Get a MySQL alias from the active profile.
26
+ * Returns undefined if the alias does not exist.
27
+ */
28
+ export function getAlias(name) {
29
+ const profile = getCurrentProfile();
30
+ return profile.mysqlAliases?.[name];
31
+ }
32
+ /**
33
+ * List all MySQL aliases in the active profile.
34
+ */
35
+ export function listAliases() {
36
+ const profile = getCurrentProfile();
37
+ const aliases = profile.mysqlAliases ?? {};
38
+ return Object.entries(aliases).map(([name, { connection, role }]) => ({
39
+ name,
40
+ connection,
41
+ role,
42
+ }));
43
+ }
44
+ /**
45
+ * Remove a MySQL alias from the active profile.
46
+ * No-op if the alias does not exist.
47
+ */
48
+ export function removeAlias(name) {
49
+ const profileName = getActiveProfileName();
50
+ const profile = getCurrentProfile();
51
+ const aliases = profile.mysqlAliases ?? {};
52
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
53
+ delete aliases[name];
54
+ saveProfile(profileName, { ...profile, mysqlAliases: aliases });
55
+ }
56
+ //# sourceMappingURL=alias.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alias.js","sourceRoot":"","sources":["../../../src/commands/mysql/alias.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,UAAkB,EAAE,IAAY;IACrE,MAAM,WAAW,GAAG,oBAAoB,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACrC,WAAW,CAAC,WAAW,EAAE,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,OAAO,OAAO,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;IAC3C,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACpE,IAAI;QACJ,UAAU;QACV,IAAI;KACL,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,WAAW,GAAG,oBAAoB,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;IAC3C,gEAAgE;IAChE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,WAAW,CAAC,WAAW,EAAE,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { GeneratedCredential } from '../dynamic-secrets/types.js';
2
+ /**
3
+ * Options for runBrokered.
4
+ */
5
+ export interface RunBrokeredOptions {
6
+ /** The dynamic-secrets role ID to generate credentials from. */
7
+ roleId: string;
8
+ /**
9
+ * Requested TTL in seconds. The server may cap this to the role's maxTtl.
10
+ * Defaults to DEFAULT_TTL_SECONDS (600).
11
+ */
12
+ ttlSeconds?: number;
13
+ /**
14
+ * Callback that receives the credential + the open cnf fd and its /dev/fd
15
+ * path. Should return the numeric child process exit code.
16
+ *
17
+ * The cnf inode is valid (reachable via `fdPath`) for the duration of this
18
+ * callback — its directory entry is already unlinked, so the child mysql must
19
+ * inherit `fd` at the same number (runMysql does this). The fd is closed and
20
+ * the lease is revoked immediately after the callback returns (or throws).
21
+ */
22
+ run: (ctx: {
23
+ credential: GeneratedCredential;
24
+ fd: number;
25
+ fdPath: string;
26
+ }) => Promise<number>;
27
+ }
28
+ /**
29
+ * Generate a lease, write its credentials to a temp my.cnf, run the callback,
30
+ * then revoke the lease and shred the my.cnf on EVERY exit path.
31
+ *
32
+ * @returns The numeric exit code returned by `run`.
33
+ * @throws If `run` throws, the error is rethrown after cleanup.
34
+ * @throws If the server does not return host/port in the credential,
35
+ * an upgrade error is thrown before `run` is called.
36
+ */
37
+ export declare function runBrokered(opts: RunBrokeredOptions): Promise<number>;
38
+ //# sourceMappingURL=broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../../src/commands/mysql/broker.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AA8DvE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,GAAG,EAAE,CAAC,GAAG,EAAE;QAAE,UAAU,EAAE,mBAAmB,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAChG;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4F3E"}
@@ -0,0 +1,171 @@
1
+ // src/commands/mysql/broker.ts
2
+ /**
3
+ * Brokered lease lifecycle for `znvault mysql exec/connect`.
4
+ *
5
+ * runBrokered:
6
+ * 1. Generates a short-lived dynamic-secret credential.
7
+ * 2. Writes credentials to a 0600 temp my.cnf on a memory-backed fs, then
8
+ * unlinks the directory entry immediately, keeping it alive via an open fd
9
+ * (spec F1 — no plaintext name on disk for the run).
10
+ * 3. Calls the injected `run` callback with { credential, fd, fdPath }.
11
+ * 4. In ALL exit paths (normal return, run error, SIGINT/SIGTERM/SIGHUP,
12
+ * uncaughtException) — calls a single idempotent cleanup() that:
13
+ * a. Closes the cnf fd (releasing the unlinked inode) + rmdir's the dir.
14
+ * b. Revokes the lease (3 retries: 1s/2s/4s backoff).
15
+ * "Already revoked" errors are treated as success.
16
+ * All retries exhausted → loud WARN with leaseId (TTL backstop).
17
+ * 5. Returns the numeric exit code from run, or rethrows run's error.
18
+ *
19
+ * Security guarantees (spec F1–F12):
20
+ * - Password only in 0600 temp file, never in argv/env/stdout.
21
+ * - host/port MUST come from the server; no --host fallback (spec F2).
22
+ * - Lease is always revoked; TTL is the backstop, not the primary mechanism.
23
+ * - Signal handlers are removed in the finally block to avoid leaks.
24
+ */
25
+ import { client } from '../../lib/client.js';
26
+ import { createMyCnf } from './mycnf.js';
27
+ /** Default lease TTL in seconds (spec F12 — may be capped by role maxTtl). */
28
+ const DEFAULT_TTL_SECONDS = 600;
29
+ /** Backoff delays in ms for revoke retries. */
30
+ const REVOKE_BACKOFF_MS = [1_000, 2_000, 4_000];
31
+ /** Maximum retries for revoke (length of REVOKE_BACKOFF_MS + 1 initial attempt). */
32
+ const REVOKE_MAX_ATTEMPTS = 1 + REVOKE_BACKOFF_MS.length; // 4 total
33
+ function sleep(ms) {
34
+ return new Promise((resolve) => setTimeout(resolve, ms));
35
+ }
36
+ /**
37
+ * Returns true if the error message indicates the lease is already revoked.
38
+ * The server throws "Cannot revoke <id>: lease is already REVOKED" (or similar).
39
+ *
40
+ * TODO: also check the HTTP status code (e.g. 404/409) once the client surfaces
41
+ * it on the error object — matching solely on err.message is fragile if the
42
+ * server error wording changes.
43
+ */
44
+ function isAlreadyRevoked(err) {
45
+ if (!(err instanceof Error))
46
+ return false;
47
+ const msg = err.message.toLowerCase();
48
+ return msg.includes('cannot revoke') || msg.includes('already revoked') || msg.includes('already_revoked');
49
+ }
50
+ /**
51
+ * Attempt to revoke the lease with up to REVOKE_MAX_ATTEMPTS tries.
52
+ * "Already revoked" errors are silently treated as success.
53
+ * If all attempts fail for other reasons, emits a loud WARN (does not throw).
54
+ */
55
+ async function revokeWithRetry(leaseId) {
56
+ let lastErr;
57
+ for (let attempt = 1; attempt <= REVOKE_MAX_ATTEMPTS; attempt++) {
58
+ try {
59
+ await client.post(`/v1/dynamic-secrets/leases/${leaseId}/revoke`, {
60
+ reason: 'znvault-mysql-exec-cleanup',
61
+ });
62
+ return; // success
63
+ }
64
+ catch (err) {
65
+ if (isAlreadyRevoked(err)) {
66
+ return; // treat as success
67
+ }
68
+ lastErr = err;
69
+ // Sleep between retries; no sleep after the last attempt.
70
+ if (attempt < REVOKE_MAX_ATTEMPTS) {
71
+ await sleep(REVOKE_BACKOFF_MS[attempt - 1] ?? 1_000);
72
+ }
73
+ }
74
+ }
75
+ // All retries exhausted — log loud WARN so the operator can manually revoke.
76
+ // Do NOT throw: the TTL backstop will clean up the DB user.
77
+ const errMsg = lastErr instanceof Error ? lastErr.message : String(lastErr);
78
+ console.warn(`[znvault] WARN: failed to revoke lease ${leaseId} after ${REVOKE_MAX_ATTEMPTS.toString()} attempts. ` +
79
+ `It will expire at its TTL. Last error: ${errMsg}`);
80
+ }
81
+ /**
82
+ * Generate a lease, write its credentials to a temp my.cnf, run the callback,
83
+ * then revoke the lease and shred the my.cnf on EVERY exit path.
84
+ *
85
+ * @returns The numeric exit code returned by `run`.
86
+ * @throws If `run` throws, the error is rethrown after cleanup.
87
+ * @throws If the server does not return host/port in the credential,
88
+ * an upgrade error is thrown before `run` is called.
89
+ */
90
+ export async function runBrokered(opts) {
91
+ const { roleId, run } = opts;
92
+ const requestedTtl = opts.ttlSeconds ?? DEFAULT_TTL_SECONDS;
93
+ // ── 1. Generate lease ───────────────────────────────────────────────────────
94
+ const credential = await client.post(`/v1/dynamic-secrets/roles/${roleId}/credentials`, { ttlSeconds: requestedTtl });
95
+ // Log the effective TTL (may differ from requested due to role maxTtl cap — spec F12).
96
+ if (credential.ttlSeconds !== requestedTtl) {
97
+ console.warn(`[znvault] Requested TTL ${requestedTtl.toString()}s was capped to ${credential.ttlSeconds.toString()}s by the role's maxTtl.`);
98
+ }
99
+ // ── 2. Validate host/port (spec F2 — no --host fallback) ───────────────────
100
+ if (!credential.host || credential.port === undefined) {
101
+ // Revoke the just-minted lease before throwing. revokeWithRetry applies the
102
+ // same retry/backoff as the main cleanup path (it does NOT skip retries).
103
+ await revokeWithRetry(credential.leaseId);
104
+ throw new Error(`Vault did not return host/port in the credential for role '${roleId}'. ` +
105
+ `Please upgrade vault to a version that returns host/port in dynamic-secret credentials.`);
106
+ }
107
+ // ── 3. Write temp my.cnf (open fd + immediate unlink — spec F1) ────────────
108
+ // The lease is minted but the idempotent cleanup()/try-finally below is not
109
+ // installed yet. If createMyCnf throws (disk full, mkdir race, EMFILE) here,
110
+ // the lease would be orphaned (only the TTL backstop would save it). Revoke it
111
+ // first, then rethrow. No double-revoke risk: cleanup() is not installed until
112
+ // after this succeeds, so on this path revoke fires exactly once (I-2).
113
+ let cnfFd;
114
+ let cnfFdPath;
115
+ let cleanupCnf;
116
+ try {
117
+ ({ fd: cnfFd, fdPath: cnfFdPath, cleanup: cleanupCnf } = await createMyCnf({
118
+ user: credential.username,
119
+ password: credential.password,
120
+ host: credential.host,
121
+ port: credential.port,
122
+ }));
123
+ }
124
+ catch (err) {
125
+ await revokeWithRetry(credential.leaseId);
126
+ throw err;
127
+ }
128
+ // ── 4. Idempotent cleanup (guarded by `cleaned` boolean) ───────────────────
129
+ let cleaned = false;
130
+ async function cleanup() {
131
+ if (cleaned)
132
+ return;
133
+ cleaned = true;
134
+ cleanupCnf();
135
+ await revokeWithRetry(credential.leaseId);
136
+ }
137
+ // ── 5. Signal handlers ──────────────────────────────────────────────────────
138
+ // SIGPIPE is intentionally not handled — treat as normal (don't crash).
139
+ // Each handler uses an async IIFE so cleanup() is properly awaited before
140
+ // process.exit. The outer `void` is the lint-clean way to fire-and-forget an
141
+ // async function from a synchronous signal handler — cleanup() cannot throw
142
+ // (revokeWithRetry eats errors, cleanupCnf is try/caught), so there is no
143
+ // unhandled rejection risk.
144
+ const onSIGINT = () => { void (async () => { await cleanup(); process.exit(130); })(); };
145
+ const onSIGTERM = () => { void (async () => { await cleanup(); process.exit(143); })(); };
146
+ const onSIGHUP = () => { void (async () => { await cleanup(); process.exit(129); })(); };
147
+ const onUncaughtException = (err) => {
148
+ console.error('[znvault] Uncaught exception during mysql exec:', err.stack ?? err);
149
+ void (async () => { await cleanup(); process.exit(1); })();
150
+ };
151
+ process.once('SIGINT', onSIGINT);
152
+ process.once('SIGTERM', onSIGTERM);
153
+ process.once('SIGHUP', onSIGHUP);
154
+ process.once('uncaughtException', onUncaughtException);
155
+ // ── 6. Run callback + cleanup in finally ────────────────────────────────────
156
+ try {
157
+ const exitCode = await run({ credential, fd: cnfFd, fdPath: cnfFdPath });
158
+ return exitCode;
159
+ }
160
+ finally {
161
+ // Remove signal handlers BEFORE awaiting cleanup so that a signal arriving
162
+ // during cleanup does not re-enter the handler (which would be a no-op due
163
+ // to the `cleaned` guard but would also leak across repeated runBrokered calls).
164
+ process.off('SIGINT', onSIGINT);
165
+ process.off('SIGTERM', onSIGTERM);
166
+ process.off('SIGHUP', onSIGHUP);
167
+ process.off('uncaughtException', onUncaughtException);
168
+ await cleanup();
169
+ }
170
+ }
171
+ //# sourceMappingURL=broker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker.js","sourceRoot":"","sources":["../../../src/commands/mysql/broker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Register `znvault mysql` commands: exec, connect, alias.
3
+ *
4
+ * Security guarantees (spec F1–F12):
5
+ * - assertMysqlOnPath() is called BEFORE generating a lease (fail-fast, no
6
+ * wasted credentials if mysql is absent — spec F1).
7
+ * - Password never in argv/env/stdout (broker writes 0600 my.cnf — spec F3).
8
+ * - host/port come from the vault server; no --host fallback (spec F2).
9
+ * If the server credential lacks host, runBrokered throws a clear upgrade
10
+ * error — surfaced here, never swallowed.
11
+ * - process.exit(code) propagates the mysql exit code so CI scripts can rely
12
+ * on non-zero exit to detect SQL failures.
13
+ */
14
+ import type { Command } from 'commander';
15
+ /**
16
+ * Parse and validate the `--ttl <seconds>` option (M-2).
17
+ *
18
+ * `parseInt('abc', 10)` is `NaN`, and `NaN ?? 600` stays `NaN` — which would be
19
+ * sent to the server as the requested TTL and produce a confusing bad request.
20
+ * Validate locally and fail fast with a clear message BEFORE any lease is
21
+ * generated.
22
+ *
23
+ * @param raw The raw `--ttl` option value, or undefined when not provided.
24
+ * @returns The parsed positive integer, or undefined when `--ttl` is absent
25
+ * (so the server/role default applies).
26
+ * @throws If `--ttl` is provided but is not a positive integer.
27
+ */
28
+ export declare function parseTtlSeconds(raw: string | undefined): number | undefined;
29
+ /**
30
+ * Register the `mysql` command group and all subcommands on `program`.
31
+ */
32
+ export declare function registerMysqlCommands(program: Command): void;
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/mysql/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBzC;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAS3E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmL5D"}
@@ -0,0 +1,207 @@
1
+ // src/commands/mysql/index.ts
2
+ import * as output from '../../lib/output.js';
3
+ import { resolveTarget } from './resolve.js';
4
+ import { runBrokered } from './broker.js';
5
+ import { assertMysqlOnPath, runMysql } from './run.js';
6
+ import { addAlias, listAliases, removeAlias } from './alias.js';
7
+ /**
8
+ * Collect helper for Commander repeatable options (--file <path> ... --file <path>).
9
+ * Each invocation appends the new value to the accumulator array.
10
+ */
11
+ function collect(value, previous) {
12
+ return [...previous, value];
13
+ }
14
+ /**
15
+ * Parse and validate the `--ttl <seconds>` option (M-2).
16
+ *
17
+ * `parseInt('abc', 10)` is `NaN`, and `NaN ?? 600` stays `NaN` — which would be
18
+ * sent to the server as the requested TTL and produce a confusing bad request.
19
+ * Validate locally and fail fast with a clear message BEFORE any lease is
20
+ * generated.
21
+ *
22
+ * @param raw The raw `--ttl` option value, or undefined when not provided.
23
+ * @returns The parsed positive integer, or undefined when `--ttl` is absent
24
+ * (so the server/role default applies).
25
+ * @throws If `--ttl` is provided but is not a positive integer.
26
+ */
27
+ export function parseTtlSeconds(raw) {
28
+ if (raw === undefined)
29
+ return undefined;
30
+ const ttl = Number(raw);
31
+ if (!Number.isInteger(ttl) || ttl <= 0) {
32
+ throw new Error(`Invalid --ttl '${raw}': must be a positive integer number of seconds.`);
33
+ }
34
+ return ttl;
35
+ }
36
+ /**
37
+ * Register the `mysql` command group and all subcommands on `program`.
38
+ */
39
+ export function registerMysqlCommands(program) {
40
+ const mysql = program
41
+ .command('mysql')
42
+ // enablePositionalOptions() lets the variadic [mysqlArgs...] coexist cleanly
43
+ // with named options — keeps '--' separator forwarding well-defined.
44
+ .enablePositionalOptions()
45
+ .description('Connect to MySQL databases via short-lived dynamic-secret credentials')
46
+ .addHelpText('after', `
47
+ Examples:
48
+ # Interactive shell (connect mode)
49
+ znvault mysql connect my-connection
50
+
51
+ # Execute SQL from a file
52
+ znvault mysql exec my-connection --file schema.sql
53
+
54
+ # Execute inline SQL
55
+ znvault mysql exec my-connection --sql "SELECT 1"
56
+
57
+ # Pipe SQL from stdin
58
+ echo "SELECT version()" | znvault mysql exec my-connection
59
+
60
+ # Use an alias (see: znvault mysql alias add)
61
+ znvault mysql connect staging-rw
62
+
63
+ # Save an alias for quick access
64
+ znvault mysql alias add staging-rw --connection staging-mysql --role app-rw
65
+
66
+ # Pass extra mysql flags after --
67
+ znvault mysql connect my-connection -- --table
68
+ `);
69
+ // ── exec ─────────────────────────────────────────────────────────────────────
70
+ //
71
+ // Using `exec <target> [mysqlArgs...]` (variadic) instead of passThroughOptions()
72
+ // so that named options (--role, --sql, etc.) can appear AFTER the positional
73
+ // <target> argument without being misread as excess positional args.
74
+ //
75
+ // With passThroughOptions(), Commander stops option-parsing at the first
76
+ // non-option token (the target), so `exec staging-mysql --role app-rw` was
77
+ // rejected as "too many arguments" — the target consumed the stop-point and
78
+ // --role/--sql were treated as excess positional args.
79
+ //
80
+ // The variadic approach: Commander continues parsing named options across the
81
+ // whole argv, and any unrecognised tokens (or tokens after `--`) land in the
82
+ // mysqlArgs array instead of causing an error. The `--` separator itself is
83
+ // NOT included in mysqlArgs — Commander strips it automatically.
84
+ mysql
85
+ .command('exec <target> [mysqlArgs...]')
86
+ .description('Execute SQL against a MySQL database via a short-lived credential')
87
+ .option('--role <name>', 'Dynamic-secrets role name or ID')
88
+ .option('--file <path>', 'SQL file to execute (repeatable; concatenated in order)', collect, [])
89
+ .option('--sql <sql>', 'Inline SQL to execute')
90
+ .option('--ttl <seconds>', `Requested lease TTL in seconds (default: 600; capped by role maxTtl)`)
91
+ .option('--database <db>', 'Database/schema to select (overrides the credential default)')
92
+ .action(async (target, mysqlArgs, opts) => {
93
+ // mysqlArgs contains any extra tokens (e.g. post-`--` flags like --batch).
94
+ // Commander excludes the `--` separator itself from this array.
95
+ const passthrough = mysqlArgs;
96
+ try {
97
+ // Fail fast: check mysql binary before generating any lease.
98
+ assertMysqlOnPath();
99
+ // Validate --ttl locally before generating any lease (M-2).
100
+ const ttlSeconds = parseTtlSeconds(opts.ttl);
101
+ const { roleId } = await resolveTarget(target, opts.role);
102
+ const code = await runBrokered({
103
+ roleId,
104
+ ttlSeconds,
105
+ run: ({ credential, fd, fdPath }) => runMysql({
106
+ fd,
107
+ fdPath,
108
+ database: opts.database ?? credential.database,
109
+ mode: 'exec',
110
+ files: opts.file,
111
+ sql: opts.sql,
112
+ passthrough,
113
+ }),
114
+ });
115
+ process.exit(code);
116
+ }
117
+ catch (err) {
118
+ output.error(err instanceof Error ? err.message : String(err));
119
+ process.exit(1);
120
+ }
121
+ });
122
+ // ── connect ───────────────────────────────────────────────────────────────────
123
+ // Same variadic idiom as exec — see exec comment above.
124
+ mysql
125
+ .command('connect <target> [mysqlArgs...]')
126
+ .description('Open an interactive MySQL shell via a short-lived credential')
127
+ .option('--role <name>', 'Dynamic-secrets role name or ID')
128
+ .option('--ttl <seconds>', `Requested lease TTL in seconds (default: 600; capped by role maxTtl)`)
129
+ .option('--database <db>', 'Database/schema to select (overrides the credential default)')
130
+ .action(async (target, mysqlArgs, opts) => {
131
+ const passthrough = mysqlArgs;
132
+ try {
133
+ // Fail fast: check mysql binary before generating any lease.
134
+ assertMysqlOnPath();
135
+ // Validate --ttl locally before generating any lease (M-2).
136
+ const ttlSeconds = parseTtlSeconds(opts.ttl);
137
+ const { roleId } = await resolveTarget(target, opts.role);
138
+ const code = await runBrokered({
139
+ roleId,
140
+ ttlSeconds,
141
+ run: ({ credential, fd, fdPath }) => runMysql({
142
+ fd,
143
+ fdPath,
144
+ database: opts.database ?? credential.database,
145
+ mode: 'connect',
146
+ passthrough,
147
+ }),
148
+ });
149
+ process.exit(code);
150
+ }
151
+ catch (err) {
152
+ output.error(err instanceof Error ? err.message : String(err));
153
+ process.exit(1);
154
+ }
155
+ });
156
+ // ── alias ─────────────────────────────────────────────────────────────────────
157
+ const alias = mysql
158
+ .command('alias')
159
+ .description('Manage MySQL connection aliases for quick access');
160
+ alias
161
+ .command('add <name>')
162
+ .description('Add or overwrite a MySQL connection alias')
163
+ .requiredOption('--connection <connection>', 'Connection name or ID to bind')
164
+ .requiredOption('--role <role>', 'Role name or ID to bind')
165
+ .action((name, opts) => {
166
+ try {
167
+ addAlias(name, opts.connection, opts.role);
168
+ output.success(`Alias '${name}' saved → ${opts.connection} / ${opts.role}`);
169
+ }
170
+ catch (err) {
171
+ output.error(err instanceof Error ? err.message : String(err));
172
+ process.exit(1);
173
+ }
174
+ });
175
+ alias
176
+ .command('list')
177
+ .alias('ls')
178
+ .description('List all MySQL aliases in the active profile')
179
+ .action(() => {
180
+ try {
181
+ const aliases = listAliases();
182
+ if (aliases.length === 0) {
183
+ output.info('No aliases defined. Use: znvault mysql alias add <name> --connection <c> --role <r>');
184
+ return;
185
+ }
186
+ output.table(['Name', 'Connection', 'Role'], aliases.map(({ name, connection, role }) => [name, connection, role]));
187
+ }
188
+ catch (err) {
189
+ output.error(err instanceof Error ? err.message : String(err));
190
+ process.exit(1);
191
+ }
192
+ });
193
+ alias
194
+ .command('rm <name>')
195
+ .description('Remove a MySQL alias from the active profile')
196
+ .action((name) => {
197
+ try {
198
+ removeAlias(name);
199
+ output.success(`Alias '${name}' removed`);
200
+ }
201
+ catch (err) {
202
+ output.error(err instanceof Error ? err.message : String(err));
203
+ process.exit(1);
204
+ }
205
+ });
206
+ }
207
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/mysql/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The result of createMyCnf.
3
+ *
4
+ * - `fd`: the open file descriptor backing the (now unlinked) my.cnf. The
5
+ * child mysql inherits this fd at the SAME number and re-opens it
6
+ * via `fdPath`.
7
+ * - `fdPath`: `/dev/fd/<fd>` — pass this verbatim as the value of
8
+ * `--defaults-extra-file`. Works on macOS (/dev/fd) and Linux
9
+ * (/dev/fd → /proc/self/fd).
10
+ * - `cleanup`: idempotent, best-effort. Closes `fd` (releasing the inode so its
11
+ * bytes are reclaimed) and rmdir's the now-empty mem-fs dir.
12
+ */
13
+ export interface MyCnfHandle {
14
+ /** Open fd backing the unlinked cnf inode. Child inherits it at this number. */
15
+ fd: number;
16
+ /** `/dev/fd/<fd>` — the value to pass to --defaults-extra-file. */
17
+ fdPath: string;
18
+ /** Idempotent best-effort teardown: closeSync(fd) + rmdir(dir). */
19
+ cleanup: () => void;
20
+ }
21
+ /**
22
+ * Create the temp my.cnf, unlink its directory entry immediately, and return an
23
+ * open fd plus an idempotent cleanup().
24
+ *
25
+ * The body is fully synchronous (all fs operations are *Sync), but the function
26
+ * returns a Promise to preserve the broker's `await createMyCnf(...)` contract
27
+ * (and so it can become genuinely async later without touching callers).
28
+ * Declared non-`async` + returning Promise.resolve avoids the require-await
29
+ * lint warning while keeping the Promise return type (M-5).
30
+ *
31
+ * @throws If the exclusive create fails (e.g. EEXIST on a suffix collision,
32
+ * which is astronomically unlikely with 8 random bytes, or ENOSPC).
33
+ */
34
+ export declare function createMyCnf(opts: {
35
+ user: string;
36
+ password: string;
37
+ host: string;
38
+ port: number;
39
+ }): Promise<MyCnfHandle>;
40
+ //# sourceMappingURL=mycnf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mycnf.d.ts","sourceRoot":"","sources":["../../../src/commands/mysql/mycnf.ts"],"names":[],"mappings":"AA2CA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,EAAE,EAAE,MAAM,CAAC;IACX,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;CAC5D,GAAG,OAAO,CAAC,WAAW,CAAC,CA8DvB"}