@catladder/cli 0.0.0-main-3b6d4049 → 0.0.0-main-5f142cf2
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/catenv/catenv.js +15 -12
- package/dist/apps/catenv/catenv.js.map +1 -1
- package/dist/apps/shell/commands/mongodb/projectMongoDestroyMember.js +6 -6
- package/dist/apps/shell/commands/mongodb/projectMongoDestroyMember.js.map +1 -1
- package/dist/apps/shell/commands/mongodb/projectMongoGetShell.js +6 -6
- package/dist/apps/shell/commands/mongodb/projectMongoGetShell.js.map +1 -1
- package/dist/apps/shell/commands/mongodb/projectMongoPortForward.js +5 -5
- package/dist/apps/shell/commands/mongodb/projectMongoPortForward.js.map +1 -1
- package/dist/apps/shell/commands/mongodb/utils/index.d.ts +3 -4
- package/dist/apps/shell/commands/mongodb/utils/index.js +6 -6
- package/dist/apps/shell/commands/mongodb/utils/index.js.map +1 -1
- package/dist/apps/shell/commands/project/commandCloudSqlProxy.js +10 -7
- package/dist/apps/shell/commands/project/commandCloudSqlProxy.js.map +1 -1
- package/dist/apps/shell/commands/project/commandConfigSecrets.js +46 -176
- package/dist/apps/shell/commands/project/commandConfigSecrets.js.map +1 -1
- package/dist/apps/shell/commands/project/commandCopyDB.js +1 -1
- package/dist/apps/shell/commands/project/commandCopyDB.js.map +1 -1
- package/dist/apps/shell/commands/project/commandDeletePods.js +5 -5
- package/dist/apps/shell/commands/project/commandDeletePods.js.map +1 -1
- package/dist/apps/shell/commands/project/commandDeleteProject.js +3 -3
- package/dist/apps/shell/commands/project/commandDeleteProject.js.map +1 -1
- package/dist/apps/shell/commands/project/commandGetShell.js +6 -6
- package/dist/apps/shell/commands/project/commandGetShell.js.map +1 -1
- package/dist/apps/shell/commands/project/commandInitGitlab.js +64 -38
- package/dist/apps/shell/commands/project/commandInitGitlab.js.map +1 -1
- package/dist/apps/shell/commands/project/commandInitProject.js +138 -129
- package/dist/apps/shell/commands/project/commandInitProject.js.map +1 -1
- package/dist/apps/shell/commands/project/commandListPods.js +5 -5
- package/dist/apps/shell/commands/project/commandListPods.js.map +1 -1
- package/dist/apps/shell/commands/project/commandMigrateHelm3.js +1 -1
- package/dist/apps/shell/commands/project/commandMigrateHelm3.js.map +1 -1
- package/dist/apps/shell/commands/project/commandNamespace.js +3 -3
- package/dist/apps/shell/commands/project/commandNamespace.js.map +1 -1
- package/dist/apps/shell/commands/project/commandOpenCostDashboard.js +4 -4
- package/dist/apps/shell/commands/project/commandOpenCostDashboard.js.map +1 -1
- package/dist/apps/shell/commands/project/commandOpenDashboard.js +11 -5
- package/dist/apps/shell/commands/project/commandOpenDashboard.js.map +1 -1
- package/dist/apps/shell/commands/project/commandOpenEnv.js +1 -1
- package/dist/apps/shell/commands/project/commandOpenEnv.js.map +1 -1
- package/dist/apps/shell/commands/project/commandOpenGrafana.js +4 -4
- package/dist/apps/shell/commands/project/commandOpenGrafana.js.map +1 -1
- package/dist/apps/shell/commands/project/commandOpenGrafanaPod.js +5 -5
- package/dist/apps/shell/commands/project/commandOpenGrafanaPod.js.map +1 -1
- package/dist/apps/shell/commands/project/commandOpenLogs.js +4 -4
- package/dist/apps/shell/commands/project/commandOpenLogs.js.map +1 -1
- package/dist/apps/shell/commands/project/commandPauseProject.js +3 -3
- package/dist/apps/shell/commands/project/commandPauseProject.js.map +1 -1
- package/dist/apps/shell/commands/project/commandPortForward.js +5 -5
- package/dist/apps/shell/commands/project/commandPortForward.js.map +1 -1
- package/dist/apps/shell/commands/project/commandTriggerCronjob.js +4 -4
- package/dist/apps/shell/commands/project/commandTriggerCronjob.js.map +1 -1
- package/dist/apps/shell/commands/project/index.js +0 -2
- package/dist/apps/shell/commands/project/index.js.map +1 -1
- package/dist/apps/shell/commands/project/utils/ensureCluster.d.ts +1 -1
- package/dist/apps/shell/commands/project/utils/ensureCluster.js +12 -10
- package/dist/apps/shell/commands/project/utils/ensureCluster.js.map +1 -1
- package/dist/apps/shell/commands/project/utils/ensureNamespace.d.ts +1 -2
- package/dist/apps/shell/commands/project/utils/ensureNamespace.js +2 -2
- package/dist/apps/shell/commands/project/utils/ensureNamespace.js.map +1 -1
- package/dist/config/getProjectConfig.d.ts +7 -4
- package/dist/config/getProjectConfig.js +35 -11
- package/dist/config/getProjectConfig.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/types.d.ts +0 -1
- package/dist/utils/cluster.d.ts +7 -0
- package/dist/utils/cluster.js +15 -3
- package/dist/utils/cluster.js.map +1 -1
- package/dist/utils/editAsFile.d.ts +1 -0
- package/dist/utils/editAsFile.js +22 -0
- package/dist/utils/editAsFile.js.map +1 -0
- package/dist/utils/gitlab.d.ts +2 -1
- package/dist/utils/gitlab.js +29 -3
- package/dist/utils/gitlab.js.map +1 -1
- package/dist/utils/projects/index.d.ts +4 -15
- package/dist/utils/projects/index.js +10 -78
- package/dist/utils/projects/index.js.map +1 -1
- package/package.json +1 -1
- package/src/apps/catenv/catenv.ts +36 -26
- package/src/apps/shell/commands/mongodb/projectMongoDestroyMember.ts +6 -6
- package/src/apps/shell/commands/mongodb/projectMongoGetShell.ts +9 -7
- package/src/apps/shell/commands/mongodb/projectMongoPortForward.ts +10 -5
- package/src/apps/shell/commands/mongodb/utils/index.ts +9 -8
- package/src/apps/shell/commands/project/commandCloudSqlProxy.ts +14 -7
- package/src/apps/shell/commands/project/commandConfigSecrets.ts +37 -172
- package/src/apps/shell/commands/project/commandCopyDB.ts +2 -1
- package/src/apps/shell/commands/project/commandDeletePods.ts +5 -6
- package/src/apps/shell/commands/project/commandDeleteProject.ts +4 -5
- package/src/apps/shell/commands/project/commandGetShell.ts +7 -7
- package/src/apps/shell/commands/project/commandInitGitlab.ts +97 -51
- package/src/apps/shell/commands/project/commandInitProject.ts +8 -0
- package/src/apps/shell/commands/project/commandListPods.ts +5 -6
- package/src/apps/shell/commands/project/commandMigrateHelm3.ts +1 -1
- package/src/apps/shell/commands/project/commandNamespace.ts +6 -4
- package/src/apps/shell/commands/project/commandOpenCostDashboard.ts +7 -4
- package/src/apps/shell/commands/project/commandOpenDashboard.ts +18 -6
- package/src/apps/shell/commands/project/commandOpenEnv.ts +1 -1
- package/src/apps/shell/commands/project/commandOpenGrafana.ts +4 -4
- package/src/apps/shell/commands/project/commandOpenGrafanaPod.ts +5 -5
- package/src/apps/shell/commands/project/commandOpenLogs.ts +4 -4
- package/src/apps/shell/commands/project/commandPauseProject.ts +6 -4
- package/src/apps/shell/commands/project/commandPortForward.ts +5 -5
- package/src/apps/shell/commands/project/commandTriggerCronjob.ts +4 -4
- package/src/apps/shell/commands/project/index.ts +1 -2
- package/src/apps/shell/commands/project/utils/ensureCluster.ts +12 -10
- package/src/apps/shell/commands/project/utils/ensureNamespace.ts +2 -3
- package/src/config/getProjectConfig.ts +40 -11
- package/src/types/types.ts +0 -2
- package/src/utils/cluster.ts +15 -2
- package/src/utils/editAsFile.ts +21 -0
- package/src/utils/gitlab.ts +56 -4
- package/src/utils/projects/index.ts +10 -93
- package/dist/apps/shell/commands/project/commandVariables.d.ts +0 -3
- package/dist/apps/shell/commands/project/commandVariables.js +0 -16
- package/dist/apps/shell/commands/project/commandVariables.js.map +0 -1
- package/dist/apps/shell/commands/project/utils/monorepo.d.ts +0 -10
- package/dist/apps/shell/commands/project/utils/monorepo.js +0 -25
- package/dist/apps/shell/commands/project/utils/monorepo.js.map +0 -1
- package/src/apps/shell/commands/project/commandVariables.ts +0 -13
- package/src/apps/shell/commands/project/utils/monorepo.ts +0 -23
|
@@ -1,27 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import { difference, mapValues, pick } from "lodash";
|
|
1
|
+
/* eslint-disable no-constant-condition */
|
|
2
|
+
import { difference } from "lodash";
|
|
4
3
|
import Vorpal from "vorpal";
|
|
5
|
-
import { GOOGLE_CLOUD_SQL_PASS_PATH } from "../../../../config/constants";
|
|
6
|
-
import k8sApi from "../../../../k8sApi";
|
|
7
|
-
import { ISecrets } from "../../../../types/types";
|
|
8
|
-
import { logError } from "../../../../utils/log";
|
|
9
|
-
import {
|
|
10
|
-
editPass,
|
|
11
|
-
insertPass,
|
|
12
|
-
readPass,
|
|
13
|
-
readPassEnvVars,
|
|
14
|
-
syncBitwarden,
|
|
15
|
-
} from "../../../../utils/passwordstore";
|
|
16
4
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} from "../../../../
|
|
5
|
+
getEnvironmentByChoice,
|
|
6
|
+
getEnvVars,
|
|
7
|
+
parseChoice,
|
|
8
|
+
} from "../../../../config/getProjectConfig";
|
|
9
|
+
import { ISecrets } from "../../../../types/types";
|
|
10
|
+
import { editAsFile } from "../../../../utils/editAsFile";
|
|
11
|
+
import { upsertAllVariables } from "../../../../utils/gitlab";
|
|
21
12
|
import { delay } from "../../../../utils/promise";
|
|
22
13
|
import { envAutocompletion } from "./utils/autocompletions";
|
|
23
|
-
import ensureCluster from "./utils/ensureCluster";
|
|
24
|
-
import ensureNamespace from "./utils/ensureNamespace";
|
|
25
14
|
|
|
26
15
|
export default (vorpal: Vorpal) => {
|
|
27
16
|
vorpal
|
|
@@ -31,86 +20,37 @@ export default (vorpal: Vorpal) => {
|
|
|
31
20
|
)
|
|
32
21
|
.autocomplete(envAutocompletion)
|
|
33
22
|
.action(async function ({ envComponent }) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const passPath = await getPassPath(env);
|
|
41
|
-
this.log("");
|
|
42
|
-
this.log(`😼 I will now open bitwarden @ '${passPath}'`);
|
|
43
|
-
this.log("");
|
|
44
|
-
|
|
45
|
-
const subapp = await promptForSubAppIfAny(this);
|
|
46
|
-
|
|
47
|
-
const secretEnvVarsMapping = await getAllSecretsEnvVarsMapping(
|
|
48
|
-
env,
|
|
49
|
-
subapp
|
|
23
|
+
const { secretEnvVarKeys } = await getEnvironmentByChoice(envComponent);
|
|
24
|
+
const { env, componentName } = parseChoice(envComponent);
|
|
25
|
+
const allEnvVars = await getEnvVars(this, envComponent);
|
|
26
|
+
let valuesToEdit = Object.fromEntries(
|
|
27
|
+
secretEnvVarKeys.map((key) => [key, allEnvVars[key]])
|
|
50
28
|
);
|
|
51
29
|
|
|
52
|
-
await syncBitwarden();
|
|
53
|
-
|
|
54
|
-
// check if exist and fill in details if not
|
|
55
|
-
try {
|
|
56
|
-
await readPass(passPath);
|
|
57
|
-
} catch (e) {
|
|
58
|
-
// does not exist. create it
|
|
59
|
-
await createNewEnvInPass.call(this, env, secretEnvVarsMapping);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
let envConfigInPass: any = null;
|
|
63
|
-
// eslint-disable-next-line no-constant-condition
|
|
64
30
|
while (true) {
|
|
65
|
-
|
|
66
|
-
await editPass(passPath);
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
envConfigInPass = await readPassEnvVars(passPath);
|
|
31
|
+
const hasError = false;
|
|
70
32
|
|
|
71
|
-
|
|
33
|
+
valuesToEdit = await editAsFile(valuesToEdit);
|
|
34
|
+
const usedKeys = valuesToEdit ? Object.keys(valuesToEdit) : [];
|
|
35
|
+
// check whether newValues have the exact number of keys
|
|
36
|
+
const extranous = difference(usedKeys, secretEnvVarKeys);
|
|
37
|
+
const missing = difference(secretEnvVarKeys, usedKeys);
|
|
72
38
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
allSecretEnvKeysInValues,
|
|
81
|
-
configuredKeysInPass
|
|
82
|
-
);
|
|
83
|
-
if (keysNotInValues.length > 0) {
|
|
84
|
-
this.log("");
|
|
85
|
-
this.log(
|
|
86
|
-
`☝️ Notice: the following keys are defined in pass, but not in values: ${keysNotInValues.join(
|
|
87
|
-
", "
|
|
88
|
-
)}`
|
|
89
|
-
);
|
|
90
|
-
this.log(
|
|
91
|
-
`These values are probably from another app that uses the same namespace.`
|
|
92
|
-
);
|
|
39
|
+
if (extranous.length > 0 || missing.length > 0) {
|
|
40
|
+
this.log("");
|
|
41
|
+
this.log("😿 Oh no! There is something wrong");
|
|
42
|
+
this.log("");
|
|
43
|
+
if (extranous.length > 0) {
|
|
44
|
+
this.log("these secrets are not declared in the config");
|
|
45
|
+
extranous.forEach((key) => this.log(key));
|
|
93
46
|
this.log("");
|
|
94
47
|
}
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
", "
|
|
100
|
-
)}`
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
hasError = true;
|
|
48
|
+
if (missing.length > 0) {
|
|
49
|
+
this.log("these secrets have not been provided:");
|
|
50
|
+
missing.forEach((key) => this.log(key));
|
|
51
|
+
this.log("");
|
|
104
52
|
}
|
|
105
|
-
} catch (e) {
|
|
106
|
-
await logError(this, "failed to parse yaml", e.message);
|
|
107
|
-
hasError = true;
|
|
108
|
-
}
|
|
109
53
|
|
|
110
|
-
if (hasError) {
|
|
111
|
-
this.log("");
|
|
112
|
-
this.log("🤦 You miserably failed to provide something useful 💩");
|
|
113
|
-
this.log("");
|
|
114
54
|
await delay(1000);
|
|
115
55
|
const { shouldContinue } = await this.prompt({
|
|
116
56
|
default: true,
|
|
@@ -123,56 +63,15 @@ export default (vorpal: Vorpal) => {
|
|
|
123
63
|
throw new Error("abort");
|
|
124
64
|
}
|
|
125
65
|
} else {
|
|
66
|
+
await upsertAllVariables(this, valuesToEdit, env, componentName);
|
|
67
|
+
|
|
126
68
|
break;
|
|
127
69
|
}
|
|
128
70
|
}
|
|
129
71
|
|
|
130
|
-
|
|
131
|
-
await ensureNamespace.call(this, env);
|
|
132
|
-
|
|
133
|
-
this.log(
|
|
134
|
-
"😼 Please be patient while i am doing some complicated stuff... "
|
|
135
|
-
);
|
|
136
|
-
const namespace = await getProjectNamespace(env);
|
|
137
|
-
|
|
138
|
-
// secrets is object of [key]: secretName
|
|
139
|
-
const grouped = Object.keys(secretEnvVarsMapping).reduce<{
|
|
140
|
-
[secretName: string]: string[];
|
|
141
|
-
}>((acc, key) => {
|
|
142
|
-
const secretName = secretEnvVarsMapping[key];
|
|
143
|
-
return {
|
|
144
|
-
...acc,
|
|
145
|
-
[secretName]: [...(acc[secretName] || []), key],
|
|
146
|
-
};
|
|
147
|
-
}, {});
|
|
148
|
-
|
|
149
|
-
for (const secretName of Object.keys(grouped)) {
|
|
150
|
-
const valueKeysInGroup = grouped[secretName];
|
|
151
|
-
const valuesFromPassInGroup = pick(envConfigInPass, valueKeysInGroup);
|
|
152
|
-
|
|
153
|
-
let existingSecretValues = {};
|
|
154
|
-
try {
|
|
155
|
-
const existingSecretResult = await k8sApi.readNamespacedSecret(
|
|
156
|
-
secretName,
|
|
157
|
-
namespace
|
|
158
|
-
);
|
|
159
|
-
// tslint:disable-next-line:no-console
|
|
160
|
-
if (existingSecretResult && existingSecretResult.body.data) {
|
|
161
|
-
existingSecretValues = existingSecretResult.body.data;
|
|
162
|
-
}
|
|
163
|
-
} catch (e) {
|
|
164
|
-
// ignore
|
|
165
|
-
}
|
|
166
|
-
await createKubernetesSecret.call(
|
|
167
|
-
this,
|
|
168
|
-
namespace,
|
|
169
|
-
secretName,
|
|
72
|
+
/*
|
|
170
73
|
|
|
171
|
-
|
|
172
|
-
existingSecretValues
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
this.log("");
|
|
74
|
+
|
|
176
75
|
// adding gcloud sql proxy secret
|
|
177
76
|
const cloudsqlCredentials = await readPass(GOOGLE_CLOUD_SQL_PASS_PATH);
|
|
178
77
|
await createKubernetesSecret.call(
|
|
@@ -198,33 +97,9 @@ export default (vorpal: Vorpal) => {
|
|
|
198
97
|
*/
|
|
199
98
|
});
|
|
200
99
|
};
|
|
201
|
-
async function createKubernetesSecret(
|
|
202
|
-
namespace: string,
|
|
203
|
-
secretName: string,
|
|
204
|
-
stringData: Pick<any, string>,
|
|
205
|
-
existingSecretValues?: Record<string, string>
|
|
206
|
-
) {
|
|
207
|
-
const secret = new V1Secret();
|
|
208
|
-
secret.metadata = {
|
|
209
|
-
name: secretName,
|
|
210
|
-
};
|
|
211
|
-
secret.data = existingSecretValues;
|
|
212
|
-
secret.stringData = stringData;
|
|
213
|
-
this.log(`😼 upserting secret '${secretName}' (push it real good!)`);
|
|
214
|
-
try {
|
|
215
|
-
await k8sApi.deleteNamespacedSecret(secretName, namespace, "true");
|
|
216
|
-
} catch (e) {
|
|
217
|
-
// ignore
|
|
218
|
-
}
|
|
219
|
-
try {
|
|
220
|
-
await k8sApi.createNamespacedSecret(namespace, secret);
|
|
221
|
-
} catch (e) {
|
|
222
|
-
logError(this, "error pushing secrets", e.body.message);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
100
|
|
|
226
101
|
async function createNewEnvInPass(env: any, secretEnvVarsMapping: ISecrets) {
|
|
227
|
-
const passPath = await getPassPath(env);
|
|
102
|
+
// const passPath = await getPassPath(env);
|
|
228
103
|
this.log(
|
|
229
104
|
"Your selected env is not yet in pass. Do you want to copy it from another env? "
|
|
230
105
|
);
|
|
@@ -235,15 +110,5 @@ async function createNewEnvInPass(env: any, secretEnvVarsMapping: ISecrets) {
|
|
|
235
110
|
choices: [...envAutocompletion.filter((e) => e !== env), noAnswer],
|
|
236
111
|
message: "Do you want to copy an env?",
|
|
237
112
|
});
|
|
238
|
-
|
|
239
|
-
await insertPass(
|
|
240
|
-
passPath,
|
|
241
|
-
yaml.safeDump(mapValues(secretEnvVarsMapping, (value, key) => "fillme"))
|
|
242
|
-
);
|
|
243
|
-
} else {
|
|
244
|
-
const sourceEnvPath = await getPassPath(sourceEnv);
|
|
245
|
-
const stdout = await readPass(sourceEnvPath);
|
|
246
|
-
|
|
247
|
-
await insertPass(passPath, stdout);
|
|
248
|
-
}
|
|
113
|
+
// TODO: reimplenent
|
|
249
114
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
getEnvVars,
|
|
9
9
|
getProjectConfig,
|
|
10
|
+
parseChoice,
|
|
10
11
|
} from "../../../../config/getProjectConfig";
|
|
11
12
|
import { readPass } from "../../../../utils/passwordstore";
|
|
12
13
|
import { envAutocompletion } from "./utils/autocompletions";
|
|
@@ -19,7 +20,7 @@ export default (vorpal: Vorpal) =>
|
|
|
19
20
|
)
|
|
20
21
|
.autocomplete(envAutocompletion)
|
|
21
22
|
.action(async function copyDB({ envComponent }) {
|
|
22
|
-
const
|
|
23
|
+
const { env, componentName } = parseChoice(envComponent);
|
|
23
24
|
const { customerName, appName } = getProjectConfig();
|
|
24
25
|
|
|
25
26
|
const { shouldContinue } = await this.prompt({
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { V1DeleteOptions } from "@kubernetes/client-node";
|
|
2
1
|
import Vorpal from "vorpal";
|
|
3
2
|
import k8sApi from "../../../../k8sApi";
|
|
4
3
|
|
|
@@ -12,12 +11,12 @@ import ensureCluster from "./utils/ensureCluster";
|
|
|
12
11
|
|
|
13
12
|
export default (vorpal: Vorpal) =>
|
|
14
13
|
vorpal
|
|
15
|
-
.command("project-delete-pods <
|
|
14
|
+
.command("project-delete-pods <envComponent>", "delete / restart pods")
|
|
16
15
|
.autocomplete(envAutocompletion)
|
|
17
|
-
.action(async function ({
|
|
18
|
-
await ensureCluster.call(this);
|
|
19
|
-
const namespace = await getProjectNamespace(
|
|
20
|
-
const podNames = await getProjectPodNames(
|
|
16
|
+
.action(async function ({ envComponent }) {
|
|
17
|
+
await ensureCluster.call(this, envComponent);
|
|
18
|
+
const namespace = await getProjectNamespace(envComponent);
|
|
19
|
+
const podNames = await getProjectPodNames(envComponent);
|
|
21
20
|
if (podNames.length === 0) {
|
|
22
21
|
logError(this, "sorry, no pods found");
|
|
23
22
|
return;
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import Vorpal from "vorpal";
|
|
2
|
-
import { exec
|
|
3
|
-
import { Env } from "../../../../types/types";
|
|
2
|
+
import { exec } from "child-process-promise";
|
|
4
3
|
import { getProjectNamespace } from "../../../../utils/projects";
|
|
5
4
|
import { envAutocompletion } from "./utils/autocompletions";
|
|
6
5
|
|
|
7
6
|
export default (vorpal: Vorpal) =>
|
|
8
7
|
vorpal
|
|
9
8
|
.command(
|
|
10
|
-
"project-delete <
|
|
9
|
+
"project-delete <envComponent>",
|
|
11
10
|
"deletes a environment of a project (it deletes the namespace)"
|
|
12
11
|
)
|
|
13
12
|
.autocomplete(envAutocompletion)
|
|
14
|
-
.action(async function ({
|
|
15
|
-
const namespace = await getProjectNamespace(
|
|
13
|
+
.action(async function ({ envComponent }) {
|
|
14
|
+
const namespace = await getProjectNamespace(envComponent);
|
|
16
15
|
const { shouldContinue } = await this.prompt({
|
|
17
16
|
type: "confirm",
|
|
18
17
|
name: "shouldContinue",
|
|
@@ -2,7 +2,7 @@ import Vorpal from "vorpal";
|
|
|
2
2
|
import { logError } from "../../../../utils/log";
|
|
3
3
|
import {
|
|
4
4
|
getProjectNamespace,
|
|
5
|
-
getProjectPodNames
|
|
5
|
+
getProjectPodNames,
|
|
6
6
|
} from "../../../../utils/projects";
|
|
7
7
|
import { getShell } from "../../../../utils/shell";
|
|
8
8
|
|
|
@@ -12,14 +12,14 @@ import ensureCluster from "./utils/ensureCluster";
|
|
|
12
12
|
export default (vorpal: Vorpal) =>
|
|
13
13
|
vorpal
|
|
14
14
|
.command(
|
|
15
|
-
"project-get-shell <
|
|
15
|
+
"project-get-shell <envComponent>",
|
|
16
16
|
"get a shell to a pod in the environment"
|
|
17
17
|
)
|
|
18
18
|
.autocomplete(envAutocompletion)
|
|
19
|
-
.action(async function({
|
|
20
|
-
await ensureCluster.call(this);
|
|
21
|
-
const namespace = await getProjectNamespace(
|
|
22
|
-
const podNames = await getProjectPodNames(
|
|
19
|
+
.action(async function ({ envComponent }) {
|
|
20
|
+
await ensureCluster.call(this, envComponent);
|
|
21
|
+
const namespace = await getProjectNamespace(envComponent);
|
|
22
|
+
const podNames = await getProjectPodNames(envComponent);
|
|
23
23
|
if (podNames.length === 0) {
|
|
24
24
|
logError(this, "sorry, no pods found");
|
|
25
25
|
return;
|
|
@@ -28,7 +28,7 @@ export default (vorpal: Vorpal) =>
|
|
|
28
28
|
type: "list",
|
|
29
29
|
name: "podName",
|
|
30
30
|
choices: podNames,
|
|
31
|
-
message: "Which pod? 🤔"
|
|
31
|
+
message: "Which pod? 🤔",
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
return getShell(namespace, podName);
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import { isOfDeployType } from "@catladder/pipeline";
|
|
1
2
|
import open from "open";
|
|
2
3
|
import Vorpal from "vorpal";
|
|
3
|
-
import {
|
|
4
|
-
import { doGitlabRequest, getProjectInfo } from "../../../../utils/gitlab";
|
|
5
|
-
import { readPass, syncBitwarden } from "../../../../utils/passwordstore/";
|
|
4
|
+
import { getAllPipelineContexts } from "../../../../config/getProjectConfig";
|
|
6
5
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from "../../../../utils/
|
|
6
|
+
getClusterByFullName,
|
|
7
|
+
getClusterByName,
|
|
8
|
+
} from "../../../../utils/cluster";
|
|
9
|
+
import { doGitlabRequest, getProjectInfo } from "../../../../utils/gitlab";
|
|
10
|
+
import { readPass } from "../../../../utils/passwordstore/";
|
|
11
|
+
import { getProjectNamespace } from "../../../../utils/projects";
|
|
10
12
|
|
|
11
13
|
export default (vorpal: Vorpal) =>
|
|
12
14
|
vorpal
|
|
@@ -18,67 +20,111 @@ export default (vorpal: Vorpal) =>
|
|
|
18
20
|
const { id: projectId, web_url: projectWebUrl } = await getProjectInfo(
|
|
19
21
|
this
|
|
20
22
|
);
|
|
21
|
-
await
|
|
22
|
-
const clusters = await doGitlabRequest(
|
|
23
|
+
const existingGitlabClusters = await doGitlabRequest<{ name: string }[]>(
|
|
23
24
|
this,
|
|
24
25
|
`projects/${projectId}/clusters`
|
|
25
26
|
);
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
const existingClusters = existingGitlabClusters.map(
|
|
29
|
+
(c: { name: string }) => {
|
|
30
|
+
const found = getClusterByFullName(c.name);
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
name: found ? found.name : null,
|
|
34
|
+
fullName: c.name,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
if (existingClusters.length === 0) {
|
|
28
40
|
this.log("");
|
|
29
41
|
this.log("there is no cluster on the current project?");
|
|
30
42
|
} else {
|
|
31
43
|
this.log("there are already these clusters on the gitlab: ");
|
|
32
44
|
this.log("");
|
|
33
|
-
|
|
45
|
+
existingClusters.forEach((cluster) =>
|
|
46
|
+
this.log(` - ${cluster.name || "unknown"} (${cluster.fullName})`)
|
|
47
|
+
);
|
|
34
48
|
}
|
|
35
49
|
|
|
36
50
|
this.log("");
|
|
37
|
-
this.log("your project specifies the following
|
|
51
|
+
this.log("your project specifies the following clusters:");
|
|
38
52
|
this.log("");
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
const allContext = getAllPipelineContexts();
|
|
54
|
+
const allDeployments = allContext.map((c) => c.componentConfig.deploy);
|
|
55
|
+
|
|
56
|
+
const configuredClusterNames = allDeployments.reduce<string[]>(
|
|
57
|
+
(acc, c) => {
|
|
58
|
+
if (
|
|
59
|
+
isOfDeployType(c, "kubernetes") &&
|
|
60
|
+
!acc.includes(c.cluster || "production")
|
|
61
|
+
) {
|
|
62
|
+
return [...acc, c.cluster || "production"];
|
|
63
|
+
}
|
|
64
|
+
return acc;
|
|
65
|
+
},
|
|
66
|
+
[]
|
|
67
|
+
);
|
|
68
|
+
const configuredClusters = configuredClusterNames.map((c) => ({
|
|
69
|
+
name: c,
|
|
70
|
+
config: getClusterByName(c),
|
|
71
|
+
}));
|
|
72
|
+
configuredClusters.forEach((cluster) =>
|
|
73
|
+
this.log(` - ${cluster.name || "unknown"} (${cluster.config.fullName})`)
|
|
74
|
+
);
|
|
47
75
|
this.log("");
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
name
|
|
51
|
-
|
|
52
|
-
|
|
76
|
+
|
|
77
|
+
const missingClusters = configuredClusters.filter(
|
|
78
|
+
(c) => !existingClusters.some((exist) => exist.name === c.name)
|
|
79
|
+
);
|
|
80
|
+
|
|
53
81
|
this.log("");
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
82
|
+
this.log("These clusters are not configured yet on gitlab:");
|
|
83
|
+
this.log("");
|
|
84
|
+
|
|
85
|
+
missingClusters.forEach((cluster) =>
|
|
86
|
+
this.log(` - ${cluster.name || "unknown"} (${cluster.config.fullName})`)
|
|
87
|
+
);
|
|
88
|
+
this.log("");
|
|
89
|
+
|
|
90
|
+
for (const cluster of missingClusters) {
|
|
91
|
+
this.log(`${cluster} (${cluster.config.fullName})`);
|
|
92
|
+
this.log("");
|
|
93
|
+
const { shouldContinue } = await this.prompt({
|
|
94
|
+
type: "confirm",
|
|
95
|
+
name: "shouldContinue",
|
|
96
|
+
message: "Should I add the this cluster ? 🤔 ",
|
|
97
|
+
});
|
|
98
|
+
this.log("");
|
|
99
|
+
if (shouldContinue) {
|
|
100
|
+
const { api_url, passCredentials } = cluster.config;
|
|
101
|
+
if (!api_url) {
|
|
102
|
+
throw new Error("no api_url on this cluster!");
|
|
103
|
+
}
|
|
104
|
+
if (!passCredentials) {
|
|
105
|
+
throw new Error("no passCredentials on this cluster!");
|
|
106
|
+
}
|
|
107
|
+
const token = await readPass(passCredentials.token);
|
|
108
|
+
const ca_cert = await readPass(passCredentials.ca_cert);
|
|
109
|
+
|
|
110
|
+
const postResult = await doGitlabRequest(
|
|
111
|
+
this,
|
|
112
|
+
`projects/${projectId}/clusters/user`,
|
|
113
|
+
{
|
|
114
|
+
name: cluster.config.fullName,
|
|
115
|
+
managed: false,
|
|
116
|
+
platform_kubernetes_attributes: {
|
|
117
|
+
api_url,
|
|
118
|
+
ca_cert,
|
|
119
|
+
token,
|
|
120
|
+
namespace: await getProjectNamespace("prod"),
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
const { message } = postResult;
|
|
125
|
+
if (message) {
|
|
126
|
+
this.log(`Message from gitlab: ${message}`);
|
|
77
127
|
}
|
|
78
|
-
);
|
|
79
|
-
const { message } = postResult;
|
|
80
|
-
if (message) {
|
|
81
|
-
this.log(`Message from gitlab: ${message}`);
|
|
82
128
|
}
|
|
83
129
|
}
|
|
84
130
|
|
|
@@ -38,6 +38,9 @@ const DEFAULT_FILES_TO_CREATE: FileToCreate[] = [
|
|
|
38
38
|
readFile(path.resolve(__dirname, "../includes/envrc"), "utf8"),
|
|
39
39
|
},
|
|
40
40
|
];
|
|
41
|
+
/*
|
|
42
|
+
|
|
43
|
+
TODO: reimplement as PRESETS ?
|
|
41
44
|
const PLATFORMS: { [platformName: string]: PlatformDefinition } = {
|
|
42
45
|
nextJS: {
|
|
43
46
|
variables: {},
|
|
@@ -180,10 +183,15 @@ const PLATFORMS: { [platformName: string]: PlatformDefinition } = {
|
|
|
180
183
|
values: {},
|
|
181
184
|
},
|
|
182
185
|
};
|
|
186
|
+
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
const PLATFORMS: any = {};
|
|
183
190
|
export default (vorpal: Vorpal) =>
|
|
184
191
|
vorpal
|
|
185
192
|
.command("project-init", "Inits a new project")
|
|
186
193
|
.action(async function () {
|
|
194
|
+
throw new Error("needs reimplementation");
|
|
187
195
|
const hasGitlabFile = await hasGitlabCiFile();
|
|
188
196
|
if (hasGitlabFile) {
|
|
189
197
|
this.log("there is already a gitlab-ci.yml file. Skipping");
|
|
@@ -2,20 +2,19 @@ import yaml from "js-yaml";
|
|
|
2
2
|
import { pick } from "lodash";
|
|
3
3
|
import Vorpal from "vorpal";
|
|
4
4
|
import { getProjectPods } from "../../../../utils/projects";
|
|
5
|
-
|
|
6
5
|
import { envAutocompletion } from "./utils/autocompletions";
|
|
7
6
|
import ensureCluster from "./utils/ensureCluster";
|
|
8
7
|
|
|
9
8
|
export default (vorpal: Vorpal) =>
|
|
10
9
|
vorpal
|
|
11
|
-
.command("project-list-pods <
|
|
10
|
+
.command("project-list-pods <envComponent>", "list pods of local project")
|
|
12
11
|
.autocomplete(envAutocompletion)
|
|
13
|
-
.action(async function({
|
|
14
|
-
await ensureCluster.call(this);
|
|
15
|
-
const pods = await getProjectPods(
|
|
12
|
+
.action(async function ({ envComponent }) {
|
|
13
|
+
await ensureCluster.call(this, envComponent);
|
|
14
|
+
const pods = await getProjectPods(envComponent);
|
|
16
15
|
this.log(
|
|
17
16
|
yaml.safeDump(
|
|
18
|
-
pods.map(p => pick(p, ["metadata.name", "status.startTime"]))
|
|
17
|
+
pods.map((p) => pick(p, ["metadata.name", "status.startTime"]))
|
|
19
18
|
)
|
|
20
19
|
);
|
|
21
20
|
});
|
|
@@ -37,7 +37,7 @@ export default (vorpal: Vorpal) =>
|
|
|
37
37
|
// ignore
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
const releaseName = await getEnvironmentByChoice(envComponent).
|
|
40
|
+
const releaseName = await getEnvironmentByChoice(envComponent).envVars
|
|
41
41
|
.RELEASE_NAME; // TODO: maybe its own function would be better
|
|
42
42
|
this.log(`helm release name: ${releaseName}`);
|
|
43
43
|
this.log("");
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import Vorpal from "vorpal";
|
|
2
|
-
import { Env } from "../../../../types/types";
|
|
3
2
|
import { getProjectNamespace } from "../../../../utils/projects";
|
|
4
3
|
import { envAutocompletion } from "./utils/autocompletions";
|
|
5
4
|
|
|
6
5
|
export default (vorpal: Vorpal) =>
|
|
7
6
|
vorpal
|
|
8
|
-
.command(
|
|
7
|
+
.command(
|
|
8
|
+
"project-namespace <envComponent>",
|
|
9
|
+
"show namespace of local project"
|
|
10
|
+
)
|
|
9
11
|
.autocomplete(envAutocompletion)
|
|
10
|
-
.action(async function({
|
|
11
|
-
this.log(await getProjectNamespace(
|
|
12
|
+
.action(async function ({ envComponent }) {
|
|
13
|
+
this.log(await getProjectNamespace(envComponent));
|
|
12
14
|
});
|
|
@@ -13,11 +13,14 @@ import { envAutocompletion } from "./utils/autocompletions";
|
|
|
13
13
|
import ensureCluster from "./utils/ensureCluster";
|
|
14
14
|
export default (vorpal: Vorpal) =>
|
|
15
15
|
vorpal
|
|
16
|
-
.command(
|
|
16
|
+
.command(
|
|
17
|
+
"project-check-costs <envComponent>",
|
|
18
|
+
"Shows you how much you're spending"
|
|
19
|
+
)
|
|
17
20
|
.autocomplete(envAutocompletion)
|
|
18
|
-
.action(async function ({
|
|
19
|
-
await ensureCluster.call(this);
|
|
20
|
-
const namespace = await getProjectNamespace(
|
|
21
|
+
.action(async function ({ envComponent }) {
|
|
22
|
+
await ensureCluster.call(this, envComponent);
|
|
23
|
+
const namespace = await getProjectNamespace(envComponent);
|
|
21
24
|
const url = `http://localhost:${GRAFANA_PROXY_LOCAL_PORT}/namespace.html?name=${namespace}`;
|
|
22
25
|
await startPortForward(
|
|
23
26
|
"deployment/kubecost-cost-analyzer",
|