@catladder/cli 1.69.0 → 1.71.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/package.json CHANGED
@@ -24,7 +24,7 @@
24
24
  "node": ">=12.0.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@catladder/pipeline": "1.69.0",
27
+ "@catladder/pipeline": "1.71.0",
28
28
  "@kubernetes/client-node": "^0.16.2",
29
29
  "@tsconfig/node14": "^1.0.1",
30
30
  "@types/common-tags": "^1.8.0",
@@ -57,5 +57,5 @@
57
57
  "typescript": "^4.5.4",
58
58
  "vorpal": "^1.12.0"
59
59
  },
60
- "version": "1.69.0"
60
+ "version": "1.71.0"
61
61
  }
@@ -4,6 +4,7 @@ import packageInfos from "../../packageInfos";
4
4
  import { stopAllPortForwards } from "../../utils/portForward";
5
5
  import general from "./commands/general";
6
6
  import mongodb from "./commands/mongodb";
7
+ import cloudSQL from "./commands/cloudSQL";
7
8
  import project from "./commands/project";
8
9
  import theStuffThatReallyMatters from "./commands/theStuffThatReallyMatters";
9
10
 
@@ -29,6 +30,7 @@ export default async () => {
29
30
 
30
31
  general(vorpal);
31
32
  project(vorpal);
33
+ cloudSQL(vorpal);
32
34
  mongodb(vorpal);
33
35
  theStuffThatReallyMatters(vorpal);
34
36
 
@@ -0,0 +1,132 @@
1
+ import { spawn } from "child-process-promise";
2
+ import type Vorpal from "vorpal";
3
+
4
+ const createProxy = async (instance: string, port: number) => {
5
+ const proxy = spawn(
6
+ `cloud_sql_proxy -instances ${instance}=tcp:${port}`,
7
+ [],
8
+ { shell: "bash" }
9
+ );
10
+ // wait until it starts
11
+ await spawn(
12
+ `echo -n "Waiting for proxy"
13
+ until echo > /dev/tcp/localhost/${port}; do
14
+ sleep 0.2
15
+ echo -n "."
16
+ done 2>/dev/null`,
17
+ [],
18
+ { shell: "bash" }
19
+ );
20
+ const stop = () => proxy.childProcess.kill();
21
+ process.on("beforeExit", stop);
22
+
23
+ return {
24
+ stop,
25
+ };
26
+ };
27
+
28
+ export default async (vorpal: Vorpal) =>
29
+ vorpal
30
+ .command(
31
+ "cloud-sql-restore-db",
32
+ "restore a db from one source to another target"
33
+ )
34
+ .action(async function restoreDb() {
35
+ const { sourceInstance } = await this.prompt({
36
+ type: "input",
37
+ name: "sourceInstance",
38
+
39
+ message: "Source instance (connection string)? 🤔 ",
40
+ });
41
+
42
+ const SOURCE_INSTANCE_PORT = 54399;
43
+ const TARGET_INSTANCE_PORT = 54499;
44
+
45
+ const sourceProxy = await createProxy(
46
+ sourceInstance,
47
+ SOURCE_INSTANCE_PORT
48
+ );
49
+
50
+ const { sourcePassword } = await this.prompt({
51
+ type: "input",
52
+ name: "sourcePassword",
53
+
54
+ message: "Source Password? 🤔 ",
55
+ });
56
+
57
+ const { sourceDbName } = await this.prompt({
58
+ type: "input",
59
+ name: "sourceDbName",
60
+
61
+ message: "Source DB name? 🤔 ",
62
+ });
63
+
64
+ const { targetInstance } = await this.prompt({
65
+ type: "input",
66
+ name: "targetInstance",
67
+
68
+ message: "Targe INSTANCE (connection string)? 🤔 ",
69
+ });
70
+
71
+ const targetProxy = await createProxy(
72
+ targetInstance,
73
+ TARGET_INSTANCE_PORT
74
+ );
75
+
76
+ const { targetPassword } = await this.prompt({
77
+ type: "input",
78
+ name: "targetPassword",
79
+
80
+ message: "Target Password? 🤔 ",
81
+ });
82
+
83
+ const { targetDbName } = await this.prompt({
84
+ type: "input",
85
+ name: "targetDbName",
86
+
87
+ message: "Target DB name? 🤔 ",
88
+ });
89
+
90
+ const { shouldContinue } = await this.prompt({
91
+ type: "confirm",
92
+ name: "shouldContinue",
93
+ message: `This will drop ${targetInstance}/${targetDbName} and replace it with ${sourceInstance}/${sourceDbName}. Continue? 🤔 `,
94
+ });
95
+
96
+ if (!shouldContinue) {
97
+ return;
98
+ }
99
+
100
+ const targetPSQL = (command: string) =>
101
+ `PGPASSWORD=${targetPassword} psql -p ${TARGET_INSTANCE_PORT} --host=localhost --user=postgres -q ${command}`;
102
+
103
+ const copyDBScript = `
104
+ set -e
105
+
106
+
107
+
108
+ dumptmp=$(mktemp /tmp/dump.XXXXXX)
109
+
110
+ echo "Dumping file to $dumptmp"
111
+ pg_dump --dbname=postgres://postgres:${sourcePassword}@localhost:${SOURCE_INSTANCE_PORT}/${sourceDbName} --no-owner --no-privileges > $dumptmp
112
+ echo "dump done"
113
+ ${targetPSQL(
114
+ `-c 'drop database "${targetDbName}" WITH (FORCE)' 1> /dev/null || true`
115
+ )}
116
+ ${targetPSQL(`-c 'create database "${targetDbName}"' 1> /dev/null`)}
117
+ echo "Restoring dump..."
118
+ ${targetPSQL(`"${targetDbName}" < $dumptmp 1> /dev/null`)}
119
+
120
+
121
+ echo "Clean up..."
122
+ set +e
123
+ rm $dumptmp
124
+ echo "\n🐱 Done!"
125
+ `;
126
+ try {
127
+ await spawn(copyDBScript, [], { shell: "bash", stdio: "inherit" });
128
+ } finally {
129
+ sourceProxy.stop();
130
+ targetProxy.stop();
131
+ }
132
+ });
@@ -0,0 +1,8 @@
1
+ import type Vorpal from "vorpal";
2
+ //import commandInitProject from "./commandInitProject.old";
3
+
4
+ import commandRestoreDb from "./commandRestoreDb";
5
+
6
+ export default async (vorpal: Vorpal) => {
7
+ commandRestoreDb(vorpal);
8
+ };
@@ -1,7 +1,7 @@
1
1
  import type Vorpal from "vorpal";
2
2
  import commandCloudSqlProxy from "./commandCloudSqlProxy";
3
3
  import commandConfigSecrets from "./commandConfigSecrets";
4
- import commandCopyDB from "./commandCopyDB";
4
+
5
5
  import commandDeletePods from "./commandDeletePods";
6
6
  import commandDeleteProject from "./commandDeleteProject";
7
7
  import commandEnvVars from "./commandEnvVars";
@@ -51,7 +51,6 @@ export default async (vorpal: Vorpal) => {
51
51
  commandConfigSecrets(vorpal);
52
52
  commandSecretsClearBackups(vorpal);
53
53
  commandDeletePods(vorpal);
54
- commandCopyDB(vorpal);
55
54
 
56
55
  commandGetShell(vorpal);
57
56
  commandPortForward(vorpal);
@@ -1 +0,0 @@
1
- {"version":3,"file":"commandCopyDB.js","sourceRoot":"","sources":["../../../../../src/apps/cli/commands/project/commandCopyDB.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,wEAI6C;AAE7C,2DAA2D;AAE3D,sBAAe,UAAO,MAAc;;;;;gBAClC,KAAA,CAAA,KAAA,MAAM;qBACH,OAAO,CACN,wBAAwB,EACxB,2CAA2C,CAC5C,CAAA;qBACA,YAAY,CAAA;gBAAC,qBAAM,IAAA,kCAAgB,GAAE,EAAA;oBALxC,sBAAA,cAKgB,SAAwB,EAAC;qBACtC,MAAM,CAAC,SAAe,MAAM,CAAC,EAAgB;wBAAd,YAAY,kBAAA;;;;;;oCACpC,KAAyB,IAAA,8BAAW,EAAC,YAAY,CAAC,EAAhD,GAAG,SAAA,EAAE,aAAa,mBAAA,CAA+B;oCACvB,qBAAM,IAAA,mCAAgB,GAAE,EAAA;;oCAApD,KAA4B,SAAwB,EAAlD,YAAY,kBAAA,EAAE,OAAO,aAAA;oCAEF,qBAAM,IAAI,CAAC,MAAM,CAAC;4CAC3C,IAAI,EAAE,SAAS;4CACf,IAAI,EAAE,gBAAgB;4CACtB,OAAO,EACL,sFAAsF;yCACzF,CAAC,EAAA;;oCALM,cAAc,GAAK,CAAA,SAKzB,CAAA,eALoB;oCAOtB,IAAI,CAAC,cAAc,EAAE;wCACnB,sBAAO;qCACR;;;;;iBA6DF,CAAC,EAAA;;;KAAA,EAAC"}
@@ -1,92 +0,0 @@
1
- import { spawn } from "child-process-promise";
2
- import type Vorpal from "vorpal";
3
- import {
4
- getEnvVars,
5
- getProjectConfig,
6
- parseChoice,
7
- } from "../../../../config/getProjectConfig";
8
- import { readPass } from "../../../../utils/passwordstore";
9
- import { envAndComponents } from "./utils/autocompletions";
10
-
11
- export default async (vorpal: Vorpal) =>
12
- vorpal
13
- .command(
14
- "copy-db <envComponent>",
15
- "replace local db with the one from an env"
16
- )
17
- .autocomplete(await envAndComponents())
18
- .action(async function copyDB({ envComponent }) {
19
- const { env, componentName } = parseChoice(envComponent);
20
- const { customerName, appName } = await getProjectConfig();
21
-
22
- const { shouldContinue } = await this.prompt({
23
- type: "confirm",
24
- name: "shouldContinue",
25
- message:
26
- "This will drop your local database and replace it with the remote one. Continue? 🤔 ",
27
- });
28
-
29
- if (!shouldContinue) {
30
- return;
31
- }
32
-
33
- // TODO: reimpleent with new config
34
- /*
35
- throw new Error("needs reimplementation with new config");
36
- const GOOGLE_CLOUD_SQL_REGION = "europe-west6"; // currently hardcoded
37
- const { POSTGRESQL_PASSWORD } = await getEnvVars(
38
- this,
39
- env,
40
- componentName
41
- );
42
-
43
- const LOCAL_PORT = 54321;
44
-
45
- const instanceName = `${"xxxxxx reimplement shoulld be project id"}:${GOOGLE_CLOUD_SQL_REGION}:${customerName}-${appName}-${env}=tcp:${LOCAL_PORT}`;
46
- const cloudsqlCredentials = await readPass(GOOGLE_CLOUD_SQL_PASS_PATH);
47
-
48
- const { POSTGRESQL_URL } = process.env;
49
- const matches = new RegExp(/\w+:\/\/.*@.*\/(\w*)()/g).exec(
50
- POSTGRESQL_URL
51
- );
52
- if (!matches) {
53
- throw new Error("Could not determine db name.");
54
- }
55
- const localDBName = matches[1];
56
-
57
- const copyDBScript = `
58
- set -e
59
- credtmp=$(mktemp /tmp/cred.XXXXXX)
60
- echo '${cloudsqlCredentials}' > $credtmp
61
- echo "Opening connection..."
62
- cloud_sql_proxy -instances ${instanceName} -credential_file $credtmp &> /dev/null &
63
- PROXY_PID=$!
64
-
65
- echo -n "Waiting for proxy"
66
- until echo > /dev/tcp/localhost/${LOCAL_PORT}; do
67
- sleep 0.2
68
- echo -n "."
69
- done 2>/dev/null
70
- echo
71
-
72
- dumptmp=$(mktemp /tmp/dump.XXXXXX)
73
-
74
- echo "Dumping file to $dumptmp"
75
- pg_dump --dbname=postgres://postgres:${POSTGRESQL_PASSWORD}@localhost:${LOCAL_PORT}/${componentName} --no-owner --no-privileges > $dumptmp
76
- psql -q -c "drop database ${localDBName}" 1> /dev/null
77
- psql -q -c "create database ${localDBName}" 1> /dev/null
78
- echo "Restoring dump..."
79
- psql -q ${localDBName} < $dumptmp 1> /dev/null
80
-
81
- echo "Clean up..."
82
- set +e
83
- kill -9 $PROXY_PID
84
- wait $PROXY_PID 2> /dev/null
85
- rm $credtmp
86
- rm $dumptmp
87
- echo "\n🐱 Done!"
88
- `;
89
-
90
- await spawn(copyDBScript, [], { shell: "bash", stdio: "inherit" });
91
- */
92
- });