@sysnee/pgs 0.1.5 → 0.1.6
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/manager.js +45 -14
- package/package.json +1 -1
package/manager.js
CHANGED
|
@@ -6,6 +6,14 @@ import yaml from 'js-yaml';
|
|
|
6
6
|
import os from 'os';
|
|
7
7
|
import { Command } from 'commander';
|
|
8
8
|
import { execSync } from 'child_process';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { dirname } from 'path';
|
|
11
|
+
|
|
12
|
+
import packageJson from './package.json' with { type: 'json' };
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
+
const __dirname = dirname(__filename);
|
|
9
17
|
|
|
10
18
|
const CONFIG_DIR = path.join(os.homedir(), '.sysnee-config');
|
|
11
19
|
|
|
@@ -16,11 +24,8 @@ const TENANT_ACCESS_FILE_PATH = path.join(CONFIG_DIR, 'tenant-access.json');
|
|
|
16
24
|
const SETUP_STATUS_PATH = path.join(CONFIG_DIR, 'status.txt');
|
|
17
25
|
|
|
18
26
|
function loadCompose() {
|
|
19
|
-
if (!fs.existsSync(COMPOSE_FILE_PATH)) {
|
|
20
|
-
const dockerComposeInitialContent = readFileSync(path.join(path.dirname(''), 'docker-compose.yml'), 'utf8')
|
|
21
|
-
writeFileSync(COMPOSE_FILE_PATH, dockerComposeInitialContent)
|
|
22
|
-
}
|
|
23
27
|
const content = fs.readFileSync(COMPOSE_FILE_PATH, 'utf8');
|
|
28
|
+
console.debug(`docker-compose file readed from ${COMPOSE_FILE_PATH}`)
|
|
24
29
|
return yaml.load(content);
|
|
25
30
|
}
|
|
26
31
|
|
|
@@ -32,9 +37,6 @@ function saveCompose(doc) {
|
|
|
32
37
|
// ==================== Tenant Access Management ====================
|
|
33
38
|
|
|
34
39
|
function loadTenantAccess() {
|
|
35
|
-
if (!fs.existsSync(TENANT_ACCESS_FILE_PATH)) {
|
|
36
|
-
fs.writeFileSync(TENANT_ACCESS_FILE_PATH, '{}');
|
|
37
|
-
}
|
|
38
40
|
const content = fs.readFileSync(TENANT_ACCESS_FILE_PATH, 'utf8');
|
|
39
41
|
return JSON.parse(content) || {};
|
|
40
42
|
}
|
|
@@ -59,15 +61,20 @@ function removeTenantAccess(tenantId) {
|
|
|
59
61
|
// ==================== HAProxy Configuration ====================
|
|
60
62
|
|
|
61
63
|
function generateHAProxyConfig() {
|
|
64
|
+
console.debug('In generateHAProxy function')
|
|
62
65
|
const doc = loadCompose();
|
|
63
66
|
|
|
64
67
|
// Get all tenant services
|
|
65
68
|
const tenants = Object.keys(doc.services || {})
|
|
66
69
|
.filter(name => name.startsWith('pgs_') && name !== 'haproxy');
|
|
67
70
|
|
|
71
|
+
console.debug(`tenants.lenght: ${tenants.length}`)
|
|
72
|
+
|
|
68
73
|
// Get initial HAProxy config
|
|
69
|
-
const templateFilePath = path.join(
|
|
74
|
+
const templateFilePath = path.join(__dirname, 'haproxy.cfg')
|
|
75
|
+
console.debug(`haproxy template file path: ${templateFilePath}`)
|
|
70
76
|
let config = readFileSync(templateFilePath, 'utf8');
|
|
77
|
+
console.debug(`haproxy template file loaded`)
|
|
71
78
|
|
|
72
79
|
// Add all tenant backends to SSL pool for SSL negotiation
|
|
73
80
|
// PostgreSQL will respond 'N' (no SSL) during negotiation, then client retries without SSL
|
|
@@ -92,7 +99,9 @@ function generateHAProxyConfig() {
|
|
|
92
99
|
`;
|
|
93
100
|
}
|
|
94
101
|
|
|
95
|
-
|
|
102
|
+
console.log(`Preparing to save haproxy file in ${HAPROXY_CFG_PATH}`)
|
|
103
|
+
writeFileSync(HAPROXY_CFG_PATH, config);
|
|
104
|
+
console.log(`Succesfully saved haproxy file in ${HAPROXY_CFG_PATH}`)
|
|
96
105
|
}
|
|
97
106
|
|
|
98
107
|
function updateHAProxyDependsOn() {
|
|
@@ -143,6 +152,8 @@ function createInitScript({ tenantId, password, databaseName }) {
|
|
|
143
152
|
`;
|
|
144
153
|
|
|
145
154
|
fs.writeFileSync(initFile, sql);
|
|
155
|
+
|
|
156
|
+
console.debug('Init script created!')
|
|
146
157
|
return initFile;
|
|
147
158
|
}
|
|
148
159
|
|
|
@@ -188,13 +199,33 @@ function ensureNetwork(doc) {
|
|
|
188
199
|
}
|
|
189
200
|
}
|
|
190
201
|
|
|
202
|
+
function initialSetup() {
|
|
203
|
+
createInitialFiles()
|
|
204
|
+
ensureDockerPrivilegies()
|
|
205
|
+
console.log('All ready!')
|
|
206
|
+
}
|
|
207
|
+
|
|
191
208
|
function ensureDockerPrivilegies() {
|
|
209
|
+
execSync('sudo usermod -aG docker $USER && newgrp docker')
|
|
210
|
+
writeFileSync(SETUP_STATUS_PATH, 'container:ok')
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function createInitialFiles() {
|
|
214
|
+
// config dir
|
|
192
215
|
if (!existsSync(CONFIG_DIR)) {
|
|
193
216
|
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
194
217
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
218
|
+
|
|
219
|
+
// docker-compose.yml
|
|
220
|
+
if (!fs.existsSync(COMPOSE_FILE_PATH)) {
|
|
221
|
+
const dockerComposeInitialContent = readFileSync(path.join(__dirname, 'docker-compose.yml'), 'utf8')
|
|
222
|
+
writeFileSync(COMPOSE_FILE_PATH, dockerComposeInitialContent)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// tenant-access.json
|
|
226
|
+
if (!fs.existsSync(TENANT_ACCESS_FILE_PATH)) {
|
|
227
|
+
fs.writeFileSync(TENANT_ACCESS_FILE_PATH, '{}');
|
|
228
|
+
}
|
|
198
229
|
}
|
|
199
230
|
|
|
200
231
|
function checkSetupStatus() {
|
|
@@ -382,13 +413,13 @@ const program = new Command();
|
|
|
382
413
|
program
|
|
383
414
|
.name('postgres-manager')
|
|
384
415
|
.description('Manage PostgreSQL tenant instances')
|
|
385
|
-
.version(
|
|
416
|
+
.version(packageJson.version);
|
|
386
417
|
|
|
387
418
|
program
|
|
388
419
|
.command('setup')
|
|
389
420
|
.description('Initial required setup')
|
|
390
421
|
.action(() => {
|
|
391
|
-
|
|
422
|
+
initialSetup()
|
|
392
423
|
})
|
|
393
424
|
|
|
394
425
|
program
|