@catladder/cli 0.0.0-refactor-env-context-76787e25 → 0.0.0-refactor-needs-c896b98e

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.
Files changed (48) hide show
  1. package/dist/apps/cli/cli.js +2 -0
  2. package/dist/apps/cli/cli.js.map +1 -1
  3. package/dist/apps/cli/commands/{project/commandCopyDB.d.ts → cloudSQL/commandRestoreDb.d.ts} +0 -0
  4. package/dist/apps/cli/commands/cloudSQL/commandRestoreDb.js +176 -0
  5. package/dist/apps/cli/commands/cloudSQL/commandRestoreDb.js.map +1 -0
  6. package/dist/apps/cli/commands/cloudSQL/index.d.ts +3 -0
  7. package/dist/apps/cli/commands/{project/commandCopyDB.js → cloudSQL/index.js} +9 -39
  8. package/dist/apps/cli/commands/cloudSQL/index.js.map +1 -0
  9. package/dist/apps/cli/commands/project/commandCloudSqlProxy.js +106 -45
  10. package/dist/apps/cli/commands/project/commandCloudSqlProxy.js.map +1 -1
  11. package/dist/apps/cli/commands/project/commandGetMyTotalWorktime.js +1 -1
  12. package/dist/apps/cli/commands/project/commandGetMyTotalWorktime.js.map +1 -1
  13. package/dist/apps/cli/commands/project/index.js +0 -2
  14. package/dist/apps/cli/commands/project/index.js.map +1 -1
  15. package/dist/apps/cli/commands/project/setup/setupCloudRun.js +20 -3
  16. package/dist/apps/cli/commands/project/setup/setupCloudRun.js.map +1 -1
  17. package/dist/apps/cli/commands/project/setup/setupCloudSQL.js +2 -2
  18. package/dist/apps/cli/commands/project/setup/setupCloudSQL.js.map +1 -1
  19. package/dist/apps/cli/commands/project/setup/setupContext.js +1 -1
  20. package/dist/apps/cli/commands/project/setup/setupContext.js.map +1 -1
  21. package/dist/apps/cli/commands/theStuffThatReallyMatters/index.js +1 -1
  22. package/dist/apps/cli/commands/theStuffThatReallyMatters/index.js.map +1 -1
  23. package/dist/apps/cli/verify/migration/fromv2.js +2 -0
  24. package/dist/apps/cli/verify/migration/fromv2.js.map +1 -1
  25. package/dist/apps/cli/verify/migration/oldGitlabCi.js +1 -1
  26. package/dist/apps/cli/verify/migration/oldGitlabCi.js.map +1 -1
  27. package/dist/bundles/catenv/index.js +1600 -1455
  28. package/dist/bundles/cli/index.js +1980 -1600
  29. package/dist/config/getProjectConfig.d.ts +1 -1
  30. package/dist/config/getProjectConfig.js +9 -2
  31. package/dist/config/getProjectConfig.js.map +1 -1
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +2 -2
  34. package/src/apps/cli/cli.ts +2 -0
  35. package/src/apps/cli/commands/cloudSQL/commandRestoreDb.ts +154 -0
  36. package/src/apps/cli/commands/cloudSQL/index.ts +8 -0
  37. package/src/apps/cli/commands/project/commandCloudSqlProxy.ts +105 -36
  38. package/src/apps/cli/commands/project/commandGetMyTotalWorktime.ts +1 -1
  39. package/src/apps/cli/commands/project/index.ts +1 -2
  40. package/src/apps/cli/commands/project/setup/setupCloudRun.ts +11 -1
  41. package/src/apps/cli/commands/project/setup/setupCloudSQL.ts +6 -3
  42. package/src/apps/cli/commands/project/setup/setupContext.ts +2 -2
  43. package/src/apps/cli/commands/theStuffThatReallyMatters/index.ts +1 -1
  44. package/src/apps/cli/verify/migration/fromv2.ts +1 -0
  45. package/src/apps/cli/verify/migration/oldGitlabCi.ts +1 -1
  46. package/src/config/getProjectConfig.ts +9 -4
  47. package/dist/apps/cli/commands/project/commandCopyDB.js.map +0 -1
  48. package/src/apps/cli/commands/project/commandCopyDB.ts +0 -92
package/package.json CHANGED
@@ -24,7 +24,7 @@
24
24
  "node": ">=12.0.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@catladder/pipeline": "0.0.0-refactor-env-context-76787e25",
27
+ "@catladder/pipeline": "0.0.0-refactor-needs-c896b98e",
28
28
  "@kubernetes/client-node": "^0.16.2",
29
29
  "@tsconfig/node14": "^1.0.1",
30
30
  "@types/common-tags": "^1.8.0",
@@ -57,6 +57,6 @@
57
57
  "typescript": "^4.5.4",
58
58
  "vorpal": "^1.12.0"
59
59
  },
60
- "version": "0.0.0-refactor-env-context-76787e25",
60
+ "version": "0.0.0-refactor-needs-c896b98e",
61
61
  "stableVersion": "0.0.0"
62
62
  }
@@ -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,154 @@
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 or 'local')? 🤔 ",
40
+ });
41
+
42
+ let sourceProxy: { stop: () => void };
43
+
44
+ let targetProxy: { stop: () => void };
45
+
46
+ let sourcePort: number;
47
+ let targetPort: number;
48
+
49
+ if (sourceInstance === "local") {
50
+ const { sourceLocalPort } = await this.prompt({
51
+ type: "number",
52
+ name: "sourceLocalPort",
53
+ default: 5432,
54
+
55
+ message: "Local Port for source? 🤔 ",
56
+ });
57
+ sourcePort = sourceLocalPort;
58
+ } else {
59
+ sourcePort = 54399;
60
+ sourceProxy = await createProxy(sourceInstance, sourcePort);
61
+ }
62
+
63
+ const { sourcePassword } = await this.prompt({
64
+ type: "input",
65
+ name: "sourcePassword",
66
+
67
+ message: "Source Password? 🤔 ",
68
+ });
69
+
70
+ const { sourceDbName } = await this.prompt({
71
+ type: "input",
72
+ name: "sourceDbName",
73
+
74
+ message: "Source DB name? 🤔 ",
75
+ });
76
+
77
+ const { targetInstance } = await this.prompt({
78
+ type: "input",
79
+ name: "targetInstance",
80
+
81
+ message: "Targe INSTANCE (connection string or 'local')? 🤔 ",
82
+ });
83
+
84
+ if (targetInstance === "local") {
85
+ const { targetLocalPort } = await this.prompt({
86
+ type: "number",
87
+ name: "targetLocalPort",
88
+ default: 5432,
89
+
90
+ message: "Local Port for target? 🤔 ",
91
+ });
92
+ targetPort = targetLocalPort;
93
+ } else {
94
+ targetPort = 54499;
95
+ targetProxy = await createProxy(targetInstance, targetPort);
96
+ }
97
+
98
+ const { targetPassword } = await this.prompt({
99
+ type: "input",
100
+ name: "targetPassword",
101
+
102
+ message: "Target Password? 🤔 ",
103
+ });
104
+
105
+ const { targetDbName } = await this.prompt({
106
+ type: "input",
107
+ name: "targetDbName",
108
+
109
+ message: "Target DB name? 🤔 ",
110
+ });
111
+
112
+ const { shouldContinue } = await this.prompt({
113
+ type: "confirm",
114
+ name: "shouldContinue",
115
+ message: `This will drop ${targetInstance}/${targetDbName} and replace it with ${sourceInstance}/${sourceDbName}. Continue? 🤔 `,
116
+ });
117
+
118
+ if (!shouldContinue) {
119
+ return;
120
+ }
121
+
122
+ const targetPSQL = (command: string) =>
123
+ `PGPASSWORD=${targetPassword} psql -p ${targetPort} --host=localhost --user=postgres -q ${command}`;
124
+
125
+ const copyDBScript = `
126
+ set -e
127
+
128
+
129
+
130
+ dumptmp=$(mktemp /tmp/dump.XXXXXX)
131
+
132
+ echo "Dumping file to $dumptmp"
133
+ pg_dump --dbname=postgres://postgres:${sourcePassword}@localhost:${sourcePort}/${sourceDbName} --no-owner --no-privileges > $dumptmp
134
+ echo "dump done"
135
+ ${targetPSQL(
136
+ `-c 'drop database "${targetDbName}" WITH (FORCE)' 1> /dev/null || true`
137
+ )}
138
+ ${targetPSQL(`-c 'create database "${targetDbName}"' 1> /dev/null`)}
139
+ echo "Restoring dump..."
140
+ ${targetPSQL(`"${targetDbName}" < $dumptmp 1> /dev/null`)}
141
+
142
+
143
+ echo "Clean up..."
144
+ set +e
145
+ rm $dumptmp
146
+ echo "\n🐱 Done!"
147
+ `;
148
+ try {
149
+ await spawn(copyDBScript, [], { shell: "bash", stdio: "inherit" });
150
+ } finally {
151
+ sourceProxy?.stop();
152
+ targetProxy?.stop();
153
+ }
154
+ });
@@ -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,3 +1,4 @@
1
+ import type { Context } from "@catladder/pipeline";
1
2
  import { isOfDeployType } from "@catladder/pipeline";
2
3
  import { spawn } from "child-process-promise";
3
4
  import { writeFile } from "fs-extra";
@@ -7,11 +8,15 @@ import {
7
8
  getEnvVars,
8
9
  getGitlabVar,
9
10
  getPipelineContextByChoice,
10
- getProjectConfig,
11
11
  parseChoice,
12
12
  } from "../../../../config/getProjectConfig";
13
13
  import { envAndComponents } from "./utils/autocompletions";
14
14
 
15
+ type ProxyInfo = {
16
+ instanceName: string;
17
+ DB_NAME: string;
18
+ DB_PASSWORD: string;
19
+ };
15
20
  export default async (vorpal: Vorpal) =>
16
21
  vorpal
17
22
  .command("project-cloud-sql-proxy <envComponent>", "proxy to cloud sql db")
@@ -19,9 +24,26 @@ export default async (vorpal: Vorpal) =>
19
24
  .action(async function ({ envComponent }) {
20
25
  const { env, componentName } = parseChoice(envComponent);
21
26
 
22
- const config = await getProjectConfig();
23
- // skynet-164509:europe-west6:pvl-cyclomania-review=tcp:5432
27
+ const context = await getPipelineContextByChoice(env, componentName);
28
+ let proxyInfo: ProxyInfo;
29
+
30
+ if (env === "review") {
31
+ vorpal.log(
32
+ "⚠️ connection string does not include mr information on review environments"
33
+ );
34
+ }
35
+ if (isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
36
+ proxyInfo = await getProxyInfoForKubernetes(context);
37
+ } else if (
38
+ isOfDeployType(context.componentConfig.deploy, "google-cloudrun")
39
+ ) {
40
+ proxyInfo = await getProxyInfoForCloudRun(context);
41
+ } else {
42
+ throw new Error("unsupported environment");
43
+ }
24
44
 
45
+ // skynet-164509:europe-west6:pvl-cyclomania-review=tcp:5432
46
+ const { DB_PASSWORD, DB_NAME, instanceName } = proxyInfo;
25
47
  const { localPort } = await this.prompt({
26
48
  type: "number",
27
49
  name: "localPort",
@@ -29,35 +51,16 @@ export default async (vorpal: Vorpal) =>
29
51
  message: "Local port: ",
30
52
  });
31
53
 
32
- const envVars = await getEnvVars(this, env, componentName);
33
- const POSTGRESQL_PASSWORD = envVars?.POSTGRESQL_PASSWORD;
34
-
35
- const context = await getPipelineContextByChoice(env, componentName);
36
- if (!isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
37
- throw new Error("currently only supported for kubernetes deployment");
38
- }
39
54
  this.log("");
40
- this.log(`postgres-PW: ${POSTGRESQL_PASSWORD}`);
55
+ this.log(`postgres-PW: ${DB_PASSWORD}`);
41
56
  this.log("");
42
57
  this.log(
43
- `POSTGRESQL_URL=postgresql://postgres:${POSTGRESQL_PASSWORD}@localhost:${localPort}/${context.environment.envVars.KUBE_APP_NAME}?schema=public`
58
+ `POSTGRESQL_URL=postgresql://postgres:${DB_PASSWORD}@localhost:${localPort}/${DB_NAME}?schema=public`
44
59
  );
45
60
  this.log("");
46
61
 
47
- const values = context.componentConfig.deploy.values;
48
-
49
- const projectId =
50
- values?.cloudsql?.projectId ||
51
- context.componentConfig.deploy.cluster?.projectId;
52
-
53
- const defaultInstanceId = `${config.customerName}-${config.appName}-${env}`;
54
- const instanceId = values?.cloudsql?.instanceId || defaultInstanceId;
55
-
56
- const defaultRegion = "europe-west6"; // currently hardcoded
57
- const region = values?.cloudsql?.region || defaultRegion;
58
-
59
- const instanceName = `${projectId}:${region}:${instanceId}=tcp:${localPort}`;
60
-
62
+ // legacy, some projects have the cloudsqlProxyCredentials in the secrets
63
+ // actually it works without, if the current local shell user has access to the db through google cloud
61
64
  const cloudsqlProxyCredentials = await getGitlabVar(
62
65
  this,
63
66
  env,
@@ -65,20 +68,20 @@ export default async (vorpal: Vorpal) =>
65
68
  "cloudsqlProxyCredentials"
66
69
  );
67
70
 
68
- if (!cloudsqlProxyCredentials) {
69
- // we store cloudsqlProxyCredentials on gitlab, but its currently get pushed via bitwarden due to legacy reasons
70
- // this will be fixed with when https://git.panter.ch/catladder/catladder/-/merge_requests/32/ is merged
71
- this.log(
72
- "cloudsqlProxyCredentials env var missing in gitlab. Please contact gilde-ci-cd about that."
73
- );
74
- throw new Error("cloudsqlProxyCredentials missing in secrets");
75
- }
76
71
  await withFile(async ({ path: tmpFilePath }) => {
77
- await writeFile(tmpFilePath, cloudsqlProxyCredentials);
72
+ if (cloudsqlProxyCredentials) {
73
+ await writeFile(tmpFilePath, cloudsqlProxyCredentials);
74
+ }
78
75
 
79
76
  await spawn(
80
77
  "cloud_sql_proxy",
81
- ["-instances", instanceName, "-credential_file", tmpFilePath],
78
+ [
79
+ "-instances",
80
+ `${instanceName}=tcp:${localPort}`,
81
+ ...(cloudsqlProxyCredentials
82
+ ? ["-credential_file", tmpFilePath]
83
+ : []),
84
+ ],
82
85
  {
83
86
  stdio: "inherit",
84
87
  shell: true,
@@ -86,3 +89,69 @@ export default async (vorpal: Vorpal) =>
86
89
  );
87
90
  });
88
91
  });
92
+
93
+ const getProxyInfoForKubernetes = async (
94
+ context: Context
95
+ ): Promise<ProxyInfo> => {
96
+ if (!isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
97
+ throw new Error("unsupported");
98
+ }
99
+
100
+ const envVars = await getEnvVars(
101
+ this,
102
+ context.environment.shortName,
103
+ context.componentName
104
+ );
105
+
106
+ const DB_PASSWORD = envVars?.DB_PASSWORD || envVars?.POSTGRESQL_PASSWORD;
107
+
108
+ const DB_NAME = context.environment.envVars.KUBE_APP_NAME;
109
+
110
+ const values = context.componentConfig.deploy.values;
111
+
112
+ const projectId =
113
+ values?.cloudsql?.projectId ||
114
+ context.componentConfig.deploy.cluster?.projectId;
115
+
116
+ const defaultInstanceId = `${context.fullConfig.customerName}-${context.fullConfig.appName}-${context.environment.shortName}`;
117
+ const instanceId = values?.cloudsql?.instanceId || defaultInstanceId;
118
+
119
+ const defaultRegion = "europe-west6"; // currently hardcoded
120
+ const region = values?.cloudsql?.region || defaultRegion;
121
+
122
+ const instanceName = `${projectId}:${region}:${instanceId}`;
123
+
124
+ return {
125
+ instanceName,
126
+ DB_PASSWORD,
127
+ DB_NAME,
128
+ };
129
+ };
130
+
131
+ const getProxyInfoForCloudRun = async (
132
+ context: Context
133
+ ): Promise<ProxyInfo> => {
134
+ if (
135
+ !isOfDeployType(context.componentConfig.deploy, "google-cloudrun") ||
136
+ !context.componentConfig.deploy.cloudSql
137
+ ) {
138
+ throw new Error("unsupported");
139
+ }
140
+
141
+ const envVars = await getEnvVars(
142
+ this,
143
+ context.environment.shortName,
144
+ context.componentName
145
+ );
146
+
147
+ const DB_PASSWORD = envVars?.DB_PASSWORD;
148
+
149
+ const DB_NAME = context.environment.envVars.DB_NAME;
150
+
151
+ return {
152
+ instanceName:
153
+ context.componentConfig.deploy.cloudSql.instanceConnectionName,
154
+ DB_PASSWORD,
155
+ DB_NAME,
156
+ };
157
+ };
@@ -8,7 +8,7 @@ export default async (vorpal: Vorpal) =>
8
8
  "show the total worktime that you spent on a project"
9
9
  )
10
10
  .action(async () => {
11
- await spawn("sh", ["-c", "curl -L http://bit.ly/10hA8iC | bash"], {
11
+ await spawn("sh", ["-c", "curl -s -L http://bit.ly/3VQEKNq | bash"], {
12
12
  stdio: ["pipe", "inherit", "pipe"],
13
13
  });
14
14
  });
@@ -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);
@@ -26,7 +26,15 @@ export const setupCloudRun = async (
26
26
 
27
27
  instance.log("enable required servies...");
28
28
  await enableGCloudServices(
29
- ["run.googleapis.com", "artifactregistry.googleapis.com"],
29
+ [
30
+ "run.googleapis.com",
31
+ "artifactregistry.googleapis.com",
32
+ "cloudscheduler.googleapis.com", // for scheduling jobs
33
+ "cloudresourcemanager.googleapis.com", // only required to get google cloud project number
34
+ ...(config.cloudSql
35
+ ? ["sqladmin.googleapis.com", "sql-component.googleapis.com"]
36
+ : []),
37
+ ],
30
38
  config
31
39
  );
32
40
  instance.log("upsert artifacts registry...");
@@ -46,6 +54,8 @@ export const setupCloudRun = async (
46
54
  "roles/artifactregistry.repoAdmin",
47
55
  "roles/run.admin",
48
56
  "roles/iam.serviceAccountUser",
57
+ "roles/cloudscheduler.admin", // for scheduling
58
+ ...(config.cloudSql ? ["roles/cloudsql.admin"] : []),
49
59
  ],
50
60
  },
51
61
  GCLOUD_DEPLOY_CREDENTIALS_KEY
@@ -1,15 +1,18 @@
1
1
  import type { Context } from "@catladder/pipeline";
2
- import { getCloudSQLConfig, hasCloudSQL } from "@catladder/pipeline";
2
+ import {
3
+ getKubernetesCloudSQLConfig,
4
+ hasKubernetesCloudSQL,
5
+ } from "@catladder/pipeline";
3
6
  import type { CommandInstance } from "vorpal";
4
7
 
5
8
  export const setupCloudSQL = async (
6
9
  instance: CommandInstance,
7
10
  context: Context
8
11
  ) => {
9
- if (!hasCloudSQL(context)) {
12
+ if (!hasKubernetesCloudSQL(context)) {
10
13
  throw new Error("cannot setup cloudsql, as it has none");
11
14
  }
12
- const config = getCloudSQLConfig(context);
15
+ const config = getKubernetesCloudSQLConfig(context);
13
16
  instance.log("");
14
17
  instance.log(
15
18
  "! make sure to provide cloudsqlProxyCredentials for the cloud sql service account in " +
@@ -1,5 +1,5 @@
1
1
  import type { Context } from "@catladder/pipeline";
2
- import { isOfDeployType, hasCloudSQL } from "@catladder/pipeline";
2
+ import { isOfDeployType, hasKubernetesCloudSQL } from "@catladder/pipeline";
3
3
  import type { CommandInstance } from "vorpal";
4
4
  import { setupCloudRun } from "./setupCloudRun";
5
5
  import { setupCloudSQL } from "./setupCloudSQL";
@@ -25,7 +25,7 @@ export const setupContext = async (
25
25
  if (isOfDeployType(context.componentConfig.deploy, "google-cloudrun")) {
26
26
  await setupCloudRun(instance, context);
27
27
  }
28
- if (hasCloudSQL(context)) {
28
+ if (hasKubernetesCloudSQL(context)) {
29
29
  await setupCloudSQL(instance, context);
30
30
  }
31
31
 
@@ -19,7 +19,7 @@ export default async (vorpal: Vorpal) => {
19
19
  vorpal
20
20
  .command("starwars", "Long time ago... in a galaxy far far away...")
21
21
  .action(async function () {
22
- starwarsPromise = spawn("telnet", ["towel.blinkenlights.nl"], {
22
+ starwarsPromise = spawn("telnet", ["2001:7b8:666:ffff::1:42"], {
23
23
  stdio: ["pipe", "inherit", "pipe"],
24
24
  });
25
25
  await starwarsPromise;
@@ -36,6 +36,7 @@ export const LEGACY_ENVS = [
36
36
 
37
37
  const arrayToRecord = (arr: { name: string }[]): Record<string, any> => {
38
38
  if (!arr) return undefined;
39
+ if (!Array.isArray(arr)) return arr;
39
40
  return Object.fromEntries(arr.map(({ name, ...rest }) => [name, rest]));
40
41
  };
41
42
 
@@ -43,6 +43,6 @@ export const detectBuildConfig = (
43
43
  }
44
44
 
45
45
  if (firstInclude.file === "rails-kubernetes.yml") {
46
- throw new Error("rails is not yet implemented");
46
+ return "rails";
47
47
  }
48
48
  };
@@ -150,8 +150,13 @@ export const getEnvVars = async (
150
150
  env: string,
151
151
  componentName: string
152
152
  ) => {
153
- const envionment = await getEnvironment(env, componentName);
154
- // in the pipeline the secrets alreadyy exists and bash will expand them
155
- // but here we need to manually load them
156
- return resolveSecrets(vorpal, envionment.envVars);
153
+ try {
154
+ const envionment = await getEnvironment(env, componentName);
155
+ // in the pipeline the secrets alreadyy exists and bash will expand them
156
+ // but here we need to manually load them
157
+ return resolveSecrets(vorpal, envionment.envVars);
158
+ } catch (e) {
159
+ // env is disabled
160
+ return {};
161
+ }
157
162
  };
@@ -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
- });