@cocreate/cli 1.45.3 → 1.46.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/CHANGELOG.md +15 -0
- package/package.json +3 -1
- package/src/commands/acme.js +25 -0
- package/src/commands/nginx.js +3 -3
- package/src/commands/other/nginxConfigManager.js +21 -0
- package/src/commands/other/certBotWildcard.js +0 -69
- package/src/commands/other/haproxy.js +0 -76
- package/src/commands/other/haproxyConfigManager.js +0 -63
- package/src/commands/other/nginx.js +0 -76
- package/src/commands/other/nodeCertManager.js +0 -182
- package/src/loaders/replace-unicode.js +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# [1.46.0](https://github.com/CoCreate-app/CoCreate-cli/compare/v1.45.3...v1.46.0) (2023-12-31)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* relocated to '@cocreate/webpack' ([05941f1](https://github.com/CoCreate-app/CoCreate-cli/commit/05941f1370f5b91f2968d90e12cd1780b9e2b31f))
|
|
7
|
+
* relocated to thier relative modules ([3635e50](https://github.com/CoCreate-app/CoCreate-cli/commit/3635e50076ee2763aed28194c2b4d099591f82ce))
|
|
8
|
+
* require '@cocreate/nginx' ([acab9d3](https://github.com/CoCreate-app/CoCreate-cli/commit/acab9d3da10de5193dd573ad7198b7356ed35283))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add '@cocreate/acme' and '@cocreate/nginx' ([0eb81e8](https://github.com/CoCreate-app/CoCreate-cli/commit/0eb81e88a54931bc2fc78663393b15338a62740f))
|
|
14
|
+
* coc acme to manage certs ([13049fa](https://github.com/CoCreate-app/CoCreate-cli/commit/13049fa7316269d1fc64b0f9c378b10937c0e7b7))
|
|
15
|
+
|
|
1
16
|
## [1.45.3](https://github.com/CoCreate-app/CoCreate-cli/compare/v1.45.2...v1.45.3) (2023-12-18)
|
|
2
17
|
|
|
3
18
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.46.0",
|
|
4
4
|
"description": "Polyrepo management bash CLI tool. Run all git commands and yarn commands on multiple repositories. Also includes a few custom macros for cloning, installing, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -55,8 +55,10 @@
|
|
|
55
55
|
"coc": "src/coc.js"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
+
"@cocreate/acme": "^1.0.0",
|
|
58
59
|
"@cocreate/config": "^1.8.0",
|
|
59
60
|
"@cocreate/file": "^1.13.0",
|
|
61
|
+
"@cocreate/nginx": "^1.0.0",
|
|
60
62
|
"glob": "^7.1.7",
|
|
61
63
|
"prettier": "^2.3.2"
|
|
62
64
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const { requestCertificate } = require('@cocreate/acme')
|
|
2
|
+
|
|
3
|
+
module.exports = async function nginx(repos, args) {
|
|
4
|
+
let failed = [];
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
if (args.length) {
|
|
8
|
+
if (args[0] === 'create') {
|
|
9
|
+
args.shift()
|
|
10
|
+
await createServer(args);
|
|
11
|
+
} else if (args[0] === 'delete') {
|
|
12
|
+
args.shift()
|
|
13
|
+
await deleteServer(args);
|
|
14
|
+
} else
|
|
15
|
+
await createServer(args);
|
|
16
|
+
}
|
|
17
|
+
} catch (err) {
|
|
18
|
+
failed.push({ name: 'GENERAL', des: err.message });
|
|
19
|
+
console.error(err.red);
|
|
20
|
+
} finally {
|
|
21
|
+
return failed;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
package/src/commands/nginx.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {createServer, deleteServer} = require('
|
|
1
|
+
const { createServer, deleteServer } = require('@cocreate/nginx')
|
|
2
2
|
|
|
3
3
|
module.exports = async function nginx(repos, args) {
|
|
4
4
|
let failed = [];
|
|
@@ -11,13 +11,13 @@ module.exports = async function nginx(repos, args) {
|
|
|
11
11
|
} else if (args[0] === 'delete') {
|
|
12
12
|
args.shift()
|
|
13
13
|
await deleteServer(args);
|
|
14
|
-
|
|
14
|
+
} else
|
|
15
15
|
await createServer(args);
|
|
16
16
|
}
|
|
17
17
|
} catch (err) {
|
|
18
18
|
failed.push({ name: 'GENERAL', des: err.message });
|
|
19
19
|
console.error(err.red);
|
|
20
|
-
} finally
|
|
20
|
+
} finally {
|
|
21
21
|
return failed;
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -107,4 +107,25 @@ async function deleteServer(hosts) {
|
|
|
107
107
|
return response
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
async function hasServer(hosts) {
|
|
111
|
+
if (!Array.isArray(hosts))
|
|
112
|
+
hosts = [hosts]
|
|
113
|
+
for (let host of hosts) {
|
|
114
|
+
const { stdout, stderr } = await exec(`grep -Ri 'server_name.*${host}' /etc/nginx/sites-enabled`)
|
|
115
|
+
if (err) {
|
|
116
|
+
console.error(`exec error: ${err}`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (stdout) {
|
|
120
|
+
console.log(`Host found in the following configuration file(s):\n${stdout}`);
|
|
121
|
+
|
|
122
|
+
} else {
|
|
123
|
+
console.log('Host not found in Nginx configurations.');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (stderr) console.error(`stderr: ${stderr}`);
|
|
127
|
+
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
110
131
|
module.exports = { createServer, deleteServer }
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const { spawn } = require('child_process');
|
|
4
|
-
|
|
5
|
-
function runCertbot() {
|
|
6
|
-
return new Promise((resolve, reject) => {
|
|
7
|
-
const certbotProcess = spawn('sudo', [
|
|
8
|
-
'certbot',
|
|
9
|
-
'certonly',
|
|
10
|
-
'--manual',
|
|
11
|
-
'-d', '*.cocreate.zone',
|
|
12
|
-
'-d', 'cocreate.zone',
|
|
13
|
-
'--agree-tos',
|
|
14
|
-
'-m', 'admin@cocreate.zone',
|
|
15
|
-
'--preferred-challenges', 'dns-01',
|
|
16
|
-
'--server', 'https://acme-v02.api.letsencrypt.org/directory'
|
|
17
|
-
]);
|
|
18
|
-
|
|
19
|
-
// let promptsCount = 0;
|
|
20
|
-
|
|
21
|
-
certbotProcess.stdout.on('data', (data) => {
|
|
22
|
-
const output = data.toString();
|
|
23
|
-
if (output.includes('Please deploy a DNS TXT record under the name:')) {
|
|
24
|
-
const namePattern = /Please deploy a DNS TXT record under the name:\s+([\w\.-]+)\./;
|
|
25
|
-
const valuePattern = /with the following value:\s+([\w\d]+)\s+/;
|
|
26
|
-
|
|
27
|
-
const nameMatch = output.match(namePattern);
|
|
28
|
-
const valueMatch = output.match(valuePattern);
|
|
29
|
-
|
|
30
|
-
if (nameMatch && valueMatch) {
|
|
31
|
-
const name = nameMatch[1];
|
|
32
|
-
const value = valueMatch[1];
|
|
33
|
-
|
|
34
|
-
console.log("Name:", name);
|
|
35
|
-
console.log("Value:", value);
|
|
36
|
-
} else {
|
|
37
|
-
console.log("Name or value not found in the text.");
|
|
38
|
-
}
|
|
39
|
-
// TODO: send name and value to client and wait for clients response before continuing
|
|
40
|
-
certbotProcess.stdin.write('\n');
|
|
41
|
-
} else if (output.includes('Press Enter to Continue')) {
|
|
42
|
-
certbotProcess.stdin.write('\n');
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
certbotProcess.stderr.on('data', (data) => {
|
|
47
|
-
reject(data.toString());
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
certbotProcess.on('close', (code) => {
|
|
51
|
-
if (code === 0) {
|
|
52
|
-
resolve('Certbot process completed successfully.');
|
|
53
|
-
} else {
|
|
54
|
-
reject(`Certbot process exited with code ${code}`);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async function executeCertbot() {
|
|
61
|
-
try {
|
|
62
|
-
const result = await runCertbot();
|
|
63
|
-
console.log(result);
|
|
64
|
-
} catch (error) {
|
|
65
|
-
console.error('An error occurred:', error);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
executeCertbot();
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const { exec } = require('child_process');
|
|
3
|
-
|
|
4
|
-
const haproxyConfigPath = '/etc/haproxy/haproxy.cfg';
|
|
5
|
-
const backendSectionName = 'backend app_backend';
|
|
6
|
-
|
|
7
|
-
// Function to update HAProxy config with new servers
|
|
8
|
-
const updateHAProxyConfig = (newServers) => {
|
|
9
|
-
fs.readFile(haproxyConfigPath, 'utf8', (err, data) => {
|
|
10
|
-
if (err) {
|
|
11
|
-
console.error('Error reading HAProxy config:', err);
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const updatedConfig = updateBackendServers(data, newServers);
|
|
16
|
-
fs.writeFile(haproxyConfigPath, updatedConfig, 'utf8', (err) => {
|
|
17
|
-
if (err) {
|
|
18
|
-
console.error('Error writing updated HAProxy config:', err);
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
reloadHAProxy();
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// Function to replace backend server entries in the config
|
|
28
|
-
const updateBackendServers = (configData, newServers) => {
|
|
29
|
-
const lines = configData.split('\n');
|
|
30
|
-
let backendSectionStart = -1;
|
|
31
|
-
let backendSectionEnd = -1;
|
|
32
|
-
|
|
33
|
-
// Find the start and end of the backend section
|
|
34
|
-
lines.forEach((line, index) => {
|
|
35
|
-
if (line.trim() === backendSectionName) {
|
|
36
|
-
backendSectionStart = index;
|
|
37
|
-
}
|
|
38
|
-
if (backendSectionStart !== -1 && backendSectionEnd === -1 && line.trim() === '') {
|
|
39
|
-
backendSectionEnd = index;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
if (backendSectionStart === -1 || backendSectionEnd === -1) {
|
|
44
|
-
console.error('Backend section not found in HAProxy config');
|
|
45
|
-
return configData;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Replace the server list in the backend section
|
|
49
|
-
const newServerLines = newServers.map(server => ` server ${server.name} ${server.address} check`);
|
|
50
|
-
const updatedLines = [
|
|
51
|
-
...lines.slice(0, backendSectionStart + 1),
|
|
52
|
-
...newServerLines,
|
|
53
|
-
...lines.slice(backendSectionEnd)
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
return updatedLines.join('\n');
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// Function to reload HAProxy
|
|
60
|
-
const reloadHAProxy = () => {
|
|
61
|
-
exec('systemctl reload haproxy', (err, stdout, stderr) => {
|
|
62
|
-
if (err) {
|
|
63
|
-
console.error('Error reloading HAProxy:', err);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
console.log('HAProxy reloaded successfully');
|
|
67
|
-
});
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// Example usage
|
|
71
|
-
const newServers = [
|
|
72
|
-
{ name: 'app1', address: '10.0.0.1:80' },
|
|
73
|
-
{ name: 'app2', address: '10.0.0.2:80' }
|
|
74
|
-
];
|
|
75
|
-
|
|
76
|
-
updateHAProxyConfig(newServers);
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const { exec } = require('child_process');
|
|
3
|
-
|
|
4
|
-
const haproxyConfigPath = '/etc/haproxy/haproxy.cfg';
|
|
5
|
-
|
|
6
|
-
// Function to add a new configuration to HAProxy and restart it
|
|
7
|
-
const addHAProxyConfig = (frontendName, backendName, backendServers) => {
|
|
8
|
-
fs.readFile(haproxyConfigPath, 'utf8', (err, data) => {
|
|
9
|
-
if (err) {
|
|
10
|
-
console.error('Error reading HAProxy config:', err);
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Append new frontend and backend configuration
|
|
15
|
-
const newConfig = `
|
|
16
|
-
# Frontend Configuration
|
|
17
|
-
frontend ${frontendName}
|
|
18
|
-
bind *:80
|
|
19
|
-
mode http
|
|
20
|
-
default_backend ${backendName}
|
|
21
|
-
|
|
22
|
-
# Backend Configuration
|
|
23
|
-
backend ${backendName}
|
|
24
|
-
mode http
|
|
25
|
-
balance roundrobin`;
|
|
26
|
-
|
|
27
|
-
// Add server entries
|
|
28
|
-
backendServers.forEach((server, index) => {
|
|
29
|
-
newConfig += `\n server server${index} ${server.address} check`;
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// Write updated configuration
|
|
33
|
-
fs.writeFile(haproxyConfigPath, data + newConfig, 'utf8', (err) => {
|
|
34
|
-
if (err) {
|
|
35
|
-
console.error('Error writing updated HAProxy config:', err);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
restartHAProxy();
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
// Function to restart HAProxy
|
|
45
|
-
const restartHAProxy = () => {
|
|
46
|
-
exec('systemctl restart haproxy', (err, stdout, stderr) => {
|
|
47
|
-
if (err) {
|
|
48
|
-
console.error('Error restarting HAProxy:', err);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
console.log('HAProxy restarted successfully');
|
|
52
|
-
});
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// Example usage
|
|
56
|
-
const frontendName = 'my_frontend';
|
|
57
|
-
const backendName = 'my_backend';
|
|
58
|
-
const backendServers = [
|
|
59
|
-
{ address: '10.0.0.1:80' },
|
|
60
|
-
{ address: '10.0.0.2:80' }
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
addHAProxyConfig(frontendName, backendName, backendServers);
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const { exec } = require('child_process');
|
|
3
|
-
|
|
4
|
-
const nginxConfigPath = '/etc/nginx/conf.d/myapp.conf';
|
|
5
|
-
const upstreamBlockName = 'upstream app_backend';
|
|
6
|
-
|
|
7
|
-
// Function to update NGINX config with new servers
|
|
8
|
-
const updateNginxConfig = (newServers) => {
|
|
9
|
-
fs.readFile(nginxConfigPath, 'utf8', (err, data) => {
|
|
10
|
-
if (err) {
|
|
11
|
-
console.error('Error reading NGINX config:', err);
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const updatedConfig = updateUpstreamServers(data, newServers);
|
|
16
|
-
fs.writeFile(nginxConfigPath, updatedConfig, 'utf8', (err) => {
|
|
17
|
-
if (err) {
|
|
18
|
-
console.error('Error writing updated NGINX config:', err);
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
reloadNginx();
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// Function to replace upstream server entries in the config
|
|
28
|
-
const updateUpstreamServers = (configData, newServers) => {
|
|
29
|
-
const lines = configData.split('\n');
|
|
30
|
-
let upstreamSectionStart = -1;
|
|
31
|
-
let upstreamSectionEnd = -1;
|
|
32
|
-
|
|
33
|
-
// Find the start and end of the upstream section
|
|
34
|
-
lines.forEach((line, index) => {
|
|
35
|
-
if (line.trim().startsWith(upstreamBlockName)) {
|
|
36
|
-
upstreamSectionStart = index;
|
|
37
|
-
}
|
|
38
|
-
if (upstreamSectionStart !== -1 && upstreamSectionEnd === -1 && line.trim() === '}') {
|
|
39
|
-
upstreamSectionEnd = index;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
if (upstreamSectionStart === -1 || upstreamSectionEnd === -1) {
|
|
44
|
-
console.error('Upstream section not found in NGINX config');
|
|
45
|
-
return configData;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Replace the server list in the upstream section
|
|
49
|
-
const newServerLines = newServers.map(server => ` server ${server.address};`);
|
|
50
|
-
const updatedLines = [
|
|
51
|
-
...lines.slice(0, upstreamSectionStart + 1),
|
|
52
|
-
...newServerLines,
|
|
53
|
-
...lines.slice(upstreamSectionEnd)
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
return updatedLines.join('\n');
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// Function to reload NGINX
|
|
60
|
-
const reloadNginx = () => {
|
|
61
|
-
exec('systemctl reload nginx', (err, stdout, stderr) => {
|
|
62
|
-
if (err) {
|
|
63
|
-
console.error('Error reloading NGINX:', err);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
console.log('NGINX reloaded successfully');
|
|
67
|
-
});
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// Example usage
|
|
71
|
-
const newServers = [
|
|
72
|
-
{ address: '10.0.0.1:80' },
|
|
73
|
-
{ address: '10.0.0.2:80' }
|
|
74
|
-
];
|
|
75
|
-
|
|
76
|
-
updateNginxConfig(newServers);
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
const util = require('node:util');
|
|
2
|
-
const exec = require('node:child_process').exec;
|
|
3
|
-
const dns = require('dns');
|
|
4
|
-
const child_process = require('child_process');
|
|
5
|
-
const spawn = child_process.spawn;
|
|
6
|
-
|
|
7
|
-
const localip = '3.231.17.247'
|
|
8
|
-
const certificates = new Map()
|
|
9
|
-
const certbotPath = `/etc/letsencrypt/live/`;
|
|
10
|
-
const fullchainPath = `${certbotPath}/fullchain.pem`;
|
|
11
|
-
const privkeyPath = `${certbotPath}/privkey.pem`;
|
|
12
|
-
const combinedPath = `${certbotPath}/haproxy.pem`;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
async function checkDns(host) {
|
|
16
|
-
return new Promise((resolve, reject) => {
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
dns.resolve(host, 'A', (err, records) => {
|
|
20
|
-
if (records && records[0] === localip) {
|
|
21
|
-
resolve(true)
|
|
22
|
-
} else {
|
|
23
|
-
console.log('host A record need to point to', localip)
|
|
24
|
-
resolve(false)
|
|
25
|
-
}
|
|
26
|
-
if (err)
|
|
27
|
-
console.log(host, err);
|
|
28
|
-
});
|
|
29
|
-
} catch (err) {
|
|
30
|
-
console.log('certificate', err)
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async function createCert(host) {
|
|
36
|
-
try {
|
|
37
|
-
// let hosts = await exec(`sudo openssl x509 -dates -noout -in /etc/letsencrypt/live/${host}/fullchain.pem`);
|
|
38
|
-
// console.log('hostst check', hosts)
|
|
39
|
-
let test = await checkDns(host)
|
|
40
|
-
console.log('checked dns from createCert', test)
|
|
41
|
-
if (test) {
|
|
42
|
-
await exec(`sudo certbot certonly -d ${host}`);
|
|
43
|
-
// let exitCode = await spawn('sudo', ['certbot', 'certonly', '--manual', '-d', `*.${host}`, '-d', host, '--agree-tos', '--preferred-challenges', 'dns-01', '--server', 'https://acme-v02.api.letsencrypt.org/directory'], { stdio: 'inherit', cwd: process.cwd() })
|
|
44
|
-
if (exitCode !== 0) {
|
|
45
|
-
failed.push({ name: false, des: `creating directory failed` })
|
|
46
|
-
} else
|
|
47
|
-
console.log(true)
|
|
48
|
-
|
|
49
|
-
// return true
|
|
50
|
-
} else
|
|
51
|
-
return false
|
|
52
|
-
} catch (err) {
|
|
53
|
-
return false
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async function deleteCert(host) {
|
|
58
|
-
try {
|
|
59
|
-
await exec(`sudo certbot delete --cert-name ${host}`);
|
|
60
|
-
return true
|
|
61
|
-
} catch (err) {
|
|
62
|
-
return false
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async function checkCert(host) {
|
|
67
|
-
try {
|
|
68
|
-
let hosts = await exec(`host ${host}`);
|
|
69
|
-
console.log('hostst check', hosts)
|
|
70
|
-
|
|
71
|
-
if (certificates.has(host))
|
|
72
|
-
return true
|
|
73
|
-
else {
|
|
74
|
-
let certs = await exec(`sudo openssl x509 -dates -noout -in /etc/letsencrypt/live/${host}/fullchain.pem`);
|
|
75
|
-
let cert = certs.stdout.split('\n')
|
|
76
|
-
let issued = Date.parse(cert[0].replace('notBefore=', ''))
|
|
77
|
-
let expires = Date.parse(cert[1].replace('notAfter=', ''))
|
|
78
|
-
let currentDate = new Date()
|
|
79
|
-
|
|
80
|
-
if (!issued || !expires)
|
|
81
|
-
console.log('not defined', { issued, expires })
|
|
82
|
-
else if (!isNaN(expires)) {
|
|
83
|
-
if (currentDate < expires) {
|
|
84
|
-
certificates.set(host, { issued, expires })
|
|
85
|
-
return true
|
|
86
|
-
} else {
|
|
87
|
-
let cert = await createCert(host)
|
|
88
|
-
return cert
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
let cert = await createCert(host)
|
|
92
|
-
return cert
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
} catch (err) {
|
|
96
|
-
let cert = await createCert(host)
|
|
97
|
-
if (cert)
|
|
98
|
-
certificates.set(host, { issued, expires })
|
|
99
|
-
return cert
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const combineCertificate = (host) => {
|
|
104
|
-
const certbotPath = `/etc/letsencrypt/live/${host}`;
|
|
105
|
-
const fullchainPath = `${certbotPath}/fullchain.pem`;
|
|
106
|
-
const privkeyPath = `${certbotPath}/privkey.pem`;
|
|
107
|
-
const combinedPath = `${certbotPath}/haproxy.pem`;
|
|
108
|
-
|
|
109
|
-
fs.readFile(fullchainPath, (err, fullchainData) => {
|
|
110
|
-
if (err) {
|
|
111
|
-
console.error('Error reading fullchain.pem:', err);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
fs.readFile(privkeyPath, (err, privkeyData) => {
|
|
116
|
-
if (err) {
|
|
117
|
-
console.error('Error reading privkey.pem:', err);
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const combinedData = `${fullchainData}\n${privkeyData}`;
|
|
122
|
-
fs.writeFile(combinedPath, combinedData, (err) => {
|
|
123
|
-
if (err) {
|
|
124
|
-
console.error('Error writing combined haproxy.pem:', err);
|
|
125
|
-
} else {
|
|
126
|
-
console.log('Successfully combined certificates for HAProxy.');
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
async function test(host) {
|
|
134
|
-
try {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
await exec(`sudo certbot certonly --manual --test-cert -d *.${host} -d ${host} --agree-tos --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory`);
|
|
138
|
-
let exitCode = await spawn('sudo', ['certbot', 'certonly', '--manual', '--test-cert', '-d', `*.${host}`, '-d', host, '--agree-tos', '--preferred-challenges', 'dns-01', '--server', 'https://acme-v02.api.letsencrypt.org/directory'], { stdio: 'inherit', cwd: process.cwd() })
|
|
139
|
-
if (exitCode !== 0) {
|
|
140
|
-
failed.push({ name: false, des: `creating directory failed` })
|
|
141
|
-
} else
|
|
142
|
-
console.log(true)
|
|
143
|
-
|
|
144
|
-
// let child = exec('su -')
|
|
145
|
-
// child.stdin.write("testserver\n");
|
|
146
|
-
|
|
147
|
-
// child.stdout.on('data', (data) => {
|
|
148
|
-
// console.log(`stdout: "${data}"`);
|
|
149
|
-
// });
|
|
150
|
-
|
|
151
|
-
// child.stdin.end(); // EOF
|
|
152
|
-
|
|
153
|
-
// child.on('close', (code) => {
|
|
154
|
-
// console.log(`Child process exited with code ${code}.`);
|
|
155
|
-
// });
|
|
156
|
-
|
|
157
|
-
// exitCode.on("data", data => {
|
|
158
|
-
// console.log('test')
|
|
159
|
-
// })
|
|
160
|
-
// let test = exitCode
|
|
161
|
-
// if (exitCode !== 0) {
|
|
162
|
-
// exitCode.write('test', (err) => {
|
|
163
|
-
// if (err) throw Error(err.message)
|
|
164
|
-
// })
|
|
165
|
-
// } else {
|
|
166
|
-
// exitCode.write('test', (err) => {
|
|
167
|
-
// if (err) throw Error(err.message)
|
|
168
|
-
// })
|
|
169
|
-
// }
|
|
170
|
-
|
|
171
|
-
// return true
|
|
172
|
-
// return false
|
|
173
|
-
} catch (err) {
|
|
174
|
-
process.exit(1)
|
|
175
|
-
// return false
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
// test('cocreate.app')
|
|
181
|
-
|
|
182
|
-
module.exports = { checkDns, checkCert, createCert, deleteCert }
|