@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.
Files changed (119) hide show
  1. package/dist/apps/catenv/catenv.js +15 -12
  2. package/dist/apps/catenv/catenv.js.map +1 -1
  3. package/dist/apps/shell/commands/mongodb/projectMongoDestroyMember.js +6 -6
  4. package/dist/apps/shell/commands/mongodb/projectMongoDestroyMember.js.map +1 -1
  5. package/dist/apps/shell/commands/mongodb/projectMongoGetShell.js +6 -6
  6. package/dist/apps/shell/commands/mongodb/projectMongoGetShell.js.map +1 -1
  7. package/dist/apps/shell/commands/mongodb/projectMongoPortForward.js +5 -5
  8. package/dist/apps/shell/commands/mongodb/projectMongoPortForward.js.map +1 -1
  9. package/dist/apps/shell/commands/mongodb/utils/index.d.ts +3 -4
  10. package/dist/apps/shell/commands/mongodb/utils/index.js +6 -6
  11. package/dist/apps/shell/commands/mongodb/utils/index.js.map +1 -1
  12. package/dist/apps/shell/commands/project/commandCloudSqlProxy.js +10 -7
  13. package/dist/apps/shell/commands/project/commandCloudSqlProxy.js.map +1 -1
  14. package/dist/apps/shell/commands/project/commandConfigSecrets.js +46 -176
  15. package/dist/apps/shell/commands/project/commandConfigSecrets.js.map +1 -1
  16. package/dist/apps/shell/commands/project/commandCopyDB.js +1 -1
  17. package/dist/apps/shell/commands/project/commandCopyDB.js.map +1 -1
  18. package/dist/apps/shell/commands/project/commandDeletePods.js +5 -5
  19. package/dist/apps/shell/commands/project/commandDeletePods.js.map +1 -1
  20. package/dist/apps/shell/commands/project/commandDeleteProject.js +3 -3
  21. package/dist/apps/shell/commands/project/commandDeleteProject.js.map +1 -1
  22. package/dist/apps/shell/commands/project/commandGetShell.js +6 -6
  23. package/dist/apps/shell/commands/project/commandGetShell.js.map +1 -1
  24. package/dist/apps/shell/commands/project/commandInitGitlab.js +64 -38
  25. package/dist/apps/shell/commands/project/commandInitGitlab.js.map +1 -1
  26. package/dist/apps/shell/commands/project/commandInitProject.js +138 -129
  27. package/dist/apps/shell/commands/project/commandInitProject.js.map +1 -1
  28. package/dist/apps/shell/commands/project/commandListPods.js +5 -5
  29. package/dist/apps/shell/commands/project/commandListPods.js.map +1 -1
  30. package/dist/apps/shell/commands/project/commandMigrateHelm3.js +1 -1
  31. package/dist/apps/shell/commands/project/commandMigrateHelm3.js.map +1 -1
  32. package/dist/apps/shell/commands/project/commandNamespace.js +3 -3
  33. package/dist/apps/shell/commands/project/commandNamespace.js.map +1 -1
  34. package/dist/apps/shell/commands/project/commandOpenCostDashboard.js +4 -4
  35. package/dist/apps/shell/commands/project/commandOpenCostDashboard.js.map +1 -1
  36. package/dist/apps/shell/commands/project/commandOpenDashboard.js +11 -5
  37. package/dist/apps/shell/commands/project/commandOpenDashboard.js.map +1 -1
  38. package/dist/apps/shell/commands/project/commandOpenEnv.js +1 -1
  39. package/dist/apps/shell/commands/project/commandOpenEnv.js.map +1 -1
  40. package/dist/apps/shell/commands/project/commandOpenGrafana.js +4 -4
  41. package/dist/apps/shell/commands/project/commandOpenGrafana.js.map +1 -1
  42. package/dist/apps/shell/commands/project/commandOpenGrafanaPod.js +5 -5
  43. package/dist/apps/shell/commands/project/commandOpenGrafanaPod.js.map +1 -1
  44. package/dist/apps/shell/commands/project/commandOpenLogs.js +4 -4
  45. package/dist/apps/shell/commands/project/commandOpenLogs.js.map +1 -1
  46. package/dist/apps/shell/commands/project/commandPauseProject.js +3 -3
  47. package/dist/apps/shell/commands/project/commandPauseProject.js.map +1 -1
  48. package/dist/apps/shell/commands/project/commandPortForward.js +5 -5
  49. package/dist/apps/shell/commands/project/commandPortForward.js.map +1 -1
  50. package/dist/apps/shell/commands/project/commandTriggerCronjob.js +4 -4
  51. package/dist/apps/shell/commands/project/commandTriggerCronjob.js.map +1 -1
  52. package/dist/apps/shell/commands/project/index.js +0 -2
  53. package/dist/apps/shell/commands/project/index.js.map +1 -1
  54. package/dist/apps/shell/commands/project/utils/ensureCluster.d.ts +1 -1
  55. package/dist/apps/shell/commands/project/utils/ensureCluster.js +12 -10
  56. package/dist/apps/shell/commands/project/utils/ensureCluster.js.map +1 -1
  57. package/dist/apps/shell/commands/project/utils/ensureNamespace.d.ts +1 -2
  58. package/dist/apps/shell/commands/project/utils/ensureNamespace.js +2 -2
  59. package/dist/apps/shell/commands/project/utils/ensureNamespace.js.map +1 -1
  60. package/dist/config/getProjectConfig.d.ts +7 -4
  61. package/dist/config/getProjectConfig.js +35 -11
  62. package/dist/config/getProjectConfig.js.map +1 -1
  63. package/dist/tsconfig.tsbuildinfo +1 -1
  64. package/dist/types/types.d.ts +0 -1
  65. package/dist/utils/cluster.d.ts +7 -0
  66. package/dist/utils/cluster.js +15 -3
  67. package/dist/utils/cluster.js.map +1 -1
  68. package/dist/utils/editAsFile.d.ts +1 -0
  69. package/dist/utils/editAsFile.js +22 -0
  70. package/dist/utils/editAsFile.js.map +1 -0
  71. package/dist/utils/gitlab.d.ts +2 -1
  72. package/dist/utils/gitlab.js +29 -3
  73. package/dist/utils/gitlab.js.map +1 -1
  74. package/dist/utils/projects/index.d.ts +4 -15
  75. package/dist/utils/projects/index.js +10 -78
  76. package/dist/utils/projects/index.js.map +1 -1
  77. package/package.json +1 -1
  78. package/src/apps/catenv/catenv.ts +36 -26
  79. package/src/apps/shell/commands/mongodb/projectMongoDestroyMember.ts +6 -6
  80. package/src/apps/shell/commands/mongodb/projectMongoGetShell.ts +9 -7
  81. package/src/apps/shell/commands/mongodb/projectMongoPortForward.ts +10 -5
  82. package/src/apps/shell/commands/mongodb/utils/index.ts +9 -8
  83. package/src/apps/shell/commands/project/commandCloudSqlProxy.ts +14 -7
  84. package/src/apps/shell/commands/project/commandConfigSecrets.ts +37 -172
  85. package/src/apps/shell/commands/project/commandCopyDB.ts +2 -1
  86. package/src/apps/shell/commands/project/commandDeletePods.ts +5 -6
  87. package/src/apps/shell/commands/project/commandDeleteProject.ts +4 -5
  88. package/src/apps/shell/commands/project/commandGetShell.ts +7 -7
  89. package/src/apps/shell/commands/project/commandInitGitlab.ts +97 -51
  90. package/src/apps/shell/commands/project/commandInitProject.ts +8 -0
  91. package/src/apps/shell/commands/project/commandListPods.ts +5 -6
  92. package/src/apps/shell/commands/project/commandMigrateHelm3.ts +1 -1
  93. package/src/apps/shell/commands/project/commandNamespace.ts +6 -4
  94. package/src/apps/shell/commands/project/commandOpenCostDashboard.ts +7 -4
  95. package/src/apps/shell/commands/project/commandOpenDashboard.ts +18 -6
  96. package/src/apps/shell/commands/project/commandOpenEnv.ts +1 -1
  97. package/src/apps/shell/commands/project/commandOpenGrafana.ts +4 -4
  98. package/src/apps/shell/commands/project/commandOpenGrafanaPod.ts +5 -5
  99. package/src/apps/shell/commands/project/commandOpenLogs.ts +4 -4
  100. package/src/apps/shell/commands/project/commandPauseProject.ts +6 -4
  101. package/src/apps/shell/commands/project/commandPortForward.ts +5 -5
  102. package/src/apps/shell/commands/project/commandTriggerCronjob.ts +4 -4
  103. package/src/apps/shell/commands/project/index.ts +1 -2
  104. package/src/apps/shell/commands/project/utils/ensureCluster.ts +12 -10
  105. package/src/apps/shell/commands/project/utils/ensureNamespace.ts +2 -3
  106. package/src/config/getProjectConfig.ts +40 -11
  107. package/src/types/types.ts +0 -2
  108. package/src/utils/cluster.ts +15 -2
  109. package/src/utils/editAsFile.ts +21 -0
  110. package/src/utils/gitlab.ts +56 -4
  111. package/src/utils/projects/index.ts +10 -93
  112. package/dist/apps/shell/commands/project/commandVariables.d.ts +0 -3
  113. package/dist/apps/shell/commands/project/commandVariables.js +0 -16
  114. package/dist/apps/shell/commands/project/commandVariables.js.map +0 -1
  115. package/dist/apps/shell/commands/project/utils/monorepo.d.ts +0 -10
  116. package/dist/apps/shell/commands/project/utils/monorepo.js +0 -25
  117. package/dist/apps/shell/commands/project/utils/monorepo.js.map +0 -1
  118. package/src/apps/shell/commands/project/commandVariables.ts +0 -13
  119. package/src/apps/shell/commands/project/utils/monorepo.ts +0 -23
@@ -1,27 +1,16 @@
1
- import { V1Secret } from "@kubernetes/client-node";
2
- import yaml from "js-yaml";
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
- getAllSecretsEnvVarsMapping,
18
- getPassPath,
19
- getProjectNamespace,
20
- } from "../../../../utils/projects";
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
- throw new Error("need to reimplement");
35
- await ensureCluster.call(this);
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
- let hasError = false;
66
- await editPass(passPath);
67
-
68
- try {
69
- envConfigInPass = await readPassEnvVars(passPath);
31
+ const hasError = false;
70
32
 
71
- const configuredKeysInPass = Object.keys(envConfigInPass);
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
- const allSecretEnvKeysInValues = Object.keys(secretEnvVarsMapping);
74
- const keysNotInValues = difference(
75
- configuredKeysInPass,
76
- allSecretEnvKeysInValues
77
- );
78
-
79
- const keysNotInPass = difference(
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 (keysNotInPass.length > 0) {
96
- await logError(
97
- this,
98
- `the following keys are defined in the values.yaml, but not in pass: ${keysNotInPass.join(
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
- if (env !== "env-local") {
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
- valuesFromPassInGroup,
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
- if (sourceEnv === noAnswer) {
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 [env, componentName] = envComponent.split("-");
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 <env>", "delete / restart pods")
14
+ .command("project-delete-pods <envComponent>", "delete / restart pods")
16
15
  .autocomplete(envAutocompletion)
17
- .action(async function ({ env }) {
18
- await ensureCluster.call(this);
19
- const namespace = await getProjectNamespace(env);
20
- const podNames = await getProjectPodNames(env);
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, spawn } from "child-process-promise";
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 <env>",
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 ({ env }) {
15
- const namespace = await getProjectNamespace(env as Env);
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 <env>",
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({ env }) {
20
- await ensureCluster.call(this);
21
- const namespace = await getProjectNamespace(env);
22
- const podNames = await getProjectPodNames(env);
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 { getClusterByName } from "../../../../utils/cluster";
4
- import { doGitlabRequest, getProjectInfo } from "../../../../utils/gitlab";
5
- import { readPass, syncBitwarden } from "../../../../utils/passwordstore/";
4
+ import { getAllPipelineContexts } from "../../../../config/getProjectConfig";
6
5
  import {
7
- getLocalProjectVariables,
8
- getProjectNamespace,
9
- } from "../../../../utils/projects";
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 syncBitwarden();
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
- if (clusters.length === 0) {
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
- clusters.forEach((cluster: any) => this.log(` - ${cluster.name}`));
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 cluster:");
51
+ this.log("your project specifies the following clusters:");
38
52
  this.log("");
39
- const { CLUSTER_NAME } = await getLocalProjectVariables();
40
- const configuredCluster = await getClusterByName(CLUSTER_NAME);
41
- if (!configuredCluster) {
42
- throw new Error(
43
- `there exist no cluster with the name '${CLUSTER_NAME}'`
44
- );
45
- }
46
- this.log(`${CLUSTER_NAME} (${configuredCluster.fullName})`);
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
- const { shouldContinue } = await this.prompt({
49
- type: "confirm",
50
- name: "shouldContinue",
51
- message: "Should I add the this cluster ? 🤔 ",
52
- });
76
+
77
+ const missingClusters = configuredClusters.filter(
78
+ (c) => !existingClusters.some((exist) => exist.name === c.name)
79
+ );
80
+
53
81
  this.log("");
54
- if (shouldContinue) {
55
- const { api_url, passCredentials } = configuredCluster;
56
- if (!api_url) {
57
- throw new Error("no api_url on this cluster!");
58
- }
59
- if (!passCredentials) {
60
- throw new Error("no passCredentials on this cluster!");
61
- }
62
- const token = await readPass(passCredentials.token);
63
- const ca_cert = await readPass(passCredentials.ca_cert);
64
-
65
- const postResult = await doGitlabRequest(
66
- this,
67
- `projects/${projectId}/clusters/user`,
68
- {
69
- name: configuredCluster.fullName,
70
- managed: false,
71
- platform_kubernetes_attributes: {
72
- api_url,
73
- ca_cert,
74
- token,
75
- namespace: await getProjectNamespace("prod"),
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 <env>", "list pods of local project")
10
+ .command("project-list-pods <envComponent>", "list pods of local project")
12
11
  .autocomplete(envAutocompletion)
13
- .action(async function({ env }) {
14
- await ensureCluster.call(this);
15
- const pods = await getProjectPods(env);
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).variables
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("project-namespace <env>", "show namespace of local project")
7
+ .command(
8
+ "project-namespace <envComponent>",
9
+ "show namespace of local project"
10
+ )
9
11
  .autocomplete(envAutocompletion)
10
- .action(async function({ env }) {
11
- this.log(await getProjectNamespace(env as Env));
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("project-check-costs <env>", "Shows you how much you're spending")
16
+ .command(
17
+ "project-check-costs <envComponent>",
18
+ "Shows you how much you're spending"
19
+ )
17
20
  .autocomplete(envAutocompletion)
18
- .action(async function ({ env }) {
19
- await ensureCluster.call(this);
20
- const namespace = await getProjectNamespace(env);
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",