@intentius/sql-yodeler 0.3.0 → 0.4.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.
- package/README.md +1 -1
- package/dist/apply-steps/index.d.ts +65 -0
- package/dist/apply-steps/index.js +106 -0
- package/dist/apply-steps/index.js.map +1 -0
- package/dist/approval-mode/index.d.ts +78 -0
- package/dist/approval-mode/index.js +105 -0
- package/dist/approval-mode/index.js.map +1 -0
- package/dist/chant/access.d.ts +87 -0
- package/dist/chant/access.js +169 -0
- package/dist/chant/access.js.map +1 -0
- package/dist/chant/drift.d.ts +17 -1
- package/dist/chant/drift.js +55 -2
- package/dist/chant/drift.js.map +1 -1
- package/dist/chant/plan.d.ts +18 -2
- package/dist/chant/plan.js +21 -3
- package/dist/chant/plan.js.map +1 -1
- package/dist/ci/render.d.ts +54 -10
- package/dist/ci/render.js +249 -52
- package/dist/ci/render.js.map +1 -1
- package/dist/cleanup/index.d.ts +86 -0
- package/dist/cleanup/index.js +207 -0
- package/dist/cleanup/index.js.map +1 -0
- package/dist/commands/apply.js +153 -20
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/approve.d.ts +13 -0
- package/dist/commands/approve.js +206 -24
- package/dist/commands/approve.js.map +1 -1
- package/dist/commands/ci.js +12 -0
- package/dist/commands/ci.js.map +1 -1
- package/dist/commands/cleanup.d.ts +13 -0
- package/dist/commands/cleanup.js +138 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.js +136 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/drift.js +34 -3
- package/dist/commands/drift.js.map +1 -1
- package/dist/commands/index.js +6 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/lint.js +30 -6
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/new.js +133 -34
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/plan.js +42 -5
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.js +164 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/config/define.d.ts +117 -2
- package/dist/config/define.js +2 -0
- package/dist/config/define.js.map +1 -1
- package/dist/config/load.js +74 -10
- package/dist/config/load.js.map +1 -1
- package/dist/config/settings.d.ts +18 -0
- package/dist/config/settings.js +26 -0
- package/dist/config/settings.js.map +1 -1
- package/dist/credentials.d.ts +119 -0
- package/dist/credentials.js +119 -0
- package/dist/credentials.js.map +1 -0
- package/dist/exit.js +1 -1
- package/dist/exit.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/init/adopt.js +1 -1
- package/dist/init/adopt.js.map +1 -1
- package/dist/init/clickhouse-access.d.ts +64 -0
- package/dist/init/clickhouse-access.js +211 -0
- package/dist/init/clickhouse-access.js.map +1 -0
- package/dist/init/live.d.ts +4 -0
- package/dist/init/live.js +16 -0
- package/dist/init/live.js.map +1 -1
- package/dist/lint/access.d.ts +18 -0
- package/dist/lint/access.js +34 -0
- package/dist/lint/access.js.map +1 -0
- package/dist/lint/check.js +23 -6
- package/dist/lint/check.js.map +1 -1
- package/dist/lint/config.d.ts +7 -1
- package/dist/lint/config.js +11 -5
- package/dist/lint/config.js.map +1 -1
- package/dist/lint/index.d.ts +2 -0
- package/dist/lint/index.js +2 -0
- package/dist/lint/index.js.map +1 -1
- package/dist/lint/naming.d.ts +62 -0
- package/dist/lint/naming.js +138 -0
- package/dist/lint/naming.js.map +1 -0
- package/dist/lint/rules.d.ts +37 -4
- package/dist/lint/rules.js +16 -4
- package/dist/lint/rules.js.map +1 -1
- package/dist/lint/schema-checks.d.ts +63 -0
- package/dist/lint/schema-checks.js +128 -0
- package/dist/lint/schema-checks.js.map +1 -0
- package/dist/lint/statements.d.ts +22 -1
- package/dist/lint/statements.js +40 -1
- package/dist/lint/statements.js.map +1 -1
- package/dist/mcp/tools.d.ts +1 -1
- package/dist/mcp/tools.js +1 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/migrations/checkpoint.js +0 -2
- package/dist/migrations/checkpoint.js.map +1 -1
- package/dist/migrations/checks.d.ts +19 -1
- package/dist/migrations/checks.js +15 -0
- package/dist/migrations/checks.js.map +1 -1
- package/dist/migrations/create.d.ts +13 -4
- package/dist/migrations/create.js +24 -9
- package/dist/migrations/create.js.map +1 -1
- package/dist/migrations/routines.d.ts +5 -15
- package/dist/migrations/routines.js +5 -30
- package/dist/migrations/routines.js.map +1 -1
- package/dist/pr/model.d.ts +4 -1
- package/dist/pr/model.js +13 -5
- package/dist/pr/model.js.map +1 -1
- package/dist/pr/render.d.ts +4 -1
- package/dist/pr/render.js +22 -8
- package/dist/pr/render.js.map +1 -1
- package/dist/pr/tenants.d.ts +37 -0
- package/dist/pr/tenants.js +138 -0
- package/dist/pr/tenants.js.map +1 -0
- package/dist/probe.d.ts +27 -0
- package/dist/probe.js +106 -0
- package/dist/probe.js.map +1 -0
- package/dist/project.d.ts +16 -0
- package/dist/project.js +29 -1
- package/dist/project.js.map +1 -1
- package/dist/replay/clickhouse.d.ts +31 -0
- package/dist/replay/clickhouse.js +103 -6
- package/dist/replay/clickhouse.js.map +1 -1
- package/dist/replay/replay.d.ts +5 -2
- package/dist/replay/replay.js.map +1 -1
- package/dist/report/audit.d.ts +1 -1
- package/dist/report/audit.js +20 -3
- package/dist/report/audit.js.map +1 -1
- package/dist/schemas.d.ts +3 -1
- package/dist/schemas.js +2 -0
- package/dist/schemas.js.map +1 -1
- package/dist/sources/ddl.d.ts +15 -20
- package/dist/sources/ddl.js +34 -328
- package/dist/sources/ddl.js.map +1 -1
- package/dist/sources/index.js +2 -2
- package/dist/sources/index.js.map +1 -1
- package/dist/steps/backfill.d.ts +40 -5
- package/dist/steps/backfill.js +128 -8
- package/dist/steps/backfill.js.map +1 -1
- package/dist/steps/index.d.ts +19 -1
- package/dist/steps/index.js +34 -7
- package/dist/steps/index.js.map +1 -1
- package/dist/steps/kinds.d.ts +42 -4
- package/dist/steps/kinds.js +88 -14
- package/dist/steps/kinds.js.map +1 -1
- package/dist/steps/postgres-migration.d.ts +3 -0
- package/dist/steps/postgres-migration.js +7 -3
- package/dist/steps/postgres-migration.js.map +1 -1
- package/dist/steps/rebuild.d.ts +15 -6
- package/dist/steps/rebuild.js +12 -9
- package/dist/steps/rebuild.js.map +1 -1
- package/dist/tenants/index.d.ts +2 -1
- package/dist/tenants/index.js +3 -4
- package/dist/tenants/index.js.map +1 -1
- package/dist/tenants/wave.d.ts +128 -0
- package/dist/tenants/wave.js +254 -0
- package/dist/tenants/wave.js.map +1 -0
- package/dist/testing/define.d.ts +62 -0
- package/dist/testing/define.js +32 -0
- package/dist/testing/define.js.map +1 -0
- package/dist/testing/files.d.ts +5 -0
- package/dist/testing/files.js +18 -0
- package/dist/testing/files.js.map +1 -0
- package/dist/testing/report.d.ts +14 -0
- package/dist/testing/report.js +83 -0
- package/dist/testing/report.js.map +1 -0
- package/dist/testing/run.d.ts +104 -0
- package/dist/testing/run.js +328 -0
- package/dist/testing/run.js.map +1 -0
- package/dist/versioned/approval.d.ts +6 -0
- package/dist/versioned/approval.js +11 -5
- package/dist/versioned/approval.js.map +1 -1
- package/dist/versioned/checks.d.ts +8 -2
- package/dist/versioned/checks.js +34 -13
- package/dist/versioned/checks.js.map +1 -1
- package/dist/versioned/driver.d.ts +2 -2
- package/dist/versioned/engine.d.ts +10 -0
- package/dist/versioned/engine.js +8 -4
- package/dist/versioned/engine.js.map +1 -1
- package/dist/versioned/explain.d.ts +2 -0
- package/dist/versioned/explain.js +3 -1
- package/dist/versioned/explain.js.map +1 -1
- package/dist/versioned/state.js +1 -1
- package/dist/versioned/state.js.map +1 -1
- package/dist/waves/index.d.ts +58 -13
- package/dist/waves/index.js +109 -24
- package/dist/waves/index.js.map +1 -1
- package/dist/waves/record.d.ts +10 -0
- package/dist/waves/record.js.map +1 -1
- package/package.json +7 -7
- package/schemas/apply.schema.json +1 -1
- package/schemas/cleanup.schema.json +40 -0
- package/schemas/lint-rules.schema.json +4 -0
- package/schemas/new.schema.json +41 -3
- package/schemas/plan.schema.json +39 -0
- package/schemas/report.schema.json +1 -1
- package/schemas/test.schema.json +41 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/config/settings.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/config/settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reader and the writer of an environment (#50), for a project's
|
|
3
|
+
* `chant.config.ts`:
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { credentials } from "@intentius/sql-yodeler";
|
|
7
|
+
*
|
|
8
|
+
* profiles: {
|
|
9
|
+
* dev: { url: "postgres://127.0.0.1:5432/app", ...credentials("dev", "postgres"), schemas: ["app"] },
|
|
10
|
+
* prod: {
|
|
11
|
+
* url: "postgres://db.abc.us-east-1.rds.amazonaws.com:5432/app",
|
|
12
|
+
* ...credentials("prod", "postgres", { writer: { password: { token: "rds-iam" } } }),
|
|
13
|
+
* schemas: ["app"],
|
|
14
|
+
* },
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* `YODEL_CREDENTIALS` picks the role a process connects as: the reader
|
|
19
|
+
* unless it is `writer` (every environment) or `writer:<env>` (that one).
|
|
20
|
+
* Only an environment's apply job sets it. Each role reads its user and its
|
|
21
|
+
* password from a variable, by default `<ENV>_<DIALECT>_READER_USER`,
|
|
22
|
+
* `..._READER_PASSWORD`, `..._WRITER_USER` and `..._WRITER_PASSWORD`
|
|
23
|
+
* (`DEV_POSTGRES_READER_USER`), the names `yodel ci` maps the forge's
|
|
24
|
+
* secrets to. A role's password can instead be a short-lived token, minted
|
|
25
|
+
* by chant's sql lexicon when a connection needs it: `{ token: "rds-iam" }`,
|
|
26
|
+
* `{ token: "cloud-sql-iam" }` or `{ token: "entra" }` (Postgres), or
|
|
27
|
+
* `{ token: "command", command: ["./mint.sh"] }` (either dialect).
|
|
28
|
+
*
|
|
29
|
+
* The profile carries both roles under a symbol chant does not read, so
|
|
30
|
+
* yodel sees the reader and the writer from one evaluation of the config:
|
|
31
|
+
* it refuses (exit 4) an environment whose two roles are the same user or
|
|
32
|
+
* read the same variable, and `yodel ci` gives each job the variables, and
|
|
33
|
+
* the cloud identity, of the role it runs as.
|
|
34
|
+
*/
|
|
35
|
+
/** A value read from an environment variable, as chant's profiles name one. */
|
|
36
|
+
export interface EnvRef {
|
|
37
|
+
env: string;
|
|
38
|
+
}
|
|
39
|
+
/** A short-lived password, minted by chant's sql lexicon when a connection needs one. */
|
|
40
|
+
export type TokenSource = {
|
|
41
|
+
token: "rds-iam";
|
|
42
|
+
region?: string;
|
|
43
|
+
ttlSeconds?: number;
|
|
44
|
+
} | {
|
|
45
|
+
token: "cloud-sql-iam";
|
|
46
|
+
ttlSeconds?: number;
|
|
47
|
+
} | {
|
|
48
|
+
token: "entra";
|
|
49
|
+
ttlSeconds?: number;
|
|
50
|
+
} | {
|
|
51
|
+
token: "command";
|
|
52
|
+
command: string[];
|
|
53
|
+
ttlSeconds?: number;
|
|
54
|
+
};
|
|
55
|
+
/** The token sources that mint from a cloud identity, which a CI job gets over OIDC. */
|
|
56
|
+
export type CloudToken = Exclude<TokenSource["token"], "command">;
|
|
57
|
+
export declare const CLOUD_TOKENS: readonly CloudToken[];
|
|
58
|
+
export type Role = "reader" | "writer";
|
|
59
|
+
export declare const ROLES: readonly Role[];
|
|
60
|
+
/** One role's user and password. Either left out is read from its default variable. */
|
|
61
|
+
export interface RoleCredentials {
|
|
62
|
+
user?: EnvRef;
|
|
63
|
+
password?: EnvRef | TokenSource;
|
|
64
|
+
}
|
|
65
|
+
export type CredentialsDialect = "clickhouse" | "postgres";
|
|
66
|
+
/** Both roles of one environment, as {@link credentials} recorded them. */
|
|
67
|
+
export interface Credentials {
|
|
68
|
+
env: string;
|
|
69
|
+
dialect: CredentialsDialect;
|
|
70
|
+
/** The role this process connects as. */
|
|
71
|
+
role: Role;
|
|
72
|
+
reader: {
|
|
73
|
+
user: EnvRef;
|
|
74
|
+
password: EnvRef | TokenSource;
|
|
75
|
+
};
|
|
76
|
+
writer: {
|
|
77
|
+
user: EnvRef;
|
|
78
|
+
password: EnvRef | TokenSource;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** Where a profile made by {@link credentials} keeps both roles. A symbol, so chant's strict profile schema does not see it. */
|
|
82
|
+
export declare const CREDENTIALS: unique symbol;
|
|
83
|
+
/** What {@link credentials} returns: the chosen role's `user` and `password`, to spread into the profile. */
|
|
84
|
+
export interface ProfileCredentials {
|
|
85
|
+
user: EnvRef;
|
|
86
|
+
password: EnvRef | TokenSource;
|
|
87
|
+
[CREDENTIALS]: Credentials;
|
|
88
|
+
}
|
|
89
|
+
/** DEV_POSTGRES for dev on Postgres: what an environment's variables start with. */
|
|
90
|
+
export declare const credentialsPrefix: (env: string, dialect: CredentialsDialect) => string;
|
|
91
|
+
/** The role `YODEL_CREDENTIALS` picks for `env`: the writer under `writer` or `writer:<env>`, else the reader. */
|
|
92
|
+
export declare function roleOf(env: string, value?: string | undefined): Role;
|
|
93
|
+
/**
|
|
94
|
+
* The profile's `user` and `password` for the role `YODEL_CREDENTIALS`
|
|
95
|
+
* picks, with both roles recorded for yodel. `roles` replaces a role's
|
|
96
|
+
* user or password; what it leaves out is read from the default variable.
|
|
97
|
+
*/
|
|
98
|
+
export declare function credentials(env: string, dialect: CredentialsDialect, roles?: {
|
|
99
|
+
reader?: RoleCredentials;
|
|
100
|
+
writer?: RoleCredentials;
|
|
101
|
+
}): ProfileCredentials;
|
|
102
|
+
/** The roles a profile made by {@link credentials} carries; undefined for any other profile. */
|
|
103
|
+
export declare function credentialsOf(profile: unknown): Credentials | undefined;
|
|
104
|
+
/** The variables a role reads its user and password from (a token source reads none). */
|
|
105
|
+
export declare function roleVariables(c: Credentials, role: Role): string[];
|
|
106
|
+
/** The cloud token source a role's password is minted by, if it is one. */
|
|
107
|
+
export declare function cloudToken(c: Credentials, role: Role): CloudToken | undefined;
|
|
108
|
+
/** How a role's password is got, for a message: `DEV_POSTGRES_READER_PASSWORD` or `a rds-iam token`. */
|
|
109
|
+
export declare function describePassword(p: EnvRef | TokenSource): string;
|
|
110
|
+
/**
|
|
111
|
+
* Why environment `c.env`'s reader and writer are not two identities, or
|
|
112
|
+
* undefined when they are: both name the same user variable, both users
|
|
113
|
+
* resolve to the same name in `processEnv`, or both read the same password
|
|
114
|
+
* variable (a job holding the reader's would hold the writer's). The
|
|
115
|
+
* message names the variables and the user.
|
|
116
|
+
*/
|
|
117
|
+
export declare function sharedCredentials(c: Credentials, processEnv?: NodeJS.ProcessEnv): string | undefined;
|
|
118
|
+
/** The first refusal among a config's profiles, checked in order; see {@link sharedCredentials}. */
|
|
119
|
+
export declare function sharedCredentialsIn(profiles: Record<string, unknown>, processEnv?: NodeJS.ProcessEnv): string | undefined;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reader and the writer of an environment (#50), for a project's
|
|
3
|
+
* `chant.config.ts`:
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { credentials } from "@intentius/sql-yodeler";
|
|
7
|
+
*
|
|
8
|
+
* profiles: {
|
|
9
|
+
* dev: { url: "postgres://127.0.0.1:5432/app", ...credentials("dev", "postgres"), schemas: ["app"] },
|
|
10
|
+
* prod: {
|
|
11
|
+
* url: "postgres://db.abc.us-east-1.rds.amazonaws.com:5432/app",
|
|
12
|
+
* ...credentials("prod", "postgres", { writer: { password: { token: "rds-iam" } } }),
|
|
13
|
+
* schemas: ["app"],
|
|
14
|
+
* },
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* `YODEL_CREDENTIALS` picks the role a process connects as: the reader
|
|
19
|
+
* unless it is `writer` (every environment) or `writer:<env>` (that one).
|
|
20
|
+
* Only an environment's apply job sets it. Each role reads its user and its
|
|
21
|
+
* password from a variable, by default `<ENV>_<DIALECT>_READER_USER`,
|
|
22
|
+
* `..._READER_PASSWORD`, `..._WRITER_USER` and `..._WRITER_PASSWORD`
|
|
23
|
+
* (`DEV_POSTGRES_READER_USER`), the names `yodel ci` maps the forge's
|
|
24
|
+
* secrets to. A role's password can instead be a short-lived token, minted
|
|
25
|
+
* by chant's sql lexicon when a connection needs it: `{ token: "rds-iam" }`,
|
|
26
|
+
* `{ token: "cloud-sql-iam" }` or `{ token: "entra" }` (Postgres), or
|
|
27
|
+
* `{ token: "command", command: ["./mint.sh"] }` (either dialect).
|
|
28
|
+
*
|
|
29
|
+
* The profile carries both roles under a symbol chant does not read, so
|
|
30
|
+
* yodel sees the reader and the writer from one evaluation of the config:
|
|
31
|
+
* it refuses (exit 4) an environment whose two roles are the same user or
|
|
32
|
+
* read the same variable, and `yodel ci` gives each job the variables, and
|
|
33
|
+
* the cloud identity, of the role it runs as.
|
|
34
|
+
*/
|
|
35
|
+
export const CLOUD_TOKENS = ["rds-iam", "cloud-sql-iam", "entra"];
|
|
36
|
+
export const ROLES = ["reader", "writer"];
|
|
37
|
+
/** Where a profile made by {@link credentials} keeps both roles. A symbol, so chant's strict profile schema does not see it. */
|
|
38
|
+
export const CREDENTIALS = Symbol.for("@intentius/sql-yodeler/credentials");
|
|
39
|
+
/** DEV_POSTGRES for dev on Postgres: what an environment's variables start with. */
|
|
40
|
+
export const credentialsPrefix = (env, dialect) => `${env.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_${dialect.toUpperCase()}`;
|
|
41
|
+
/** The role `YODEL_CREDENTIALS` picks for `env`: the writer under `writer` or `writer:<env>`, else the reader. */
|
|
42
|
+
export function roleOf(env, value = process.env.YODEL_CREDENTIALS) {
|
|
43
|
+
return value === "writer" || value === `writer:${env}` ? "writer" : "reader";
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The profile's `user` and `password` for the role `YODEL_CREDENTIALS`
|
|
47
|
+
* picks, with both roles recorded for yodel. `roles` replaces a role's
|
|
48
|
+
* user or password; what it leaves out is read from the default variable.
|
|
49
|
+
*/
|
|
50
|
+
export function credentials(env, dialect, roles = {}) {
|
|
51
|
+
const prefix = credentialsPrefix(env, dialect);
|
|
52
|
+
const of = (role) => {
|
|
53
|
+
const r = roles[role] ?? {};
|
|
54
|
+
const upper = role.toUpperCase();
|
|
55
|
+
return { user: r.user ?? { env: `${prefix}_${upper}_USER` }, password: r.password ?? { env: `${prefix}_${upper}_PASSWORD` } };
|
|
56
|
+
};
|
|
57
|
+
const role = roleOf(env);
|
|
58
|
+
const recorded = { env, dialect, role, reader: of("reader"), writer: of("writer") };
|
|
59
|
+
const chosen = recorded[role];
|
|
60
|
+
return { user: chosen.user, password: chosen.password, [CREDENTIALS]: recorded };
|
|
61
|
+
}
|
|
62
|
+
/** The roles a profile made by {@link credentials} carries; undefined for any other profile. */
|
|
63
|
+
export function credentialsOf(profile) {
|
|
64
|
+
if (typeof profile !== "object" || profile === null)
|
|
65
|
+
return undefined;
|
|
66
|
+
const c = profile[CREDENTIALS];
|
|
67
|
+
return typeof c === "object" && c !== null ? c : undefined;
|
|
68
|
+
}
|
|
69
|
+
const isEnvRef = (v) => typeof v === "object" && v !== null && typeof v.env === "string";
|
|
70
|
+
/** The variables a role reads its user and password from (a token source reads none). */
|
|
71
|
+
export function roleVariables(c, role) {
|
|
72
|
+
const r = c[role];
|
|
73
|
+
return [r.user, r.password].filter(isEnvRef).map((v) => v.env);
|
|
74
|
+
}
|
|
75
|
+
/** The cloud token source a role's password is minted by, if it is one. */
|
|
76
|
+
export function cloudToken(c, role) {
|
|
77
|
+
const p = c[role].password;
|
|
78
|
+
return !isEnvRef(p) && CLOUD_TOKENS.includes(p.token) ? p.token : undefined;
|
|
79
|
+
}
|
|
80
|
+
/** How a role's password is got, for a message: `DEV_POSTGRES_READER_PASSWORD` or `a rds-iam token`. */
|
|
81
|
+
export function describePassword(p) {
|
|
82
|
+
if (isEnvRef(p))
|
|
83
|
+
return p.env;
|
|
84
|
+
return p.token === "command" ? `a command token (${p.command[0] ?? ""})` : `a ${p.token} token`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Why environment `c.env`'s reader and writer are not two identities, or
|
|
88
|
+
* undefined when they are: both name the same user variable, both users
|
|
89
|
+
* resolve to the same name in `processEnv`, or both read the same password
|
|
90
|
+
* variable (a job holding the reader's would hold the writer's). The
|
|
91
|
+
* message names the variables and the user.
|
|
92
|
+
*/
|
|
93
|
+
export function sharedCredentials(c, processEnv = process.env) {
|
|
94
|
+
const where = `sql.profiles.${c.env}`;
|
|
95
|
+
const { reader, writer } = c;
|
|
96
|
+
if (reader.user.env === writer.user.env) {
|
|
97
|
+
return `${where}: the reader and the writer read their user from the same variable, ${reader.user.env}, so a job that holds the reader holds the writer. Give the writer a user of its own (${credentialsPrefix(c.env, c.dialect)}_WRITER_USER).`;
|
|
98
|
+
}
|
|
99
|
+
const r = processEnv[reader.user.env];
|
|
100
|
+
const w = processEnv[writer.user.env];
|
|
101
|
+
if (r !== undefined && r !== "" && r === w) {
|
|
102
|
+
return `${where}: the reader (${reader.user.env}) and the writer (${writer.user.env}) are the same user, ${r}, so a job that holds the reader can write. Give each role its own database user.`;
|
|
103
|
+
}
|
|
104
|
+
if (isEnvRef(reader.password) && isEnvRef(writer.password) && reader.password.env === writer.password.env) {
|
|
105
|
+
return `${where}: the reader and the writer read their password from the same variable, ${reader.password.env}, so a job that holds the reader holds the writer's password. Give the writer a password variable of its own.`;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
/** The first refusal among a config's profiles, checked in order; see {@link sharedCredentials}. */
|
|
110
|
+
export function sharedCredentialsIn(profiles, processEnv = process.env) {
|
|
111
|
+
for (const profile of Object.values(profiles)) {
|
|
112
|
+
const c = credentialsOf(profile);
|
|
113
|
+
const why = c ? sharedCredentials(c, processEnv) : undefined;
|
|
114
|
+
if (why)
|
|
115
|
+
return why;
|
|
116
|
+
}
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
|
package/dist/exit.js
CHANGED
|
@@ -20,7 +20,7 @@ export const EXIT_CODES = [
|
|
|
20
20
|
[EXIT_ERROR, "an error"],
|
|
21
21
|
[EXIT_NEEDS_OP, "something yodel will not do itself (a change that needs an Op it does not run, a manual step); for yodel drift, drift found"],
|
|
22
22
|
[EXIT_OUTSTANDING, "something outstanding: apply stopped at its approval gate, status found pending migrations, lint found errors"],
|
|
23
|
-
[EXIT_REFUSED, "refused, nothing done: a checksum mismatch, an applied migration gone from the directory, an out-of-order migration, a fork or another problem in the migrations directory, a migration the environment it must run on first has not applied"],
|
|
23
|
+
[EXIT_REFUSED, "refused, nothing done: a checksum mismatch, an applied migration gone from the directory, an out-of-order migration, a fork or another problem in the migrations directory, a migration the environment it must run on first has not applied, an environment whose reader and writer are one identity"],
|
|
24
24
|
[EXIT_LOCKED, "another apply holds the lock"],
|
|
25
25
|
];
|
|
26
26
|
/** Why `yodel plan` exits 0 with pending migrations, where `yodel status` exits 3. */
|
package/dist/exit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exit.js","sourceRoot":"","sources":["../src/exit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AACzB,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5B,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B,2EAA2E;AAC3E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,6BAA6B;AAC7B,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAC9B,oCAAoC;AACpC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B,kDAAkD;AAClD,MAAM,CAAC,MAAM,UAAU,GAA6C;IAClE,CAAC,OAAO,EAAE,wBAAwB,CAAC;IACnC,CAAC,UAAU,EAAE,UAAU,CAAC;IACxB,CAAC,aAAa,EAAE,6HAA6H,CAAC;IAC9I,CAAC,gBAAgB,EAAE,+GAA+G,CAAC;IACnI,CAAC,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"exit.js","sourceRoot":"","sources":["../src/exit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AACzB,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5B,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B,2EAA2E;AAC3E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,6BAA6B;AAC7B,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAC9B,oCAAoC;AACpC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B,kDAAkD;AAClD,MAAM,CAAC,MAAM,UAAU,GAA6C;IAClE,CAAC,OAAO,EAAE,wBAAwB,CAAC;IACnC,CAAC,UAAU,EAAE,UAAU,CAAC;IACxB,CAAC,aAAa,EAAE,6HAA6H,CAAC;IAC9I,CAAC,gBAAgB,EAAE,+GAA+G,CAAC;IACnI,CAAC,YAAY,EAAE,uSAAuS,CAAC;IACvT,CAAC,WAAW,EAAE,8BAA8B,CAAC;CAC9C,CAAC;AAEF,sFAAsF;AACtF,MAAM,CAAC,MAAM,iBAAiB,GAC5B,4NAA4N,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
* ```
|
|
8
8
|
*/
|
|
9
9
|
export { defineConfig } from "./config/define.js";
|
|
10
|
-
export
|
|
10
|
+
export { credentials, roleOf } from "./credentials.js";
|
|
11
|
+
export type { CloudToken, Credentials, EnvRef, ProfileCredentials, Role, RoleCredentials, TokenSource } from "./credentials.js";
|
|
12
|
+
export type { ApprovalMode, EnvironmentApprovalMode, EnvironmentConfig, PolicyConfig, PolicyMigration, PolicyPlan, PolicyRule, PolicyStep, NotifyConfig, Topology, TopologySetting, YodelConfig } from "./config/define.js";
|
|
11
13
|
export { verifyWebhook, signWebhook } from "./notify/verify.js";
|
|
12
14
|
export type { NotifyEvent, NotifyEventKind } from "./notify/index.js";
|
|
13
15
|
export type { DdlSource } from "./sources/index.js";
|
|
16
|
+
export { defineTests, expectError, expectRows, expectValue } from "./testing/define.js";
|
|
17
|
+
export type { ErrorExpectation, Expectation, RowsExpectation, TestCase, ValueExpectation } from "./testing/define.js";
|
package/dist/index.js
CHANGED
|
@@ -7,5 +7,7 @@
|
|
|
7
7
|
* ```
|
|
8
8
|
*/
|
|
9
9
|
export { defineConfig } from "./config/define.js";
|
|
10
|
+
export { credentials, roleOf } from "./credentials.js";
|
|
10
11
|
export { verifyWebhook, signWebhook } from "./notify/verify.js";
|
|
12
|
+
export { defineTests, expectError, expectRows, expectValue } from "./testing/define.js";
|
|
11
13
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGhE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/init/adopt.js
CHANGED
|
@@ -82,7 +82,7 @@ async function adoptWith(project, env, venv, options, processEnv, log) {
|
|
|
82
82
|
if (live.ir.resources.length === 0) {
|
|
83
83
|
throw new YodelError(`refused: ${env.name} holds no objects in its scope (sql.profiles.${env.name}); there is nothing to adopt. Declare a schema and run yodel new instead. Nothing was written.`, REFUSED);
|
|
84
84
|
}
|
|
85
|
-
const objects = describeImported(live.ir);
|
|
85
|
+
const objects = [...describeImported(live.ir), ...(live.access ?? [])];
|
|
86
86
|
log(`read ${String(objects.length)} object(s) from ${env.name}`);
|
|
87
87
|
const journal = new Journal();
|
|
88
88
|
try {
|
package/dist/init/adopt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../src/init/adopt.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../src/init/adopt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClickHouse access control adopted by `yodel init --from` (#46), where the
|
|
3
|
+
* environment manages access: chant's ClickHouse import writes databases,
|
|
4
|
+
* tables, views, dictionaries and functions, and no user, role, row policy
|
|
5
|
+
* or grant, so yodel reads those itself and writes them as `user`, `role`,
|
|
6
|
+
* `policy` and `grant` declarations in `access.ts`, beside the import's
|
|
7
|
+
* `schema.ts`.
|
|
8
|
+
*
|
|
9
|
+
* What is adopted, read from the server's catalog:
|
|
10
|
+
*
|
|
11
|
+
* - every row policy on a table in the profile's databases;
|
|
12
|
+
* - the grantees: each user or role holding a privilege in those databases,
|
|
13
|
+
* each role a policy applies to, and each user or role those roles are
|
|
14
|
+
* granted to. The `default` user is the server's own and is left out;
|
|
15
|
+
* - for each grantee, its `CREATE USER` or `CREATE ROLE` and all of its
|
|
16
|
+
* grants (`SHOW GRANTS FOR`), not only those in the databases: chant
|
|
17
|
+
* compares a grantee's grants as a whole and revokes what is not
|
|
18
|
+
* declared, so a partial list would plan revokes.
|
|
19
|
+
*
|
|
20
|
+
* A user's authentication is the environment's: its `IDENTIFIED` clause is
|
|
21
|
+
* left out, and chant then compares the user without it and never creates
|
|
22
|
+
* or changes its password. A grantee with a partial revoke (`REVOKE` in
|
|
23
|
+
* `SHOW GRANTS`) cannot be declared, since a declaration holds no `REVOKE`:
|
|
24
|
+
* it is left out with a warning, and its grants with it.
|
|
25
|
+
*
|
|
26
|
+
* A table the import declared, or a user or role adopted here, is
|
|
27
|
+
* interpolated where a statement names it (`ON ${events}`, `TO ${reader}`),
|
|
28
|
+
* so the declarations carry their dependencies and a baseline creates them
|
|
29
|
+
* in order.
|
|
30
|
+
*/
|
|
31
|
+
import type { GeneratedFile } from "@intentius/chant/import/generator";
|
|
32
|
+
import type { TemplateIR } from "@intentius/chant/import/parser";
|
|
33
|
+
import type { Environment, Project } from "../project.js";
|
|
34
|
+
/** What {@link clickhouseAccessDeclarations} adopts. */
|
|
35
|
+
export interface AdoptedAccess {
|
|
36
|
+
/** `access.ts`, or none when there is nothing to adopt. */
|
|
37
|
+
file?: GeneratedFile;
|
|
38
|
+
/** The objects adopted, as `<kind> <name>` lines for people. */
|
|
39
|
+
objects: string[];
|
|
40
|
+
warnings: string[];
|
|
41
|
+
}
|
|
42
|
+
interface Statement {
|
|
43
|
+
kind: "user" | "role" | "policy" | "grant";
|
|
44
|
+
exportName: string;
|
|
45
|
+
/** The object's own name, never interpolated in its own statement. */
|
|
46
|
+
own?: string;
|
|
47
|
+
sql: string;
|
|
48
|
+
}
|
|
49
|
+
/** `CREATE USER u IDENTIFIED WITH sha256_password HOST ...` without its authentication, which is the environment's. */
|
|
50
|
+
export declare function withoutAuthentication(sql: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* The statement as a template body: `db.table` of a declared table as its
|
|
53
|
+
* export, and a principal as its export where the statement names it as a
|
|
54
|
+
* grantee, a granted role or a default role (anywhere in a `GRANT`, after
|
|
55
|
+
* `TO` in a row policy, after `DEFAULT ROLE` in a user). Strings and the
|
|
56
|
+
* object's own name stay as they are.
|
|
57
|
+
*/
|
|
58
|
+
export declare function templateOf(s: Pick<Statement, "kind" | "own" | "sql">, tables: ReadonlyMap<string, string>, principals: ReadonlyMap<string, string>): {
|
|
59
|
+
body: string;
|
|
60
|
+
refs: Set<string>;
|
|
61
|
+
};
|
|
62
|
+
/** The users, roles, row policies and grants to adopt from `env`, as `access.ts`; see the module comment. */
|
|
63
|
+
export declare function clickhouseAccessDeclarations(project: Project, env: Environment, ir: TemplateIR, processEnv: NodeJS.ProcessEnv): Promise<AdoptedAccess>;
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClickHouse access control adopted by `yodel init --from` (#46), where the
|
|
3
|
+
* environment manages access: chant's ClickHouse import writes databases,
|
|
4
|
+
* tables, views, dictionaries and functions, and no user, role, row policy
|
|
5
|
+
* or grant, so yodel reads those itself and writes them as `user`, `role`,
|
|
6
|
+
* `policy` and `grant` declarations in `access.ts`, beside the import's
|
|
7
|
+
* `schema.ts`.
|
|
8
|
+
*
|
|
9
|
+
* What is adopted, read from the server's catalog:
|
|
10
|
+
*
|
|
11
|
+
* - every row policy on a table in the profile's databases;
|
|
12
|
+
* - the grantees: each user or role holding a privilege in those databases,
|
|
13
|
+
* each role a policy applies to, and each user or role those roles are
|
|
14
|
+
* granted to. The `default` user is the server's own and is left out;
|
|
15
|
+
* - for each grantee, its `CREATE USER` or `CREATE ROLE` and all of its
|
|
16
|
+
* grants (`SHOW GRANTS FOR`), not only those in the databases: chant
|
|
17
|
+
* compares a grantee's grants as a whole and revokes what is not
|
|
18
|
+
* declared, so a partial list would plan revokes.
|
|
19
|
+
*
|
|
20
|
+
* A user's authentication is the environment's: its `IDENTIFIED` clause is
|
|
21
|
+
* left out, and chant then compares the user without it and never creates
|
|
22
|
+
* or changes its password. A grantee with a partial revoke (`REVOKE` in
|
|
23
|
+
* `SHOW GRANTS`) cannot be declared, since a declaration holds no `REVOKE`:
|
|
24
|
+
* it is left out with a warning, and its grants with it.
|
|
25
|
+
*
|
|
26
|
+
* A table the import declared, or a user or role adopted here, is
|
|
27
|
+
* interpolated where a statement names it (`ON ${events}`, `TO ${reader}`),
|
|
28
|
+
* so the declarations carry their dependencies and a baseline creates them
|
|
29
|
+
* in order.
|
|
30
|
+
*/
|
|
31
|
+
const quote = (s) => `'${s.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
32
|
+
const ident = (s) => `\`${s.replace(/`/g, "``")}\``;
|
|
33
|
+
const list = (xs) => xs.map(quote).join(", ");
|
|
34
|
+
const JS_RESERVED = new Set("break case catch class const continue debugger default delete do else enum export extends false finally for function if import in instanceof new null return super switch this throw true try typeof var void while with yield let static implements interface package private protected public await".split(" "));
|
|
35
|
+
function camel(name) {
|
|
36
|
+
const words = name.split(/[^A-Za-z0-9]+/).filter(Boolean);
|
|
37
|
+
const s = words.map((w, i) => (i === 0 ? w.charAt(0).toLowerCase() : w.charAt(0).toUpperCase()) + w.slice(1)).join("") || "object";
|
|
38
|
+
return /^[0-9]/.test(s) ? `a${s}` : s;
|
|
39
|
+
}
|
|
40
|
+
/** `CREATE USER u IDENTIFIED WITH sha256_password HOST ...` without its authentication, which is the environment's. */
|
|
41
|
+
export function withoutAuthentication(sql) {
|
|
42
|
+
return sql
|
|
43
|
+
.replace(/\s+NOT\s+IDENTIFIED\b/i, "")
|
|
44
|
+
.replace(/\s+IDENTIFIED\s+(?:WITH\s+\w+)?(?:\s+BY\s+'(?:[^'\\]|\\.)*')?(?:\s+SALT\s+'(?:[^'\\]|\\.)*')?/i, "");
|
|
45
|
+
}
|
|
46
|
+
/** The statement's tokens: quoted strings, identifiers (bare or backquoted, with `name` unquoted), and the rest. */
|
|
47
|
+
function tokens(sql) {
|
|
48
|
+
const out = [];
|
|
49
|
+
const re = /('(?:[^'\\]|\\.)*')|(`(?:[^`]|``)*`)|([A-Za-z_][A-Za-z0-9_]*)|(\s+|.)/gs;
|
|
50
|
+
for (let m = re.exec(sql); m; m = re.exec(sql)) {
|
|
51
|
+
if (m[1] !== undefined)
|
|
52
|
+
out.push({ kind: "string", text: m[1] });
|
|
53
|
+
else if (m[2] !== undefined)
|
|
54
|
+
out.push({ kind: "ident", text: m[2], name: m[2].slice(1, -1).replace(/``/g, "`") });
|
|
55
|
+
else if (m[3] !== undefined)
|
|
56
|
+
out.push({ kind: "ident", text: m[3], name: m[3] });
|
|
57
|
+
else
|
|
58
|
+
out.push({ kind: "other", text: m[4] ?? "" });
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
/** `text` escaped for a template literal. */
|
|
63
|
+
const literal = (text) => text.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
64
|
+
/**
|
|
65
|
+
* The statement as a template body: `db.table` of a declared table as its
|
|
66
|
+
* export, and a principal as its export where the statement names it as a
|
|
67
|
+
* grantee, a granted role or a default role (anywhere in a `GRANT`, after
|
|
68
|
+
* `TO` in a row policy, after `DEFAULT ROLE` in a user). Strings and the
|
|
69
|
+
* object's own name stay as they are.
|
|
70
|
+
*/
|
|
71
|
+
export function templateOf(s, tables, principals) {
|
|
72
|
+
const t = tokens(s.sql);
|
|
73
|
+
const refs = new Set();
|
|
74
|
+
let body = "";
|
|
75
|
+
let ownSeen = false;
|
|
76
|
+
let zone = s.kind === "grant";
|
|
77
|
+
for (let i = 0; i < t.length; i++) {
|
|
78
|
+
const tok = t[i];
|
|
79
|
+
if (tok === undefined)
|
|
80
|
+
break;
|
|
81
|
+
if (tok.kind === "ident") {
|
|
82
|
+
const word = tok.text.toUpperCase();
|
|
83
|
+
if (s.kind === "policy" && word === "TO")
|
|
84
|
+
zone = true;
|
|
85
|
+
if (s.kind === "user" && word === "DEFAULT" && t[i + 2]?.text.toUpperCase() === "ROLE")
|
|
86
|
+
zone = true;
|
|
87
|
+
if (s.kind === "user" && zone && ["SETTINGS", "GRANTEES", "HOST", "VALID", "IN"].includes(word))
|
|
88
|
+
zone = false;
|
|
89
|
+
// db.table
|
|
90
|
+
const next = t[i + 2];
|
|
91
|
+
if (t[i + 1]?.text === "." && next?.kind === "ident") {
|
|
92
|
+
const exp = tables.get(`${tok.name ?? ""}.${next.name ?? ""}`);
|
|
93
|
+
if (exp) {
|
|
94
|
+
body += `\${${exp}}`;
|
|
95
|
+
refs.add(exp);
|
|
96
|
+
i += 2;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (!ownSeen && s.own !== undefined && tok.name === s.own) {
|
|
101
|
+
ownSeen = true;
|
|
102
|
+
body += literal(tok.text);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const exp = zone && tok.name !== undefined ? principals.get(tok.name) : undefined;
|
|
106
|
+
if (exp && t[i - 1]?.text !== ".") {
|
|
107
|
+
body += `\${${exp}}`;
|
|
108
|
+
refs.add(exp);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
body += literal(tok.text);
|
|
113
|
+
}
|
|
114
|
+
return { body, refs };
|
|
115
|
+
}
|
|
116
|
+
/** The users, roles, row policies and grants to adopt from `env`, as `access.ts`; see the module comment. */
|
|
117
|
+
export async function clickhouseAccessDeclarations(project, env, ir, processEnv) {
|
|
118
|
+
const { bindClickHouse } = await import("@intentius/chant-lexicon-sql/clickhouse/live/bind");
|
|
119
|
+
const { clickhouseQuery } = await import("@intentius/chant-lexicon-sql/clickhouse/http");
|
|
120
|
+
const target = await bindClickHouse({ environment: env.name, config: project.config, cwd: project.dir, env: processEnv });
|
|
121
|
+
const q = (sql) => clickhouseQuery(target.endpoint, sql);
|
|
122
|
+
const first = async (sql) => Object.values((await q(sql))[0] ?? {})[0] ?? "";
|
|
123
|
+
const databases = target.databases ?? [];
|
|
124
|
+
const warnings = [];
|
|
125
|
+
if (databases.length === 0)
|
|
126
|
+
return { objects: [], warnings };
|
|
127
|
+
const policies = await q(`SELECT short_name AS name, database, table, apply_to_list FROM system.row_policies WHERE database IN (${list(databases)}) ORDER BY database, table, name`);
|
|
128
|
+
const holders = await q(`SELECT DISTINCT user_name, role_name FROM system.grants WHERE database IN (${list(databases)})`);
|
|
129
|
+
const named = new Set([...holders.flatMap((h) => [h.user_name, h.role_name]).filter((n) => !!n), ...policies.flatMap((p) => p.apply_to_list)]);
|
|
130
|
+
const allRoles = new Set((await q("SELECT name FROM system.roles")).map((r) => r.name));
|
|
131
|
+
const allUsers = new Set((await q("SELECT name FROM system.users")).map((r) => r.name));
|
|
132
|
+
const roles = new Set([...named].filter((n) => allRoles.has(n)));
|
|
133
|
+
const users = new Set([...named].filter((n) => allUsers.has(n) && n !== "default"));
|
|
134
|
+
if (roles.size > 0) {
|
|
135
|
+
for (const g of await q(`SELECT user_name, role_name FROM system.role_grants WHERE granted_role_name IN (${list([...roles])})`)) {
|
|
136
|
+
if (g.user_name && g.user_name !== "default")
|
|
137
|
+
users.add(g.user_name);
|
|
138
|
+
if (g.role_name)
|
|
139
|
+
roles.add(g.role_name);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Each grantee's grants whole; one with a partial revoke cannot be declared.
|
|
143
|
+
const grants = new Map();
|
|
144
|
+
for (const name of [...[...roles].sort(), ...[...users].sort()]) {
|
|
145
|
+
const lines = (await q(`SHOW GRANTS FOR ${ident(name)}`)).map((r) => Object.values(r)[0] ?? "");
|
|
146
|
+
if (lines.some((l) => /^\s*REVOKE\b/i.test(l))) {
|
|
147
|
+
warnings.push(`${roles.has(name) ? "role" : "user"} ${name} has a partial revoke (${lines.find((l) => /^\s*REVOKE\b/i.test(l)) ?? ""}), which a grant declaration cannot hold; left out, with its grants`);
|
|
148
|
+
roles.delete(name);
|
|
149
|
+
users.delete(name);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
grants.set(name, lines.filter((l) => /^\s*GRANT\b/i.test(l)));
|
|
153
|
+
}
|
|
154
|
+
const used = new Set(ir.resources.map((r) => r.logicalId));
|
|
155
|
+
const exportFor = (base) => {
|
|
156
|
+
let b = camel(base);
|
|
157
|
+
if (JS_RESERVED.has(b))
|
|
158
|
+
b = `${b}Access`;
|
|
159
|
+
let name = b;
|
|
160
|
+
for (let i = 2; used.has(name); i++)
|
|
161
|
+
name = `${b}${String(i)}`;
|
|
162
|
+
used.add(name);
|
|
163
|
+
return name;
|
|
164
|
+
};
|
|
165
|
+
const tables = new Map();
|
|
166
|
+
for (const r of ir.resources) {
|
|
167
|
+
const p = r.properties;
|
|
168
|
+
if (p.database !== undefined && p.name !== undefined && r.type !== "ClickHouse::Function")
|
|
169
|
+
tables.set(`${p.database}.${p.name}`, r.logicalId);
|
|
170
|
+
}
|
|
171
|
+
const statements = [];
|
|
172
|
+
const principals = new Map();
|
|
173
|
+
for (const name of [...roles].sort()) {
|
|
174
|
+
const exportName = exportFor(name);
|
|
175
|
+
principals.set(name, exportName);
|
|
176
|
+
statements.push({ kind: "role", exportName, own: name, sql: await first(`SHOW CREATE ROLE ${ident(name)}`) });
|
|
177
|
+
}
|
|
178
|
+
for (const name of [...users].sort()) {
|
|
179
|
+
const exportName = exportFor(name);
|
|
180
|
+
principals.set(name, exportName);
|
|
181
|
+
statements.push({ kind: "user", exportName, own: name, sql: withoutAuthentication(await first(`SHOW CREATE USER ${ident(name)}`)) });
|
|
182
|
+
}
|
|
183
|
+
for (const p of policies) {
|
|
184
|
+
const sql = await first(`SHOW CREATE ROW POLICY ${ident(p.name)} ON ${ident(p.database)}.${ident(p.table)}`);
|
|
185
|
+
statements.push({ kind: "policy", exportName: exportFor(`${p.table}_${p.name}`), own: p.name, sql });
|
|
186
|
+
}
|
|
187
|
+
for (const [grantee, lines] of grants) {
|
|
188
|
+
lines.forEach((sql, i) => {
|
|
189
|
+
statements.push({ kind: "grant", exportName: exportFor(`${grantee}_grant${lines.length > 1 ? `_${String(i + 1)}` : ""}`), sql });
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (statements.length === 0)
|
|
193
|
+
return { objects: [], warnings };
|
|
194
|
+
const bodies = statements.map((s) => ({ s, ...templateOf(s, tables, principals) }));
|
|
195
|
+
const declared = new Set(statements.map((s) => s.exportName));
|
|
196
|
+
const fromSchema = [...new Set(bodies.flatMap((b) => [...b.refs].filter((r) => !declared.has(r))))].sort();
|
|
197
|
+
const tags = [...new Set(statements.map((s) => s.kind))].sort();
|
|
198
|
+
const lines = [`import { ${tags.join(", ")} } from "@intentius/chant-lexicon-sql/clickhouse";`];
|
|
199
|
+
if (fromSchema.length > 0)
|
|
200
|
+
lines.push(`import { ${fromSchema.join(", ")} } from "./schema.js";`);
|
|
201
|
+
lines.push("");
|
|
202
|
+
// Roles, then users (whose default role names a role), then policies and grants, so each comes after what it interpolates.
|
|
203
|
+
for (const b of bodies)
|
|
204
|
+
lines.push(`export const ${b.s.exportName} = ${b.s.kind}\`${b.body}\`;`, "");
|
|
205
|
+
return {
|
|
206
|
+
file: { path: "access.ts", content: `${lines.join("\n").trimEnd()}\n` },
|
|
207
|
+
objects: statements.map((s) => (s.kind === "grant" ? `Grant ${s.sql}` : `${s.kind === "policy" ? "RowPolicy" : s.kind === "user" ? "User" : "Role"} ${s.own ?? ""}`)),
|
|
208
|
+
warnings,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=clickhouse-access.js.map
|