clickhouse-migrations 1.0.5 → 1.1.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 CHANGED
@@ -19,6 +19,8 @@ For migrations' content should be used correct SQL ClickHouse queries. Multiple
19
19
 
20
20
  If the database provided in the `--db` option (or in `CH_MIGRATIONS_DB`) doesn't exist, it will be created automatically.
21
21
 
22
+ For TLS/HTTPS connections, you can provide a custom CA certificate and optional client certificate/key via the `--ca-cert`, `--cert`, and `--key` options (or the `CH_MIGRATIONS_CA_CERT`, `CH_MIGRATIONS_CERT`, and `CH_MIGRATIONS_KEY` environment variables).
23
+
22
24
  ```
23
25
  Usage
24
26
  $ clickhouse-migrations migrate <options>
@@ -36,6 +38,9 @@ If the database provided in the `--db` option (or in `CH_MIGRATIONS_DB`) doesn't
36
38
  (default: 'ENGINE=Atomic')
37
39
  --timeout=<value> Client request timeout
38
40
  (milliseconds, default: 30000)
41
+ --ca-cert=<path> CA certificate file path
42
+ --cert=<path> Client certificate file path
43
+ --key=<path> Client key file path
39
44
 
40
45
  Environment variables
41
46
  Instead of options can be used environment variables.
@@ -48,6 +53,10 @@ If the database provided in the `--db` option (or in `CH_MIGRATIONS_DB`) doesn't
48
53
  CH_MIGRATIONS_DB_ENGINE (optional) DB engine (--db-engine)
49
54
  CH_MIGRATIONS_TIMEOUT (optional) Client request timeout
50
55
  (--timeout)
56
+ CH_MIGRATIONS_CA_CERT (optional) CA certificate file path
57
+ CH_MIGRATIONS_CERT (optional) Client certificate file path
58
+ CH_MIGRATIONS_KEY (optional) Client key file path
59
+
51
60
 
52
61
  CLI executions examples
53
62
  settings are passed as command-line options
@@ -66,6 +75,12 @@ If the database provided in the `--db` option (or in `CH_MIGRATIONS_DB`) doesn't
66
75
 
67
76
  settings provided partially through options and environment variables
68
77
  clickhouse-migrations migrate --timeout=60000
78
+
79
+ settings provided as options with TLS certificates
80
+ clickhouse-migrations migrate --host=https://localhost:8443
81
+ --user=default --password='' --db=analytics
82
+ --migrations-home=/app/clickhouse/migrations
83
+ --ca-cert=/app/certs/ca.pem --cert=/app/certs/client.crt --key=/app/certs/client.key
69
84
  ```
70
85
 
71
86
  Migration file example:
package/lib/migrate.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- declare const migration: (migrations_home: string, host: string, username: string, password: string, db_name: string, db_engine?: string, timeout?: string) => Promise<void>;
1
+ declare const migration: (migrations_home: string, host: string, username: string, password: string, db_name: string, db_engine?: string, timeout?: string, ca_cert?: string | undefined, cert?: string | undefined, key?: string | undefined) => Promise<void>;
2
2
  declare const migrate: () => void;
3
3
  export { migrate, migration };
package/lib/migrate.js CHANGED
@@ -63,7 +63,7 @@ var log = function (type, message, error) {
63
63
  console.error('\x1b[36m', "clickhouse-migrations :", '\x1b[31m', "Error: ".concat(message), error ? "\n\n ".concat(error) : '');
64
64
  }
65
65
  };
66
- var connect = function (url, username, password, db_name, timeout) {
66
+ var connect = function (url, username, password, db_name, timeout, ca_cert, cert, key) {
67
67
  var db_params = {
68
68
  url: url,
69
69
  username: username,
@@ -76,6 +76,26 @@ var connect = function (url, username, password, db_name, timeout) {
76
76
  if (timeout) {
77
77
  db_params.request_timeout = Number(timeout);
78
78
  }
79
+ if (ca_cert) {
80
+ try {
81
+ if (cert && key) {
82
+ db_params.tls = {
83
+ ca_cert: fs_1.default.readFileSync(ca_cert),
84
+ cert: fs_1.default.readFileSync(cert),
85
+ key: fs_1.default.readFileSync(key),
86
+ };
87
+ }
88
+ else {
89
+ db_params.tls = {
90
+ ca_cert: fs_1.default.readFileSync(ca_cert),
91
+ };
92
+ }
93
+ }
94
+ catch (e) {
95
+ log('error', 'Failed to read CA certificate file for TLS connection.', e instanceof Error ? e.message : String(e));
96
+ process.exit(1);
97
+ }
98
+ }
79
99
  return (0, client_1.createClient)(db_params);
80
100
  };
81
101
  var create_db = function (host_1, username_1, password_1, db_name_1) {
@@ -83,33 +103,46 @@ var create_db = function (host_1, username_1, password_1, db_name_1) {
83
103
  for (var _i = 4; _i < arguments.length; _i++) {
84
104
  args_1[_i - 4] = arguments[_i];
85
105
  }
86
- return __awaiter(void 0, __spreadArray([host_1, username_1, password_1, db_name_1], args_1, true), void 0, function (host, username, password, db_name, db_engine) {
87
- var client, q, e_1;
106
+ return __awaiter(void 0, __spreadArray([host_1, username_1, password_1, db_name_1], args_1, true), void 0, function (host, username, password, db_name, db_engine, timeout, ca_cert, cert, key) {
107
+ var client, e_1, q, e_2;
88
108
  if (db_engine === void 0) { db_engine = 'ENGINE=Atomic'; }
89
109
  return __generator(this, function (_a) {
90
110
  switch (_a.label) {
91
111
  case 0:
92
- client = connect(host, username, password);
93
- q = "CREATE DATABASE IF NOT EXISTS \"".concat(db_name, "\" ").concat(db_engine);
112
+ client = connect(host, username, password, undefined, timeout, ca_cert, cert, key);
94
113
  _a.label = 1;
95
114
  case 1:
96
115
  _a.trys.push([1, 3, , 4]);
97
- return [4 /*yield*/, client.exec({
98
- query: q,
99
- clickhouse_settings: {
100
- wait_end_of_query: 1,
101
- },
102
- })];
116
+ return [4 /*yield*/, client.ping()];
103
117
  case 2:
104
118
  _a.sent();
105
119
  return [3 /*break*/, 4];
106
120
  case 3:
107
121
  e_1 = _a.sent();
108
- log('error', "can't create the database ".concat(db_name, "."), e_1.message);
122
+ log('error', "Failed to connect to ClickHouse", e_1.message);
109
123
  process.exit(1);
110
124
  return [3 /*break*/, 4];
111
- case 4: return [4 /*yield*/, client.close()];
125
+ case 4:
126
+ q = "CREATE DATABASE IF NOT EXISTS \"".concat(db_name, "\" ").concat(db_engine);
127
+ _a.label = 5;
112
128
  case 5:
129
+ _a.trys.push([5, 7, , 8]);
130
+ return [4 /*yield*/, client.exec({
131
+ query: q,
132
+ clickhouse_settings: {
133
+ wait_end_of_query: 1,
134
+ },
135
+ })];
136
+ case 6:
137
+ _a.sent();
138
+ return [3 /*break*/, 8];
139
+ case 7:
140
+ e_2 = _a.sent();
141
+ log('error', "can't create the database ".concat(db_name, "."), e_2.message);
142
+ process.exit(1);
143
+ return [3 /*break*/, 8];
144
+ case 8: return [4 /*yield*/, client.close()];
145
+ case 9:
113
146
  _a.sent();
114
147
  return [2 /*return*/];
115
148
  }
@@ -117,7 +150,7 @@ var create_db = function (host_1, username_1, password_1, db_name_1) {
117
150
  });
118
151
  };
119
152
  var init_migration_table = function (client) { return __awaiter(void 0, void 0, void 0, function () {
120
- var q, e_2;
153
+ var q, e_3;
121
154
  return __generator(this, function (_a) {
122
155
  switch (_a.label) {
123
156
  case 0:
@@ -135,8 +168,8 @@ var init_migration_table = function (client) { return __awaiter(void 0, void 0,
135
168
  _a.sent();
136
169
  return [3 /*break*/, 4];
137
170
  case 3:
138
- e_2 = _a.sent();
139
- log('error', "can't create the _migrations table.", e_2.message);
171
+ e_3 = _a.sent();
172
+ log('error', "can't create the _migrations table.", e_3.message);
140
173
  process.exit(1);
141
174
  return [3 /*break*/, 4];
142
175
  case 4: return [2 /*return*/];
@@ -176,7 +209,7 @@ var get_migrations = function (migrations_home) {
176
209
  return migrations;
177
210
  };
178
211
  var apply_migrations = function (client, migrations, migrations_home) { return __awaiter(void 0, void 0, void 0, function () {
179
- var migration_query_result, resultSet, e_3, migrations_applied, applied_migrations, _i, migrations_1, migration_1, content, checksum, queries, sets, _a, queries_1, query, e_4, e_5;
212
+ var migration_query_result, resultSet, e_4, migrations_applied, applied_migrations, _i, migrations_1, migration_1, content, checksum, queries, sets, _a, queries_1, query, e_5, e_6;
180
213
  return __generator(this, function (_b) {
181
214
  switch (_b.label) {
182
215
  case 0:
@@ -195,8 +228,8 @@ var apply_migrations = function (client, migrations, migrations_home) { return _
195
228
  migration_query_result = _b.sent();
196
229
  return [3 /*break*/, 5];
197
230
  case 4:
198
- e_3 = _b.sent();
199
- log('error', "can't select data from the _migrations table.", e_3.message);
231
+ e_4 = _b.sent();
232
+ log('error', "can't select data from the _migrations table.", e_4.message);
200
233
  process.exit(1);
201
234
  return [3 /*break*/, 5];
202
235
  case 5:
@@ -252,11 +285,11 @@ var apply_migrations = function (client, migrations, migrations_home) { return _
252
285
  _b.sent();
253
286
  return [3 /*break*/, 11];
254
287
  case 10:
255
- e_4 = _b.sent();
288
+ e_5 = _b.sent();
256
289
  if (applied_migrations) {
257
290
  log('info', "The migration(s) ".concat(applied_migrations, " was successfully applied!"));
258
291
  }
259
- log('error', "the migrations ".concat(migration_1.file, " has an error. Please, fix it (be sure that already executed parts of the migration would not be run second time) and re-run migration script."), e_4.message);
292
+ log('error', "the migrations ".concat(migration_1.file, " has an error. Please, fix it (be sure that already executed parts of the migration would not be run second time) and re-run migration script."), e_5.message);
260
293
  process.exit(1);
261
294
  return [3 /*break*/, 11];
262
295
  case 11:
@@ -273,8 +306,8 @@ var apply_migrations = function (client, migrations, migrations_home) { return _
273
306
  _b.sent();
274
307
  return [3 /*break*/, 15];
275
308
  case 14:
276
- e_5 = _b.sent();
277
- log('error', "can't insert a data into the table _migrations.", e_5.message);
309
+ e_6 = _b.sent();
310
+ log('error', "can't insert a data into the table _migrations.", e_6.message);
278
311
  process.exit(1);
279
312
  return [3 /*break*/, 15];
280
313
  case 15:
@@ -294,16 +327,16 @@ var apply_migrations = function (client, migrations, migrations_home) { return _
294
327
  }
295
328
  });
296
329
  }); };
297
- var migration = function (migrations_home, host, username, password, db_name, db_engine, timeout) { return __awaiter(void 0, void 0, void 0, function () {
330
+ var migration = function (migrations_home, host, username, password, db_name, db_engine, timeout, ca_cert, cert, key) { return __awaiter(void 0, void 0, void 0, function () {
298
331
  var migrations, client;
299
332
  return __generator(this, function (_a) {
300
333
  switch (_a.label) {
301
334
  case 0:
302
335
  migrations = get_migrations(migrations_home);
303
- return [4 /*yield*/, create_db(host, username, password, db_name, db_engine)];
336
+ return [4 /*yield*/, create_db(host, username, password, db_name, db_engine, timeout, ca_cert, cert, key)];
304
337
  case 1:
305
338
  _a.sent();
306
- client = connect(host, username, password, db_name, timeout);
339
+ client = connect(host, username, password, db_name, timeout, ca_cert, cert, key);
307
340
  return [4 /*yield*/, init_migration_table(client)];
308
341
  case 2:
309
342
  _a.sent();
@@ -320,7 +353,7 @@ var migration = function (migrations_home, host, username, password, db_name, db
320
353
  exports.migration = migration;
321
354
  var migrate = function () {
322
355
  var program = new commander_1.Command();
323
- program.name('clickhouse-migrations').description('ClickHouse migrations.').version('1.0.5');
356
+ program.name('clickhouse-migrations').description('ClickHouse migrations.').version('1.1.0');
324
357
  program
325
358
  .command('migrate')
326
359
  .description('Apply migrations.')
@@ -331,10 +364,13 @@ var migrate = function () {
331
364
  .requiredOption('--migrations-home <dir>', "Migrations' directory", process.env.CH_MIGRATIONS_HOME)
332
365
  .option('--db-engine <value>', 'ON CLUSTER and/or ENGINE clauses for database (default: "ENGINE=Atomic")', process.env.CH_MIGRATIONS_DB_ENGINE)
333
366
  .option('--timeout <value>', 'Client request timeout (milliseconds, default value 30000)', process.env.CH_MIGRATIONS_TIMEOUT)
367
+ .option('--ca-cert <path>', 'CA certificate file path', process.env.CH_MIGRATIONS_CA_CERT)
368
+ .option('--cert <path>', 'Client certificate file path', process.env.CH_MIGRATIONS_CERT)
369
+ .option('--key <path>', 'Client key file path', process.env.CH_MIGRATIONS_KEY)
334
370
  .action(function (options) { return __awaiter(void 0, void 0, void 0, function () {
335
371
  return __generator(this, function (_a) {
336
372
  switch (_a.label) {
337
- case 0: return [4 /*yield*/, migration(options.migrationsHome, options.host, options.user, options.password, options.db, options.dbEngine, options.timeout)];
373
+ case 0: return [4 /*yield*/, migration(options.migrationsHome, options.host, options.user, options.password, options.db, options.dbEngine, options.timeout, options.caCert, options.cert, options.key)];
338
374
  case 1:
339
375
  _a.sent();
340
376
  return [2 /*return*/];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clickhouse-migrations",
3
- "version": "1.0.5",
3
+ "version": "1.1.0",
4
4
  "description": "ClickHouse Migrations",
5
5
  "bin": {
6
6
  "clickhouse-migrations": "lib/cli.js"
@@ -17,6 +17,8 @@
17
17
  "scripts": {
18
18
  "build": "rm lib/*; tsc",
19
19
  "test": "jest --config jestconfig.json",
20
+ "test:unit": "jest --config jestconfig.json --testPathPatterns=\"\\.(unit|integration)\\.test\\.ts$\"",
21
+ "test:e2e": "jest --config jestconfig.json --testPathPatterns=\"\\.e2e\\.test\\.ts$\"",
20
22
  "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
21
23
  "lint": "eslint ./src",
22
24
  "prepare": "npm run build",