@catladder/cli 1.59.0 → 1.61.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/dist/apps/cli/commands/project/commandCloudSqlProxy.js +106 -45
- package/dist/apps/cli/commands/project/commandCloudSqlProxy.js.map +1 -1
- package/dist/apps/cli/commands/project/setup/setupCloudRun.js +18 -4
- package/dist/apps/cli/commands/project/setup/setupCloudRun.js.map +1 -1
- package/dist/apps/cli/commands/project/setup/setupCloudSQL.js +2 -2
- package/dist/apps/cli/commands/project/setup/setupCloudSQL.js.map +1 -1
- package/dist/apps/cli/commands/project/setup/setupContext.js +1 -1
- package/dist/apps/cli/commands/project/setup/setupContext.js.map +1 -1
- package/dist/bundles/catenv/index.js +3 -3
- package/dist/bundles/cli/index.js +2 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/apps/cli/commands/project/commandCloudSqlProxy.ts +105 -36
- package/src/apps/cli/commands/project/setup/setupCloudRun.ts +8 -1
- package/src/apps/cli/commands/project/setup/setupCloudSQL.ts +6 -3
- package/src/apps/cli/commands/project/setup/setupContext.ts +2 -2
package/package.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"node": ">=12.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@catladder/pipeline": "1.
|
|
27
|
+
"@catladder/pipeline": "1.61.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.
|
|
60
|
+
"version": "1.61.0"
|
|
61
61
|
}
|
|
@@ -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
|
|
23
|
-
|
|
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: ${
|
|
55
|
+
this.log(`postgres-PW: ${DB_PASSWORD}`);
|
|
41
56
|
this.log("");
|
|
42
57
|
this.log(
|
|
43
|
-
`POSTGRESQL_URL=postgresql://postgres:${
|
|
58
|
+
`POSTGRESQL_URL=postgresql://postgres:${DB_PASSWORD}@localhost:${localPort}/${DB_NAME}?schema=public`
|
|
44
59
|
);
|
|
45
60
|
this.log("");
|
|
46
61
|
|
|
47
|
-
|
|
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
|
-
|
|
72
|
+
if (cloudsqlProxyCredentials) {
|
|
73
|
+
await writeFile(tmpFilePath, cloudsqlProxyCredentials);
|
|
74
|
+
}
|
|
78
75
|
|
|
79
76
|
await spawn(
|
|
80
77
|
"cloud_sql_proxy",
|
|
81
|
-
[
|
|
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
|
+
};
|
|
@@ -26,7 +26,13 @@ export const setupCloudRun = async (
|
|
|
26
26
|
|
|
27
27
|
instance.log("enable required servies...");
|
|
28
28
|
await enableGCloudServices(
|
|
29
|
-
[
|
|
29
|
+
[
|
|
30
|
+
"run.googleapis.com",
|
|
31
|
+
"artifactregistry.googleapis.com",
|
|
32
|
+
...(config.cloudSql
|
|
33
|
+
? ["sqladmin.googleapis.com", "sql-component.googleapis.com"]
|
|
34
|
+
: []),
|
|
35
|
+
],
|
|
30
36
|
config
|
|
31
37
|
);
|
|
32
38
|
instance.log("upsert artifacts registry...");
|
|
@@ -46,6 +52,7 @@ export const setupCloudRun = async (
|
|
|
46
52
|
"roles/artifactregistry.repoAdmin",
|
|
47
53
|
"roles/run.admin",
|
|
48
54
|
"roles/iam.serviceAccountUser",
|
|
55
|
+
...(config.cloudSql ? ["roles/cloudsql.admin"] : []),
|
|
49
56
|
],
|
|
50
57
|
},
|
|
51
58
|
GCLOUD_DEPLOY_CREDENTIALS_KEY
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import type { Context } from "@catladder/pipeline";
|
|
2
|
-
import {
|
|
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 (!
|
|
12
|
+
if (!hasKubernetesCloudSQL(context)) {
|
|
10
13
|
throw new Error("cannot setup cloudsql, as it has none");
|
|
11
14
|
}
|
|
12
|
-
const config =
|
|
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,
|
|
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 (
|
|
28
|
+
if (hasKubernetesCloudSQL(context)) {
|
|
29
29
|
await setupCloudSQL(instance, context);
|
|
30
30
|
}
|
|
31
31
|
|