@sysnee/pgs 0.1.5 → 0.1.7-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/manager.js +53 -16
- 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() {
|
|
@@ -109,9 +118,9 @@ function updateHAProxyDependsOn() {
|
|
|
109
118
|
container_name: 'postgres_proxy',
|
|
110
119
|
ports: ['5432:5432'],
|
|
111
120
|
volumes: [
|
|
112
|
-
|
|
121
|
+
`${HAPROXY_CFG_PATH}:/usr/local/etc/haproxy/haproxy.cfg:ro`,
|
|
113
122
|
'./haproxy-lua:/etc/haproxy/lua:ro',
|
|
114
|
-
|
|
123
|
+
`${TENANT_ACCESS_FILE_PATH}:/etc/haproxy/tenant-access.json:ro`
|
|
115
124
|
],
|
|
116
125
|
networks: ['postgres_network'],
|
|
117
126
|
restart: 'unless-stopped'
|
|
@@ -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,39 @@ 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 (!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 (!existsSync(TENANT_ACCESS_FILE_PATH)) {
|
|
227
|
+
writeFileSync(TENANT_ACCESS_FILE_PATH, '{}');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// haproxy.cfg
|
|
231
|
+
if (!existsSync(HAPROXY_CFG_PATH)) {
|
|
232
|
+
const haproxyTemplate = readFileSync(path.join(__dirname, 'haproxy.cfg'), 'utf8');
|
|
233
|
+
writeFileSync(HAPROXY_CFG_PATH, haproxyTemplate);
|
|
234
|
+
}
|
|
198
235
|
}
|
|
199
236
|
|
|
200
237
|
function checkSetupStatus() {
|
|
@@ -382,13 +419,13 @@ const program = new Command();
|
|
|
382
419
|
program
|
|
383
420
|
.name('postgres-manager')
|
|
384
421
|
.description('Manage PostgreSQL tenant instances')
|
|
385
|
-
.version(
|
|
422
|
+
.version(packageJson.version);
|
|
386
423
|
|
|
387
424
|
program
|
|
388
425
|
.command('setup')
|
|
389
426
|
.description('Initial required setup')
|
|
390
427
|
.action(() => {
|
|
391
|
-
|
|
428
|
+
initialSetup()
|
|
392
429
|
})
|
|
393
430
|
|
|
394
431
|
program
|