@catladder/cli 1.35.0 → 1.36.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.
Files changed (32) hide show
  1. package/dist/apps/cli/commands/mongodb/projectMongoPortForward.js +25 -9
  2. package/dist/apps/cli/commands/mongodb/projectMongoPortForward.js.map +1 -1
  3. package/dist/apps/cli/commands/mongodb/utils/index.js +14 -3
  4. package/dist/apps/cli/commands/mongodb/utils/index.js.map +1 -1
  5. package/dist/apps/cli/commands/project/commandConfigSecrets.js +29 -51
  6. package/dist/apps/cli/commands/project/commandConfigSecrets.js.map +1 -1
  7. package/dist/apps/cli/commands/project/commandCopyDB.js +1 -23
  8. package/dist/apps/cli/commands/project/commandCopyDB.js.map +1 -1
  9. package/dist/apps/cli/commands/project/setup/setupKubernetes.js +3 -2
  10. package/dist/apps/cli/commands/project/setup/setupKubernetes.js.map +1 -1
  11. package/dist/config/constants.d.ts +0 -1
  12. package/dist/config/constants.js +1 -2
  13. package/dist/config/constants.js.map +1 -1
  14. package/dist/tsconfig.tsbuildinfo +1 -1
  15. package/dist/utils/gitlab.d.ts +1 -1
  16. package/dist/utils/gitlab.js +106 -44
  17. package/dist/utils/gitlab.js.map +1 -1
  18. package/dist/utils/passwordstore/index.d.ts +0 -1
  19. package/dist/utils/passwordstore/index.js +1 -64
  20. package/dist/utils/passwordstore/index.js.map +1 -1
  21. package/dist/utils/projects/index.js +8 -2
  22. package/dist/utils/projects/index.js.map +1 -1
  23. package/package.json +3 -2
  24. package/src/apps/cli/commands/mongodb/projectMongoPortForward.ts +15 -0
  25. package/src/apps/cli/commands/mongodb/utils/index.ts +17 -7
  26. package/src/apps/cli/commands/project/commandConfigSecrets.ts +10 -30
  27. package/src/apps/cli/commands/project/commandCopyDB.ts +2 -1
  28. package/src/apps/cli/commands/project/setup/setupKubernetes.ts +5 -4
  29. package/src/config/constants.ts +0 -2
  30. package/src/utils/gitlab.ts +77 -9
  31. package/src/utils/passwordstore/index.ts +0 -28
  32. package/src/utils/projects/index.ts +6 -1
@@ -1,6 +1,6 @@
1
1
  import { exec } from "child-process-promise";
2
2
  import { getSecretVarName } from "@catladder/pipeline";
3
- import { isObject } from "lodash";
3
+ import { has, isObject, times } from "lodash";
4
4
  import memoizee from "memoizee";
5
5
  import fetch from "node-fetch";
6
6
  import open from "open";
@@ -143,12 +143,14 @@ const createVariable = async (
143
143
  vorpal: CommandInstance,
144
144
  projectId: string,
145
145
  key: string,
146
- value: string
146
+ value: string,
147
+ environment_scope = "*"
147
148
  ) => {
148
149
  return await doGitlabRequest(vorpal, `projects/${projectId}/variables`, {
149
150
  key,
150
151
  value,
151
152
  masked: isMaskable(value),
153
+ environment_scope,
152
154
  });
153
155
  };
154
156
 
@@ -168,23 +170,89 @@ const updateVariable = async (
168
170
  true
169
171
  );
170
172
  };
173
+
174
+ const getAllCatladderEnvVarsInGitlab = async (vorpal: CommandInstance) => {
175
+ const allVariables = await getAllVariables(vorpal).then((v) =>
176
+ v.reduce<{
177
+ [key: string]: {
178
+ value?: string;
179
+ backups: number[];
180
+ };
181
+ }>((acc, variable) => {
182
+ const { key } = variable;
183
+
184
+ if (key.startsWith("CL_")) {
185
+ const matchBackup = key.match(/(CL_.*)_backup_([0-9]+)/);
186
+
187
+ if (matchBackup) {
188
+ const key = matchBackup[1];
189
+ const timestamp = Number(matchBackup[2]);
190
+ const backups = [...(acc[key]?.backups ?? []), timestamp];
191
+ return {
192
+ ...acc,
193
+ [key]: {
194
+ ...(acc[key] ?? {}), // add value
195
+ backups,
196
+ },
197
+ };
198
+ }
199
+
200
+ return {
201
+ ...acc,
202
+ [key]: {
203
+ backups: [],
204
+ ...(acc[key] ?? {}), // may add backups
205
+ value: variable.value,
206
+ },
207
+ };
208
+ }
209
+
210
+ return acc;
211
+ }, {})
212
+ );
213
+ return allVariables;
214
+ };
215
+
171
216
  export const upsertAllVariables = async (
172
217
  vorpal: CommandInstance,
173
218
  variables: Record<string, any>,
174
219
  env: string,
175
- componentName: string
220
+ componentName: string,
221
+ backup = true
176
222
  ): Promise<void> => {
177
223
  const { id } = await getProjectInfo(vorpal);
178
224
 
225
+ // we list all existing variables. We also gather backup versions, but its currently unused
226
+ const existingVariables = await getAllCatladderEnvVarsInGitlab(vorpal);
179
227
  for (const [key, value] of Object.entries(variables ?? {})) {
180
228
  const fullKey = getSecretVarName(env, componentName, key);
181
229
  const valueSanitized = isObject(value) ? JSON.stringify(value) : `${value}`;
182
- try {
183
- await updateVariable(vorpal, id, fullKey, valueSanitized);
184
- } catch (e) {
185
- await createVariable(vorpal, id, fullKey, valueSanitized);
186
- } finally {
187
- getAllVariables.clear();
230
+
231
+ const exists = has(existingVariables, fullKey);
232
+ const oldValue = existingVariables[fullKey]?.value;
233
+ const changed = oldValue !== valueSanitized;
234
+ if (changed) {
235
+ if (exists) {
236
+ vorpal.log(`changed: ${key}`);
237
+
238
+ await updateVariable(vorpal, id, fullKey, valueSanitized);
239
+ // write backup
240
+ if (backup) {
241
+ await createVariable(
242
+ vorpal,
243
+ id,
244
+ fullKey + "_backup_" + new Date().getTime(),
245
+ oldValue,
246
+ "_backup"
247
+ );
248
+ }
249
+ } else {
250
+ vorpal.log(`new : ${key}`);
251
+ await createVariable(vorpal, id, fullKey, valueSanitized);
252
+ }
253
+ } else {
254
+ vorpal.log(`skip : ${key}`);
188
255
  }
189
256
  }
257
+ getAllVariables.clear();
190
258
  };
@@ -1,9 +1,6 @@
1
1
  import { exec, spawn } from "child-process-promise";
2
2
  import commandExists from "command-exists-promise";
3
3
  import dayjs from "dayjs";
4
- import { readFile, writeFile } from "fs-extra";
5
- import { withFile } from "tmp-promise";
6
- import getEditor from "../getEditor";
7
4
  import { getPreference, hasPreference, setPreference } from "../preferences";
8
5
 
9
6
  const DEBUG = false;
@@ -120,14 +117,6 @@ export const readPass = async (path: string) => {
120
117
  return result.notes || result.login?.password;
121
118
  };
122
119
 
123
- const update = async (type: string, itemId: string, value: any) => {
124
- const result = await execBitwardenCommand(
125
- `edit ${type} ${itemId} ${encode(value)}`
126
- );
127
-
128
- return result;
129
- };
130
-
131
120
  const MAX_SYNC_AGE_IN_MINUTES = 30;
132
121
  export const syncBitwarden = async (force = true) => {
133
122
  const lastSync = (await hasPreference("bwLastSync"))
@@ -171,20 +160,3 @@ export const trashItem = async (path: string) => {
171
160
 
172
161
  return result;
173
162
  };
174
- export const editPass = async (path: string) => {
175
- const item = await getItem(path);
176
-
177
- await withFile(
178
- async ({ path: tmpFilePath }) => {
179
- await writeFile(tmpFilePath, item.notes);
180
- await (await getEditor()).open(tmpFilePath);
181
- const newContent = (await readFile(tmpFilePath)).toString("utf-8");
182
-
183
- await update("item", item.id, {
184
- ...item,
185
- notes: newContent,
186
- });
187
- },
188
- { postfix: ".yml" }
189
- );
190
- };
@@ -35,7 +35,12 @@ export const getProjectPods = async (envComponent: string) => {
35
35
  const k8sApi = getk8sApi();
36
36
  const res = await k8sApi.listNamespacedPod(namespace);
37
37
 
38
- return res.body.items;
38
+ const { componentName } = parseChoice(envComponent);
39
+ return res.body.items.filter((item) =>
40
+ componentName
41
+ ? item.metadata?.name?.includes("-" + componentName + "-")
42
+ : true
43
+ );
39
44
  };
40
45
 
41
46
  export const getProjectPvcs = async (envComponent: string) => {