underpost 2.8.65 → 2.8.67
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/.vscode/extensions.json +3 -2
- package/.vscode/settings.json +2 -0
- package/CHANGELOG.md +24 -4
- package/README.md +39 -2
- package/bin/deploy.js +1180 -144
- package/bin/file.js +8 -0
- package/bin/index.js +1 -240
- package/cli.md +451 -0
- package/docker-compose.yml +1 -1
- package/jsdoc.json +1 -1
- package/manifests/calico-custom-resources.yaml +25 -0
- package/manifests/deployment/adminer/deployment.yaml +32 -0
- package/manifests/deployment/adminer/kustomization.yaml +7 -0
- package/manifests/deployment/adminer/service.yaml +13 -0
- package/manifests/mongodb-4.4/service-deployment.yaml +1 -1
- package/manifests/postgresql/configmap.yaml +9 -0
- package/manifests/postgresql/kustomization.yaml +10 -0
- package/manifests/postgresql/pv.yaml +15 -0
- package/manifests/postgresql/pvc.yaml +13 -0
- package/manifests/postgresql/service.yaml +10 -0
- package/manifests/postgresql/statefulset.yaml +37 -0
- package/manifests/valkey/statefulset.yaml +6 -4
- package/package.json +2 -1
- package/src/cli/cluster.js +69 -10
- package/src/cli/deploy.js +55 -8
- package/src/cli/fs.js +14 -3
- package/src/cli/index.js +312 -0
- package/src/cli/monitor.js +93 -39
- package/src/client/components/core/JoyStick.js +2 -2
- package/src/client/components/core/Modal.js +1 -0
- package/src/index.js +1 -1
- package/src/server/client-build.js +13 -0
- package/src/server/conf.js +5 -1
- package/src/server/dns.js +47 -17
- package/src/server/runtime.js +2 -0
- package/src/server/start.js +0 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"type": "module",
|
|
3
3
|
"main": "src/index.js",
|
|
4
4
|
"name": "underpost",
|
|
5
|
-
"version": "2.8.
|
|
5
|
+
"version": "2.8.67",
|
|
6
6
|
"description": "pwa api rest template",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"dev": "env-cmd -f .env.development node src/client.dev default",
|
|
12
12
|
"dev-img": "env-cmd -f .env.development node src/server",
|
|
13
13
|
"prod-img": "env-cmd -f .env.production node src/server",
|
|
14
|
+
"monitor": "pm2 start bin/deploy.js --name monitor -- monitor",
|
|
14
15
|
"dev-api": "env-cmd -f .env.development nodemon --watch src --ignore src/client src/api",
|
|
15
16
|
"dev-client": "env-cmd -f .env.development node src/client.dev",
|
|
16
17
|
"proxy": "node src/proxy proxy",
|
package/src/cli/cluster.js
CHANGED
|
@@ -14,6 +14,7 @@ class UnderpostCluster {
|
|
|
14
14
|
mongodb: false,
|
|
15
15
|
mongodb4: false,
|
|
16
16
|
mariadb: false,
|
|
17
|
+
postgresql: false,
|
|
17
18
|
valkey: false,
|
|
18
19
|
full: false,
|
|
19
20
|
info: false,
|
|
@@ -24,8 +25,15 @@ class UnderpostCluster {
|
|
|
24
25
|
nsUse: '',
|
|
25
26
|
infoCapacity: false,
|
|
26
27
|
infoCapacityPod: false,
|
|
28
|
+
istio: false,
|
|
29
|
+
pullImage: false,
|
|
27
30
|
},
|
|
28
31
|
) {
|
|
32
|
+
// 1) Install kind, kubeadm, docker, podman
|
|
33
|
+
// 2) Check kubectl, kubelet, containerd.io
|
|
34
|
+
// 3) Install Nvidia drivers from Rocky Linux docs
|
|
35
|
+
// 4) Install LXD with MAAS from Rocky Linux docs
|
|
36
|
+
// 5) Install MAAS src from snap
|
|
29
37
|
const npmRoot = getNpmRootPath();
|
|
30
38
|
const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
|
|
31
39
|
if (options.infoCapacityPod === true) return logger.info('', UnderpostDeploy.API.resourcesFactory());
|
|
@@ -66,26 +74,62 @@ class UnderpostCluster {
|
|
|
66
74
|
shellExec(`kubectl get secrets --all-namespaces -o wide`);
|
|
67
75
|
shellExec(`docker secret ls`);
|
|
68
76
|
shellExec(`kubectl get crd --all-namespaces -o wide`);
|
|
77
|
+
shellExec(`sudo kubectl api-resources`);
|
|
69
78
|
return;
|
|
70
79
|
}
|
|
71
80
|
|
|
72
|
-
if (
|
|
81
|
+
if (
|
|
82
|
+
(!options.istio && !UnderpostDeploy.API.get('kube-apiserver-kind-control-plane')[0]) ||
|
|
83
|
+
(options.istio === true && !UnderpostDeploy.API.get('calico-kube-controllers')[0])
|
|
84
|
+
) {
|
|
85
|
+
shellExec(`sudo setenforce 0`);
|
|
86
|
+
shellExec(`sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config`);
|
|
87
|
+
// sudo systemctl disable kubelet
|
|
88
|
+
// shellExec(`sudo systemctl enable --now kubelet`);
|
|
73
89
|
shellExec(`containerd config default > /etc/containerd/config.toml`);
|
|
74
90
|
shellExec(`sed -i -e "s/SystemdCgroup = false/SystemdCgroup = true/g" /etc/containerd/config.toml`);
|
|
75
91
|
// shellExec(`cp /etc/kubernetes/admin.conf ~/.kube/config`);
|
|
76
|
-
shellExec(`sudo systemctl restart kubelet`);
|
|
92
|
+
// shellExec(`sudo systemctl restart kubelet`);
|
|
77
93
|
shellExec(`sudo service docker restart`);
|
|
78
94
|
shellExec(`sudo systemctl enable --now containerd.service`);
|
|
79
|
-
shellExec(`sudo
|
|
80
|
-
|
|
81
|
-
`
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
shellExec(`sudo swapoff -a; sudo sed -i '/swap/d' /etc/fstab`);
|
|
96
|
+
if (options.istio === true) {
|
|
97
|
+
shellExec(`sysctl net.bridge.bridge-nf-call-iptables=1`);
|
|
98
|
+
shellExec(`sudo kubeadm init --pod-network-cidr=192.168.0.0/16`);
|
|
99
|
+
shellExec(`sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config`);
|
|
100
|
+
shellExec(`sudo chown $(id -u):$(id -g) $HOME/.kube/config**`);
|
|
101
|
+
// https://docs.tigera.io/calico/latest/getting-started/kubernetes/quickstart
|
|
102
|
+
shellExec(
|
|
103
|
+
`sudo kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.3/manifests/tigera-operator.yaml`,
|
|
104
|
+
);
|
|
105
|
+
// shellExec(
|
|
106
|
+
// `wget https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/custom-resources.yaml`,
|
|
107
|
+
// );
|
|
108
|
+
shellExec(`sudo kubectl apply -f ./manifests/calico-custom-resources.yaml`);
|
|
109
|
+
shellExec(`sudo systemctl restart containerd`);
|
|
110
|
+
} else {
|
|
111
|
+
shellExec(`sudo systemctl restart containerd`);
|
|
112
|
+
shellExec(
|
|
113
|
+
`cd ${underpostRoot}/manifests && kind create cluster --config kind-config${
|
|
114
|
+
options?.dev === true ? '-dev' : ''
|
|
115
|
+
}.yaml`,
|
|
116
|
+
);
|
|
117
|
+
shellExec(`sudo chown $(id -u):$(id -g) $HOME/.kube/config**`);
|
|
118
|
+
}
|
|
86
119
|
} else logger.warn('Cluster already initialized');
|
|
87
120
|
|
|
88
121
|
if (options.full === true || options.valkey === true) {
|
|
122
|
+
if (options.pullImage === true) {
|
|
123
|
+
// kubectl patch statefulset service-valkey --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"valkey/valkey:latest"}]'
|
|
124
|
+
// kubectl patch statefulset service-valkey -p '{"spec":{"template":{"spec":{"containers":[{"name":"service-valkey","imagePullPolicy":"Never"}]}}}}'
|
|
125
|
+
shellExec(`docker pull valkey/valkey`);
|
|
126
|
+
// shellExec(`sudo kind load docker-image valkey/valkey`);
|
|
127
|
+
// shellExec(`sudo podman pull docker.io/valkey/valkey:latest`);
|
|
128
|
+
// shellExec(`podman save -o valkey.tar valkey/valkey`);
|
|
129
|
+
// shellExec(`sudo kind load image-archive valkey.tar`);
|
|
130
|
+
// shellExec(`sudo rm -rf ./valkey.tar`);
|
|
131
|
+
shellExec(`sudo kind load docker-image valkey/valkey:latest`);
|
|
132
|
+
}
|
|
89
133
|
shellExec(`kubectl delete statefulset service-valkey`);
|
|
90
134
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/valkey`);
|
|
91
135
|
}
|
|
@@ -99,7 +143,17 @@ class UnderpostCluster {
|
|
|
99
143
|
shellExec(`kubectl delete statefulset mariadb-statefulset`);
|
|
100
144
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/mariadb`);
|
|
101
145
|
}
|
|
146
|
+
if (options.full === true || options.postgresql === true) {
|
|
147
|
+
shellExec(
|
|
148
|
+
`sudo kubectl create secret generic postgres-secret --from-file=password=/home/dd/engine/engine-private/postgresql-password`,
|
|
149
|
+
);
|
|
150
|
+
shellExec(`kubectl apply -k ./manifests/postgresql`);
|
|
151
|
+
}
|
|
102
152
|
if (options.mongodb4 === true) {
|
|
153
|
+
if (options.pullImage === true) {
|
|
154
|
+
shellExec(`docker pull mongo:4.4`);
|
|
155
|
+
shellExec(`sudo kind load docker-image mongo:4.4`);
|
|
156
|
+
}
|
|
103
157
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/mongodb-4.4`);
|
|
104
158
|
|
|
105
159
|
const deploymentName = 'mongodb-deployment';
|
|
@@ -199,10 +253,15 @@ class UnderpostCluster {
|
|
|
199
253
|
`sudo sed -i -e "s@/var/lib/containers/storage@/home/containers/storage@g" /etc/containers/storage.conf`,
|
|
200
254
|
);
|
|
201
255
|
shellExec(`sudo podman system reset -f`);
|
|
256
|
+
// https://github.com/kubernetes-sigs/kind/issues/2886
|
|
257
|
+
shellExec(`sysctl net.bridge.bridge-nf-call-iptables=0`);
|
|
258
|
+
shellExec(`sysctl net.bridge.bridge-nf-call-arptables=0`);
|
|
259
|
+
shellExec(`sysctl net.bridge.bridge-nf-call-ip6tables=0`);
|
|
260
|
+
shellExec(`docker network rm kind`);
|
|
202
261
|
},
|
|
203
262
|
getResourcesCapacity() {
|
|
204
263
|
const resources = {};
|
|
205
|
-
const info =
|
|
264
|
+
const info = true
|
|
206
265
|
? `Capacity:
|
|
207
266
|
cpu: 8
|
|
208
267
|
ephemeral-storage: 153131976Ki
|
package/src/cli/deploy.js
CHANGED
|
@@ -22,11 +22,11 @@ class UnderpostDeploy {
|
|
|
22
22
|
static NETWORK = {};
|
|
23
23
|
static API = {
|
|
24
24
|
sync(deployList, { versions, replicas }) {
|
|
25
|
-
const deployGroupId = 'dd.
|
|
25
|
+
const deployGroupId = 'dd.router';
|
|
26
26
|
fs.writeFileSync(`./engine-private/deploy/${deployGroupId}`, deployList, 'utf8');
|
|
27
27
|
const totalPods = deployList.split(',').length * versions.split(',').length * parseInt(replicas);
|
|
28
|
-
const limitFactor = 0.
|
|
29
|
-
const reserveFactor = 0.
|
|
28
|
+
const limitFactor = 0.8;
|
|
29
|
+
const reserveFactor = 0.05;
|
|
30
30
|
const resources = UnderpostCluster.API.getResourcesCapacity();
|
|
31
31
|
const memory = parseInt(resources.memory.value / totalPods);
|
|
32
32
|
const cpu = parseInt(resources.cpu.value / totalPods);
|
|
@@ -220,6 +220,14 @@ spec:
|
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
222
|
},
|
|
223
|
+
getCurrentTraffic(deployId) {
|
|
224
|
+
// kubectl get deploy,sts,svc,configmap,secret -n default -o yaml --export > default.yaml
|
|
225
|
+
const hostTest = Object.keys(
|
|
226
|
+
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
227
|
+
)[0];
|
|
228
|
+
const info = shellExec(`sudo kubectl get HTTPProxy/${hostTest} -o yaml`, { silent: true, stdout: true });
|
|
229
|
+
return info.match('blue') ? 'blue' : info.match('green') ? 'green' : null;
|
|
230
|
+
},
|
|
223
231
|
async callback(
|
|
224
232
|
deployList = 'default',
|
|
225
233
|
env = 'development',
|
|
@@ -235,6 +243,9 @@ spec:
|
|
|
235
243
|
traffic: '',
|
|
236
244
|
dashboardUpdate: false,
|
|
237
245
|
replicas: '',
|
|
246
|
+
disableUpdateDeployment: false,
|
|
247
|
+
infoTraffic: false,
|
|
248
|
+
rebuildClientsBundle: false,
|
|
238
249
|
},
|
|
239
250
|
) {
|
|
240
251
|
if (options.infoUtil === true)
|
|
@@ -242,11 +253,26 @@ spec:
|
|
|
242
253
|
kubectl rollout restart deployment/deployment-name
|
|
243
254
|
kubectl rollout undo deployment/deployment-name
|
|
244
255
|
kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
|
|
245
|
-
|
|
256
|
+
kubectl get pods -w
|
|
257
|
+
kubectl patch statefulset service-valkey --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"valkey/valkey:latest"}]'
|
|
258
|
+
kubectl patch statefulset service-valkey -p '{"spec":{"template":{"spec":{"containers":[{"name":"service-valkey","imagePullPolicy":"Never"}]}}}}'
|
|
259
|
+
`);
|
|
246
260
|
if (deployList === 'dd' && fs.existsSync(`./engine-private/deploy/dd.router`))
|
|
247
261
|
deployList = fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8');
|
|
262
|
+
if (options.infoTraffic === true) {
|
|
263
|
+
for (const _deployId of deployList.split(',')) {
|
|
264
|
+
const deployId = _deployId.trim();
|
|
265
|
+
logger.info('', {
|
|
266
|
+
deployId,
|
|
267
|
+
env,
|
|
268
|
+
traffic: UnderpostDeploy.API.getCurrentTraffic(deployId),
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (options.rebuildClientsBundle === true) await UnderpostDeploy.API.rebuildClientsBundle(deployList);
|
|
248
274
|
if (!(options.versions && typeof options.versions === 'string')) options.versions = 'blue,green';
|
|
249
|
-
if (!options.replicas) options.replicas =
|
|
275
|
+
if (!options.replicas) options.replicas = 1;
|
|
250
276
|
if (options.sync) UnderpostDeploy.API.sync(deployList, options);
|
|
251
277
|
if (options.buildManifest === true) await UnderpostDeploy.API.buildManifest(deployList, env, options);
|
|
252
278
|
if (options.infoRouter === true) logger.info('router', await UnderpostDeploy.API.routerFactory(deployList, env));
|
|
@@ -275,8 +301,12 @@ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
|
|
|
275
301
|
shellExec(`sudo kubectl port-forward -n default svc/${svc.NAME} ${port}:${port}`, { async: true });
|
|
276
302
|
continue;
|
|
277
303
|
}
|
|
278
|
-
|
|
279
|
-
|
|
304
|
+
|
|
305
|
+
if (!options.disableUpdateDeployment)
|
|
306
|
+
for (const version of options.versions.split(',')) {
|
|
307
|
+
shellExec(`sudo kubectl delete svc ${deployId}-${env}-${version}-service`);
|
|
308
|
+
shellExec(`sudo kubectl delete deployment ${deployId}-${env}-${version}`);
|
|
309
|
+
}
|
|
280
310
|
|
|
281
311
|
const confServer = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'));
|
|
282
312
|
for (const host of Object.keys(confServer)) {
|
|
@@ -291,7 +321,7 @@ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
|
|
|
291
321
|
: `manifests/deployment/${deployId}-${env}`;
|
|
292
322
|
|
|
293
323
|
if (!options.remove === true) {
|
|
294
|
-
shellExec(`sudo kubectl apply -f ./${manifestsPath}/deployment.yaml`);
|
|
324
|
+
if (!options.disableUpdateDeployment) shellExec(`sudo kubectl apply -f ./${manifestsPath}/deployment.yaml`);
|
|
295
325
|
shellExec(`sudo kubectl apply -f ./${manifestsPath}/proxy.yaml`);
|
|
296
326
|
if (env === 'production' && options.cert === true)
|
|
297
327
|
shellExec(`sudo kubectl apply -f ./${manifestsPath}/secret.yaml`);
|
|
@@ -354,6 +384,23 @@ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
|
|
|
354
384
|
|
|
355
385
|
return result;
|
|
356
386
|
},
|
|
387
|
+
rebuildClientsBundle(deployList) {
|
|
388
|
+
for (const _deployId of deployList.split(',')) {
|
|
389
|
+
const deployId = _deployId.trim();
|
|
390
|
+
const repoName = `engine-${deployId.split('-')[1]}`;
|
|
391
|
+
|
|
392
|
+
shellExec(`underpost script set ${deployId}-client-build '
|
|
393
|
+
cd /home/dd/engine &&
|
|
394
|
+
git checkout . &&
|
|
395
|
+
underpost pull . underpostnet/${repoName} &&
|
|
396
|
+
underpost pull ./engine-private underpostnet/${repoName}-private &&
|
|
397
|
+
underpost env ${deployId} production &&
|
|
398
|
+
node bin/deploy build-full-client ${deployId}
|
|
399
|
+
'`);
|
|
400
|
+
|
|
401
|
+
shellExec(`node bin script run ${deployId}-client-build --itc --pod-name ${deployId}`);
|
|
402
|
+
}
|
|
403
|
+
},
|
|
357
404
|
resourcesFactory() {
|
|
358
405
|
return {
|
|
359
406
|
requests: {
|
package/src/cli/fs.js
CHANGED
|
@@ -24,7 +24,7 @@ class UnderpostFileStorage {
|
|
|
24
24
|
getStorageConf(options) {
|
|
25
25
|
let storage, storageConf;
|
|
26
26
|
if (options.deployId && typeof options.deployId === 'string') {
|
|
27
|
-
storageConf = `./engine-private/conf/${options.deployId}/storage.json`;
|
|
27
|
+
storageConf = options.storageFilePath ?? `./engine-private/conf/${options.deployId}/storage.json`;
|
|
28
28
|
if (!fs.existsSync(storageConf)) fs.writeFileSync(storageConf, JSON.stringify({}), 'utf8');
|
|
29
29
|
storage = JSON.parse(fs.readFileSync(storageConf, 'utf8'));
|
|
30
30
|
}
|
|
@@ -35,7 +35,15 @@ class UnderpostFileStorage {
|
|
|
35
35
|
},
|
|
36
36
|
async recursiveCallback(
|
|
37
37
|
path,
|
|
38
|
-
options = {
|
|
38
|
+
options = {
|
|
39
|
+
rm: false,
|
|
40
|
+
recursive: false,
|
|
41
|
+
deployId: '',
|
|
42
|
+
force: false,
|
|
43
|
+
pull: false,
|
|
44
|
+
git: false,
|
|
45
|
+
storageFilePath: '',
|
|
46
|
+
},
|
|
39
47
|
) {
|
|
40
48
|
const { storage, storageConf } = UnderpostFileStorage.API.getStorageConf(options);
|
|
41
49
|
const deleteFiles = options.pull === true ? [] : UnderpostRepository.API.getDeleteFiles(path);
|
|
@@ -85,7 +93,10 @@ class UnderpostFileStorage {
|
|
|
85
93
|
if (options.rm === true) return await UnderpostFileStorage.API.delete(path, options);
|
|
86
94
|
return await UnderpostFileStorage.API.upload(path, options);
|
|
87
95
|
},
|
|
88
|
-
async upload(
|
|
96
|
+
async upload(
|
|
97
|
+
path,
|
|
98
|
+
options = { rm: false, recursive: false, deployId: '', force: false, pull: false, storageFilePath: '' },
|
|
99
|
+
) {
|
|
89
100
|
UnderpostFileStorage.API.cloudinaryConfig();
|
|
90
101
|
const { storage, storageConf } = UnderpostFileStorage.API.getStorageConf(options);
|
|
91
102
|
// path = UnderpostFileStorage.API.file2Zip(path);
|
package/src/cli/index.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import Underpost from '../index.js';
|
|
4
|
+
import { getUnderpostRootPath, loadConf } from '../server/conf.js';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import { commitData } from '../client/components/core/CommonJs.js';
|
|
7
|
+
import { shellExec } from '../server/process.js';
|
|
8
|
+
|
|
9
|
+
const underpostRootPath = getUnderpostRootPath();
|
|
10
|
+
fs.existsSync(`${underpostRootPath}/.env`)
|
|
11
|
+
? dotenv.config({ path: `${underpostRootPath}/.env`, override: true })
|
|
12
|
+
: dotenv.config();
|
|
13
|
+
|
|
14
|
+
const program = new Command();
|
|
15
|
+
|
|
16
|
+
program.name('underpost').description(`underpost ci/cd cli ${Underpost.version}`).version(Underpost.version);
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command('new')
|
|
20
|
+
.argument('<app-name>', 'Application name')
|
|
21
|
+
.description('Create a new project')
|
|
22
|
+
.action(Underpost.repo.new);
|
|
23
|
+
|
|
24
|
+
program
|
|
25
|
+
.command('start')
|
|
26
|
+
.argument('<deploy-id>', 'Deploy configuration id')
|
|
27
|
+
.argument('[env]', 'Optional environment, for default is development')
|
|
28
|
+
.option('--run', 'Run app servers and monitor health server')
|
|
29
|
+
.option('--build', 'Build app client')
|
|
30
|
+
.action(Underpost.start.callback)
|
|
31
|
+
.description('Start up server, build pipelines, or services');
|
|
32
|
+
|
|
33
|
+
program
|
|
34
|
+
.command('clone')
|
|
35
|
+
.argument(`<uri>`, 'e.g. username/repository')
|
|
36
|
+
.option('--bare', 'Clone only .git files')
|
|
37
|
+
.description('Clone github repository')
|
|
38
|
+
.action(Underpost.repo.clone);
|
|
39
|
+
|
|
40
|
+
program
|
|
41
|
+
.command('pull')
|
|
42
|
+
.argument('<path>', 'Absolute or relative directory')
|
|
43
|
+
.argument(`<uri>`, 'e.g. username/repository')
|
|
44
|
+
.description('Pull github repository')
|
|
45
|
+
.action(Underpost.repo.pull);
|
|
46
|
+
|
|
47
|
+
program
|
|
48
|
+
.command('cmt')
|
|
49
|
+
.argument('<path>', 'Absolute or relative directory')
|
|
50
|
+
.argument(`<commit-type>`, `Options: ${Object.keys(commitData)}`)
|
|
51
|
+
.argument(`[module-tag]`, 'Optional set module tag')
|
|
52
|
+
.argument(`[message]`, 'Optional set additional message')
|
|
53
|
+
.option('--empty', 'Allow empty files')
|
|
54
|
+
.option('--copy', 'Copy to clipboard message')
|
|
55
|
+
.option('--info', 'Info commit types')
|
|
56
|
+
.description('Commit github repository')
|
|
57
|
+
.action(Underpost.repo.commit);
|
|
58
|
+
|
|
59
|
+
program
|
|
60
|
+
.command('push')
|
|
61
|
+
.argument('<path>', 'Absolute or relative directory')
|
|
62
|
+
.argument(`<uri>`, 'e.g. username/repository')
|
|
63
|
+
.option('-f', 'Force push overwriting repository')
|
|
64
|
+
.description('Push github repository')
|
|
65
|
+
.action(Underpost.repo.push);
|
|
66
|
+
|
|
67
|
+
program
|
|
68
|
+
.command('env')
|
|
69
|
+
.argument('<deploy-id>', `deploy configuration id, if 'clean' restore default`)
|
|
70
|
+
.argument('[env]', 'Optional environment, for default is production')
|
|
71
|
+
.description('Set environment variables files and conf related to <deploy-id>')
|
|
72
|
+
.action(loadConf);
|
|
73
|
+
|
|
74
|
+
program
|
|
75
|
+
.command('config')
|
|
76
|
+
.argument('operator', `Options: ${Object.keys(Underpost.env)}`)
|
|
77
|
+
.argument('[key]', 'Config key')
|
|
78
|
+
.argument('[value]', 'Config value')
|
|
79
|
+
.description(`Manage configuration, operators`)
|
|
80
|
+
.action((...args) => Underpost.env[args[0]](args[1], args[2]));
|
|
81
|
+
|
|
82
|
+
program
|
|
83
|
+
.command('root')
|
|
84
|
+
.description('Get npm root path')
|
|
85
|
+
.action(() => console.log(getNpmRootPath()));
|
|
86
|
+
|
|
87
|
+
program
|
|
88
|
+
.command('cluster')
|
|
89
|
+
.argument('[pod-name]', 'Optional pod name filter')
|
|
90
|
+
.option('--reset', `Delete all clusters and prune all data and caches`)
|
|
91
|
+
.option('--mariadb', 'Init with mariadb statefulset')
|
|
92
|
+
.option('--mongodb', 'Init with mongodb statefulset')
|
|
93
|
+
.option('--postgresql', 'Init with postgresql statefulset')
|
|
94
|
+
.option('--mongodb4', 'Init with mongodb 4.4 service')
|
|
95
|
+
.option('--istio', 'Init base istio cluster')
|
|
96
|
+
.option('--valkey', 'Init with valkey service')
|
|
97
|
+
.option('--contour', 'Init with project contour base HTTPProxy and envoy')
|
|
98
|
+
.option('--cert-manager', 'Init with letsencrypt-prod ClusterIssuer')
|
|
99
|
+
.option('--info', 'Get all kinds objects deployed')
|
|
100
|
+
.option('--full', 'Init with all statefulsets and services available')
|
|
101
|
+
.option('--ns-use <ns-name>', 'Switches current context to namespace')
|
|
102
|
+
.option('--dev', 'init with dev cluster')
|
|
103
|
+
.option('--list-pods', 'Display list pods information')
|
|
104
|
+
.option('--info-capacity', 'display current total machine capacity info')
|
|
105
|
+
.option('--info-capacity-pod', 'display current machine capacity pod info')
|
|
106
|
+
.option('--pull-image', 'Set optional pull associated image')
|
|
107
|
+
.action(Underpost.cluster.init)
|
|
108
|
+
.description('Manage cluster, for default initialization base kind cluster');
|
|
109
|
+
|
|
110
|
+
program
|
|
111
|
+
.command('deploy')
|
|
112
|
+
.argument('<deploy-list>', 'Deploy id list, e.g. default-a,default-b')
|
|
113
|
+
.argument('[env]', 'Optional environment, for default is development')
|
|
114
|
+
.option('--remove', 'Delete deployments and services')
|
|
115
|
+
.option('--sync', 'Sync deployments env, ports, and replicas')
|
|
116
|
+
.option('--info-router', 'Display router structure')
|
|
117
|
+
.option('--expose', 'Expose service match deploy-list')
|
|
118
|
+
.option('--info-util', 'Display kubectl util management commands')
|
|
119
|
+
.option('--cert', 'Reset tls/ssl certificate secrets')
|
|
120
|
+
.option('--build-manifest', 'Build kind yaml manifests: deployments, services, proxy and secrets')
|
|
121
|
+
.option('--dashboard-update', 'Update dashboard instance data with current router config')
|
|
122
|
+
.option('--replicas <replicas>', 'Set custom number of replicas')
|
|
123
|
+
.option('--versions <deployment-versions>', 'Comma separated custom deployment versions')
|
|
124
|
+
.option('--traffic <traffic-versions>', 'Comma separated custom deployment traffic')
|
|
125
|
+
.option('--disable-update-deployment', 'Disable update deployments')
|
|
126
|
+
.option('--info-traffic', 'get traffic conf form current resources deployments')
|
|
127
|
+
.option(
|
|
128
|
+
'--rebuild-clients-bundle',
|
|
129
|
+
'Inside container, rebuild clients bundle, only static public or storage client files',
|
|
130
|
+
)
|
|
131
|
+
.description('Manage deployment, for default deploy development pods')
|
|
132
|
+
.action(Underpost.deploy.callback);
|
|
133
|
+
|
|
134
|
+
program
|
|
135
|
+
.command('secret')
|
|
136
|
+
.argument('<platform>', `Options: ${Object.keys(Underpost.secret)}`)
|
|
137
|
+
.option('--init', 'Init secrets platform environment')
|
|
138
|
+
.option('--create-from-file <path-env-file>', 'Create secret from env file')
|
|
139
|
+
.option('--list', 'Lists secrets')
|
|
140
|
+
// .option('--delete [secret-key]', 'Delete key secret, if not set, are default delete all')
|
|
141
|
+
// .option('--create [secret-key] [secret-value]', 'Create secret key, with secret value')
|
|
142
|
+
.description(`Manage secrets`)
|
|
143
|
+
.action((...args) => {
|
|
144
|
+
if (args[1].createFromFile) return Underpost.secret[args[0]].createFromEnvFile(args[1].createFromFile);
|
|
145
|
+
if (args[1].list) return Underpost.secret[args[0]].list();
|
|
146
|
+
if (args[1].init) return Underpost.secret[args[0]].init();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
program
|
|
150
|
+
.command('dockerfile-image-build')
|
|
151
|
+
.option('--path [path]', 'Dockerfile path')
|
|
152
|
+
.option('--image-name [image-name]', 'Set image name')
|
|
153
|
+
.option('--image-path [image-path]', 'Set tar image path')
|
|
154
|
+
.option('--dockerfile-name [dockerfile-name]', 'set Dockerfile name')
|
|
155
|
+
.option('--podman-save', 'Export tar file from podman')
|
|
156
|
+
.option('--kind-load', 'Import tar image to Kind cluster')
|
|
157
|
+
.option('--secrets', 'Dockerfile env secrets')
|
|
158
|
+
.option('--secrets-path [secrets-path]', 'Dockerfile custom path env secrets')
|
|
159
|
+
.option('--no-cache', 'Build without using cache')
|
|
160
|
+
.description('Build image from Dockerfile')
|
|
161
|
+
.action(Underpost.image.dockerfile.build);
|
|
162
|
+
|
|
163
|
+
program
|
|
164
|
+
.command('dockerfile-pull-base-images')
|
|
165
|
+
.description('Pull underpost dockerfile images requirements')
|
|
166
|
+
.action(Underpost.image.dockerfile.pullBaseImages);
|
|
167
|
+
|
|
168
|
+
program
|
|
169
|
+
.command('install')
|
|
170
|
+
.description('Fast import underpost npm dependencies')
|
|
171
|
+
.action(() => {
|
|
172
|
+
fs.copySync(`${underpostRootPath}/node_modules`, './node_modules');
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
program
|
|
176
|
+
.command('db')
|
|
177
|
+
.argument('<deploy-list>', 'Deploy id list, e.g. default-a,default-b')
|
|
178
|
+
.option('--import', 'Import container backups from repositories')
|
|
179
|
+
.option('--export', 'Export container backups to repositories')
|
|
180
|
+
.option('--pod-name <pod-name>', 'Optional pod context')
|
|
181
|
+
.option('--collections <collections>', 'Comma separated collections')
|
|
182
|
+
.option('--out-path <out-path>', 'Custom out path backup')
|
|
183
|
+
.option('--drop', 'Drop databases')
|
|
184
|
+
.option('--preserveUUID', 'Preserve Ids')
|
|
185
|
+
.option('--git', 'Upload to github')
|
|
186
|
+
.option('--hosts <hosts>', 'Comma separated hosts')
|
|
187
|
+
.option('--paths <paths>', 'Comma separated paths')
|
|
188
|
+
.option('--ns <ns-name>', 'Optional name space context')
|
|
189
|
+
.description('Manage databases')
|
|
190
|
+
.action(Underpost.db.callback);
|
|
191
|
+
|
|
192
|
+
program
|
|
193
|
+
.command('script')
|
|
194
|
+
.argument('operator', `Options: ${Object.keys(Underpost.script)}`)
|
|
195
|
+
.argument('<script-name>', 'Script name')
|
|
196
|
+
.argument('[script-value]', 'Literal command, or path')
|
|
197
|
+
.option('--itc', 'Inside container execution context')
|
|
198
|
+
.option('--itc-path', 'Inside container path options')
|
|
199
|
+
.option('--ns <ns-name>', 'Options name space context')
|
|
200
|
+
.option('--pod-name <pod-name>')
|
|
201
|
+
.description(
|
|
202
|
+
'Supports a number of built-in underpost global scripts and their preset life cycle events as well as arbitrary scripts',
|
|
203
|
+
)
|
|
204
|
+
.action((...args) => Underpost.script[args[0]](args[1], args[2], args[3]));
|
|
205
|
+
|
|
206
|
+
program
|
|
207
|
+
.command('cron')
|
|
208
|
+
.argument('[deploy-list]', 'Deploy id list, e.g. default-a,default-b')
|
|
209
|
+
.argument('[job-list]', `Deploy id list, e.g. ${Object.keys(Underpost.cron)}, for default all available jobs`)
|
|
210
|
+
.option('--itc', 'Inside container execution context')
|
|
211
|
+
.option('--init', 'Init cron jobs for cron job default deploy id')
|
|
212
|
+
.option('--git', 'Upload to github')
|
|
213
|
+
.option('--dashboard-update', 'Update dashboard cron data with current jobs config')
|
|
214
|
+
.description('Cron jobs management')
|
|
215
|
+
.action(Underpost.cron.callback);
|
|
216
|
+
|
|
217
|
+
program
|
|
218
|
+
.command('fs')
|
|
219
|
+
.argument('[path]', 'Absolute or relative directory')
|
|
220
|
+
.option('--rm', 'Remove file')
|
|
221
|
+
.option('--git', 'Current git changes')
|
|
222
|
+
.option('--recursive', 'Upload files recursively')
|
|
223
|
+
.option('--deploy-id <deploy-id>', 'Deploy configuration id')
|
|
224
|
+
.option('--pull', 'Download file')
|
|
225
|
+
.option('--force', 'Force action')
|
|
226
|
+
.option('--storage-file-path <storage-file-path>', 'custom file storage path')
|
|
227
|
+
.description('File storage management, for default upload file')
|
|
228
|
+
.action(Underpost.fs.callback);
|
|
229
|
+
|
|
230
|
+
program
|
|
231
|
+
.command('test')
|
|
232
|
+
.argument('[deploy-list]', 'Deploy id list, e.g. default-a,default-b')
|
|
233
|
+
.description('Manage Test, for default run current underpost default test')
|
|
234
|
+
.option('--itc', 'Inside container execution context')
|
|
235
|
+
.option('--sh', 'Copy to clipboard, container entrypoint shell command')
|
|
236
|
+
.option('--logs', 'Display container logs')
|
|
237
|
+
.option('--pod-name <pod-name>')
|
|
238
|
+
.option('--pod-status <pod-status>')
|
|
239
|
+
.option('--kind-type <kind-type>')
|
|
240
|
+
.action(Underpost.test.callback);
|
|
241
|
+
|
|
242
|
+
program
|
|
243
|
+
.command('monitor')
|
|
244
|
+
.argument('<deploy-id>', 'Deploy configuration id')
|
|
245
|
+
.argument('[env]', 'Optional environment, for default is development')
|
|
246
|
+
.option('--ms-interval <ms-interval>', 'Custom ms interval delta time')
|
|
247
|
+
.option('--now', 'Exec immediately monitor script')
|
|
248
|
+
.option('--single', 'Disable recurrence')
|
|
249
|
+
.option('--replicas <replicas>', 'Set custom number of replicas')
|
|
250
|
+
.option('--type <type>', 'Set custom monitor type')
|
|
251
|
+
.option('--sync', 'Sync with current proxy deployments proxy traffic')
|
|
252
|
+
.description('Monitor health server management')
|
|
253
|
+
.action(Underpost.monitor.callback);
|
|
254
|
+
|
|
255
|
+
const buildCliDoc = () => {
|
|
256
|
+
let md = shellExec(`node bin help`, { silent: true, stdout: true }).split('Options:');
|
|
257
|
+
const baseOptions =
|
|
258
|
+
`## ${md[0].split(`\n`)[2]}
|
|
259
|
+
|
|
260
|
+
### Usage: ` +
|
|
261
|
+
'`' +
|
|
262
|
+
md[0].split(`\n`)[0].split('Usage: ')[1] +
|
|
263
|
+
'`' +
|
|
264
|
+
`
|
|
265
|
+
` +
|
|
266
|
+
'```\n Options:' +
|
|
267
|
+
md[1] +
|
|
268
|
+
' \n```';
|
|
269
|
+
md =
|
|
270
|
+
baseOptions +
|
|
271
|
+
`
|
|
272
|
+
|
|
273
|
+
## Commands:
|
|
274
|
+
`;
|
|
275
|
+
program.commands.map((o) => {
|
|
276
|
+
md +=
|
|
277
|
+
`
|
|
278
|
+
|
|
279
|
+
` +
|
|
280
|
+
'### `' +
|
|
281
|
+
o._name +
|
|
282
|
+
'` :' +
|
|
283
|
+
`
|
|
284
|
+
` +
|
|
285
|
+
'```\n ' +
|
|
286
|
+
shellExec(`node bin help ${o._name}`, { silent: true, stdout: true }) +
|
|
287
|
+
' \n```' +
|
|
288
|
+
`
|
|
289
|
+
`;
|
|
290
|
+
});
|
|
291
|
+
fs.writeFileSync(`./src/client/public/nexodev/docs/references/Command Line Interface.md`, md, 'utf8');
|
|
292
|
+
fs.writeFileSync(`./cli.md`, md, 'utf8');
|
|
293
|
+
const readmeSplit = `pwa-microservices-template</a>`;
|
|
294
|
+
const readme = fs.readFileSync(`./README.md`, 'utf8').split(readmeSplit);
|
|
295
|
+
fs.writeFileSync(
|
|
296
|
+
'./README.md',
|
|
297
|
+
readme[0] +
|
|
298
|
+
readmeSplit +
|
|
299
|
+
`
|
|
300
|
+
|
|
301
|
+
` +
|
|
302
|
+
baseOptions +
|
|
303
|
+
`
|
|
304
|
+
|
|
305
|
+
<a target="_top" href="https://github.com/underpostnet/pwa-microservices-template/blob/master/cli.md">See complete CLI Docs here.</a>
|
|
306
|
+
|
|
307
|
+
`,
|
|
308
|
+
'utf8',
|
|
309
|
+
);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
export { program, buildCliDoc };
|