@vaharoni/devops 1.1.12 → 1.2.1

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 (172) hide show
  1. package/dist/cli/core/affected.d.ts +9 -0
  2. package/dist/cli/core/affected.d.ts.map +1 -0
  3. package/dist/cli/{affected.js → core/affected.js} +4 -6
  4. package/dist/cli/core/cloudrun.d.ts +9 -0
  5. package/dist/cli/core/cloudrun.d.ts.map +1 -0
  6. package/dist/cli/{cloudrun.js → core/cloudrun.js} +3 -5
  7. package/dist/cli/core/console.d.ts +10 -0
  8. package/dist/cli/core/console.d.ts.map +1 -0
  9. package/dist/cli/core/console.js +50 -0
  10. package/dist/cli/core/constant.d.ts +9 -0
  11. package/dist/cli/core/constant.d.ts.map +1 -0
  12. package/dist/cli/{constant.js → core/constant.js} +3 -5
  13. package/dist/cli/core/env.d.ts +9 -0
  14. package/dist/cli/core/env.d.ts.map +1 -0
  15. package/dist/cli/{env.js → core/env.js} +4 -6
  16. package/dist/cli/core/exec.d.ts +9 -0
  17. package/dist/cli/core/exec.d.ts.map +1 -0
  18. package/dist/cli/{exec.js → core/exec.js} +5 -7
  19. package/dist/cli/core/image.d.ts +9 -0
  20. package/dist/cli/core/image.d.ts.map +1 -0
  21. package/dist/cli/{image.js → core/image.js} +6 -8
  22. package/dist/cli/core/index.d.ts +16 -0
  23. package/dist/cli/core/index.d.ts.map +1 -0
  24. package/dist/cli/core/index.js +15 -0
  25. package/dist/cli/core/init.d.ts +9 -0
  26. package/dist/cli/core/init.d.ts.map +1 -0
  27. package/dist/cli/{init.js → core/init.js} +3 -5
  28. package/dist/cli/core/job.d.ts +9 -0
  29. package/dist/cli/core/job.d.ts.map +1 -0
  30. package/dist/cli/{job.js → core/job.js} +7 -9
  31. package/dist/cli/core/namespace.d.ts +9 -0
  32. package/dist/cli/core/namespace.d.ts.map +1 -0
  33. package/dist/cli/{namespace.js → core/namespace.js} +4 -7
  34. package/dist/cli/core/prep-build.d.ts +10 -0
  35. package/dist/cli/core/prep-build.d.ts.map +1 -0
  36. package/dist/cli/{prep-build.js → core/prep-build.js} +6 -8
  37. package/dist/cli/core/registry.d.ts +9 -0
  38. package/dist/cli/core/registry.d.ts.map +1 -0
  39. package/dist/cli/{registry.js → core/registry.js} +5 -7
  40. package/dist/cli/core/run-many.d.ts +10 -0
  41. package/dist/cli/core/run-many.d.ts.map +1 -0
  42. package/dist/cli/{run-many.js → core/run-many.js} +3 -5
  43. package/dist/cli/core/run.d.ts +9 -0
  44. package/dist/cli/core/run.d.ts.map +1 -0
  45. package/dist/cli/{run.js → core/run.js} +6 -8
  46. package/dist/cli/core/test.d.ts +9 -0
  47. package/dist/cli/core/test.d.ts.map +1 -0
  48. package/dist/cli/{test.js → core/test.js} +2 -4
  49. package/dist/cli/exec.sh +21 -0
  50. package/dist/cli/extensions/dml.d.ts +9 -0
  51. package/dist/cli/extensions/dml.d.ts.map +1 -0
  52. package/dist/cli/{dml.js → extensions/dml.js} +2 -4
  53. package/dist/cli/extensions/index.d.ts +9 -0
  54. package/dist/cli/extensions/index.d.ts.map +1 -0
  55. package/dist/cli/extensions/index.js +8 -0
  56. package/dist/cli/extensions/internal-curl.d.ts +10 -0
  57. package/dist/cli/extensions/internal-curl.d.ts.map +1 -0
  58. package/dist/cli/{internal-curl.js → extensions/internal-curl.js} +3 -5
  59. package/dist/cli/extensions/jwt.d.ts +9 -0
  60. package/dist/cli/extensions/jwt.d.ts.map +1 -0
  61. package/dist/cli/{jwt.js → extensions/jwt.js} +3 -5
  62. package/dist/cli/extensions/prisma.d.ts +9 -0
  63. package/dist/cli/extensions/prisma.d.ts.map +1 -0
  64. package/dist/cli/{prisma.js → extensions/prisma.js} +4 -6
  65. package/dist/cli/extensions/redis-bitnami.d.ts +11 -0
  66. package/dist/cli/extensions/redis-bitnami.d.ts.map +1 -0
  67. package/dist/cli/{redis.js → extensions/redis-bitnami.js} +4 -6
  68. package/dist/cli/extensions/redis-ha.d.ts +11 -0
  69. package/dist/cli/extensions/redis-ha.d.ts.map +1 -0
  70. package/dist/cli/extensions/redis-ha.js +51 -0
  71. package/dist/cli/extensions/stackgres.d.ts +10 -0
  72. package/dist/cli/extensions/stackgres.d.ts.map +1 -0
  73. package/dist/cli/{db.js → extensions/stackgres.js} +3 -5
  74. package/dist/cli/extensions/template.d.ts +9 -0
  75. package/dist/cli/extensions/template.d.ts.map +1 -0
  76. package/dist/cli/{template.js → extensions/template.js} +8 -10
  77. package/dist/devops.js +84 -62
  78. package/dist/libs/k8s-generate.d.ts +1 -1
  79. package/dist/libs/k8s-generate.d.ts.map +1 -1
  80. package/dist/libs/k8s-generate.js +15 -14
  81. package/dist/libs/{k8s-redis.d.ts → k8s-redis-bitnami.d.ts} +1 -1
  82. package/dist/libs/k8s-redis-bitnami.d.ts.map +1 -0
  83. package/dist/libs/k8s-redis-ha.d.ts +3 -0
  84. package/dist/libs/k8s-redis-ha.d.ts.map +1 -0
  85. package/dist/libs/k8s-redis-ha.js +15 -0
  86. package/dist/plugins.d.ts +4 -0
  87. package/dist/plugins.d.ts.map +1 -0
  88. package/dist/plugins.js +7 -0
  89. package/dist/types/index.d.ts +3 -0
  90. package/dist/types/index.d.ts.map +1 -1
  91. package/dist/types/index.js +1 -0
  92. package/package.json +12 -2
  93. package/src/cli/{affected.ts → core/affected.ts} +4 -6
  94. package/src/cli/{cloudrun.ts → core/cloudrun.ts} +3 -5
  95. package/src/cli/core/console.ts +59 -0
  96. package/src/cli/{constant.ts → core/constant.ts} +3 -5
  97. package/src/cli/{env.ts → core/env.ts} +4 -6
  98. package/src/cli/{exec.ts → core/exec.ts} +5 -7
  99. package/src/cli/{image.ts → core/image.ts} +6 -8
  100. package/src/cli/core/index.ts +15 -0
  101. package/src/cli/{init.ts → core/init.ts} +4 -6
  102. package/src/cli/{job.ts → core/job.ts} +7 -9
  103. package/src/cli/{namespace.ts → core/namespace.ts} +4 -8
  104. package/src/cli/{prep-build.ts → core/prep-build.ts} +6 -8
  105. package/src/cli/{registry.ts → core/registry.ts} +5 -7
  106. package/src/cli/{run-many.ts → core/run-many.ts} +3 -5
  107. package/src/cli/{run.ts → core/run.ts} +6 -8
  108. package/src/cli/{test.ts → core/test.ts} +2 -4
  109. package/src/cli/{dml.ts → extensions/dml.ts} +2 -4
  110. package/src/cli/extensions/index.ts +8 -0
  111. package/src/cli/{internal-curl.ts → extensions/internal-curl.ts} +3 -5
  112. package/src/cli/{jwt.ts → extensions/jwt.ts} +3 -5
  113. package/src/cli/{prisma.ts → extensions/prisma.ts} +4 -6
  114. package/src/cli/{redis.ts → extensions/redis-bitnami.ts} +4 -6
  115. package/src/cli/extensions/redis-ha.ts +57 -0
  116. package/src/cli/{db.ts → extensions/stackgres.ts} +3 -5
  117. package/src/cli/{template.ts → extensions/template.ts} +8 -10
  118. package/src/devops.ts +100 -64
  119. package/src/libs/k8s-generate.ts +15 -14
  120. package/src/libs/k8s-redis-ha.ts +16 -0
  121. package/src/plugins.ts +8 -0
  122. package/src/target-templates/lang-variants-common/typescript/.devops/manifests/deployment-debug.yaml.hb +36 -39
  123. package/src/types/index.ts +1 -0
  124. package/dist/cli/affected.d.ts +0 -11
  125. package/dist/cli/affected.d.ts.map +0 -1
  126. package/dist/cli/cloudrun.d.ts +0 -11
  127. package/dist/cli/cloudrun.d.ts.map +0 -1
  128. package/dist/cli/console.d.ts +0 -11
  129. package/dist/cli/console.d.ts.map +0 -1
  130. package/dist/cli/console.js +0 -35
  131. package/dist/cli/constant.d.ts +0 -11
  132. package/dist/cli/constant.d.ts.map +0 -1
  133. package/dist/cli/db.d.ts +0 -11
  134. package/dist/cli/db.d.ts.map +0 -1
  135. package/dist/cli/dml.d.ts +0 -11
  136. package/dist/cli/dml.d.ts.map +0 -1
  137. package/dist/cli/env.d.ts +0 -11
  138. package/dist/cli/env.d.ts.map +0 -1
  139. package/dist/cli/exec.d.ts +0 -11
  140. package/dist/cli/exec.d.ts.map +0 -1
  141. package/dist/cli/image.d.ts +0 -11
  142. package/dist/cli/image.d.ts.map +0 -1
  143. package/dist/cli/init.d.ts +0 -11
  144. package/dist/cli/init.d.ts.map +0 -1
  145. package/dist/cli/internal-curl.d.ts +0 -11
  146. package/dist/cli/internal-curl.d.ts.map +0 -1
  147. package/dist/cli/job.d.ts +0 -11
  148. package/dist/cli/job.d.ts.map +0 -1
  149. package/dist/cli/jwt.d.ts +0 -11
  150. package/dist/cli/jwt.d.ts.map +0 -1
  151. package/dist/cli/namespace.d.ts +0 -11
  152. package/dist/cli/namespace.d.ts.map +0 -1
  153. package/dist/cli/prep-build.d.ts +0 -11
  154. package/dist/cli/prep-build.d.ts.map +0 -1
  155. package/dist/cli/prisma.d.ts +0 -11
  156. package/dist/cli/prisma.d.ts.map +0 -1
  157. package/dist/cli/redis.d.ts +0 -11
  158. package/dist/cli/redis.d.ts.map +0 -1
  159. package/dist/cli/registry.d.ts +0 -11
  160. package/dist/cli/registry.d.ts.map +0 -1
  161. package/dist/cli/run-many.d.ts +0 -11
  162. package/dist/cli/run-many.d.ts.map +0 -1
  163. package/dist/cli/run.d.ts +0 -11
  164. package/dist/cli/run.d.ts.map +0 -1
  165. package/dist/cli/template.d.ts +0 -11
  166. package/dist/cli/template.d.ts.map +0 -1
  167. package/dist/cli/test.d.ts +0 -11
  168. package/dist/cli/test.d.ts.map +0 -1
  169. package/dist/libs/k8s-redis.d.ts.map +0 -1
  170. package/src/cli/console.ts +0 -46
  171. /package/dist/libs/{k8s-redis.js → k8s-redis-bitnami.js} +0 -0
  172. /package/src/libs/{k8s-redis.ts → k8s-redis-bitnami.ts} +0 -0
@@ -0,0 +1,57 @@
1
+ import { CLICommandParser, printUsageAndExit, StrongParams } from "../common";
2
+ import { establishRedisTunnel, getRedisList } from "../../libs/k8s-redis-ha";
3
+
4
+ const oneLiner =
5
+ "Utilities to help accessing production and staging redis installation from redis-ha";
6
+ const keyExamples = `
7
+ $ devops redis list
8
+ $ devops redis tunnel redis-staging
9
+ `.trim();
10
+
11
+ const usage = `
12
+ ${oneLiner}
13
+
14
+ COMMANDS
15
+ list Lists the available redis installations
16
+ tunnel <namespace> [-p <port>] Sets up a tunnel to the remote Redis instance so you can access the DB from your local machine on port 9379 by default
17
+
18
+ NOTES
19
+ This command assumes the namespace and the helm release name are the same.
20
+ The --env flag should not be used with these commands, as the Redis namespaces follow different conventions than the monorepo env.
21
+
22
+ EXAMPLES
23
+ ${keyExamples}
24
+ `;
25
+
26
+ const handlers = {
27
+ list: () => {
28
+ const res = getRedisList();
29
+ console.log(res);
30
+ },
31
+ tunnel: (opts: StrongParams) => {
32
+ const namespace = opts.required("namespace");
33
+ const port = opts.optional("port") ?? '9379';
34
+ establishRedisTunnel(namespace, port);
35
+ },
36
+ };
37
+
38
+ function run(cmdObj: CLICommandParser) {
39
+ if (cmdObj.help || cmdObj.args.length < 1) printUsageAndExit(usage);
40
+ const parsed = cmdObj.parseOptions({ params: ["-p"] });
41
+
42
+ const [command, namespace] = parsed.args;
43
+ const port = parsed.options["-p"];
44
+ // @ts-expect-error left as an exercise for the reader
45
+ const handler = handlers[command];
46
+ if (!handler) {
47
+ console.error(`Unknown command: ${command}`);
48
+ printUsageAndExit(usage);
49
+ }
50
+ const params = new StrongParams(usage, {
51
+ namespace,
52
+ port,
53
+ });
54
+ handler(params);
55
+ }
56
+
57
+ export const redisHa = { name: 'redis-ha', command: 'redis', oneLiner, keyExamples, run };
@@ -6,8 +6,8 @@ import {
6
6
  getDbBackups,
7
7
  getDbList,
8
8
  getDbPasswords,
9
- } from "../libs/k8s-db";
10
- import { CLICommandParser, printUsageAndExit, StrongParams } from "./common";
9
+ } from "../../libs/k8s-db";
10
+ import { CLICommandParser, printUsageAndExit, StrongParams } from "../common";
11
11
 
12
12
  const oneLiner =
13
13
  "Utilities to help day to day operations of production and staging databases";
@@ -128,6 +128,4 @@ function run(cmdObj: CLICommandParser) {
128
128
  handler(params);
129
129
  }
130
130
 
131
- export default {
132
- db: { oneLiner, keyExamples, run },
133
- };
131
+ export const stackgres = { command: 'db', oneLiner, keyExamples, run };
@@ -1,11 +1,11 @@
1
1
  import {
2
- } from "../libs/k8s-image-config";
3
- import { CLICommandParser, printUsageAndExit, StrongParams } from "../../src/cli/common";
4
- import { generateDbMigrateJob, generateDebugDeployment, generateWorkspaceDeployment, ImageContextGenerator } from "../libs/k8s-generate";
2
+ } from "../../libs/k8s-image-config";
3
+ import { CLICommandParser, printUsageAndExit, StrongParams } from "../common";
4
+ import { generateDbMigrateJob, generateDebugPod, generateWorkspaceDeployment, ImageContextGenerator } from "../../libs/k8s-generate";
5
5
  import chalk from "chalk";
6
- import { getWorkspace } from "../libs/discovery";
7
- import { getWorkspaceImages } from "../libs/discovery/images";
8
- import { getImageData, getImageNames } from "../libs/config";
6
+ import { getWorkspace } from "../../libs/discovery";
7
+ import { getWorkspaceImages } from "../../libs/discovery/images";
8
+ import { getImageData, getImageNames } from "../../libs/config";
9
9
 
10
10
  const SUPPORTED_CONTEXT_TYPES = ['deployment', 'db-migrate', 'debug'];
11
11
 
@@ -130,7 +130,7 @@ const handlers = {
130
130
  const image = opts.required('workspaceOrImage');
131
131
  console.warn(chalk.green(`\nThis is a sample of generated manifests for the debug image ${image}:\n`))
132
132
  console.log(
133
- generateDebugDeployment(
133
+ generateDebugPod(
134
134
  opts.required('env'),
135
135
  image,
136
136
  'dummy-sha'
@@ -164,6 +164,4 @@ function run(cmdObj: CLICommandParser) {
164
164
  handler(params);
165
165
  }
166
166
 
167
- export default {
168
- template: { oneLiner, keyExamples, run },
169
- };
167
+ export const template = { oneLiner, keyExamples, run };
package/src/devops.ts CHANGED
@@ -1,76 +1,90 @@
1
1
  #!/usr/bin/env bun
2
2
  // This file behaves as a façade for various devops scripts
3
+ import { globSync } from "glob";
3
4
  import { CLICommandParser, printUsageAndExit } from "./cli/common";
4
- import affected from "./cli/affected";
5
- import constant from "./cli/constant";
6
- import console from "./cli/console";
7
- import db from "./cli/db";
8
- import dml from "./cli/dml";
9
- import registry from "./cli/registry";
10
- import env from "./cli/env";
11
- import exec from "./cli/exec";
12
- import prepBuild from "./cli/prep-build";
13
- import prisma from "./cli/prisma";
14
- import run from "./cli/run";
15
- import runMany from "./cli/run-many";
16
- import test from "./cli/test";
17
- import init from "./cli/init";
18
- import redis from "./cli/redis";
19
- import internalCurl from "./cli/internal-curl";
20
- import jwt from "./cli/jwt";
21
- import namespace from "./cli/namespace";
22
- import image from "./cli/image";
23
- import template from "./cli/template";
24
- import job from "./cli/job";
25
- import cloudrun from "./cli/cloudrun";
5
+ import * as coreImports from "./cli/core";
6
+ import * as extensionImports from "./cli/extensions";
7
+ import { getConst } from "./libs/config";
8
+ import { existsSync, readdirSync } from "fs";
9
+ import path from "path";
26
10
 
27
11
  const [_node, _scriptPath, ...commandArgs] = process.argv;
28
12
 
29
- const allImports = [
30
- // day-to-day
31
- init,
32
- run,
33
- runMany,
34
- exec,
35
- env,
36
- prisma,
37
- dml,
38
- db,
39
- redis,
40
- console,
41
- test,
42
- //= Infra
43
- namespace,
44
- image,
45
- template,
46
- job,
47
- //= Deployment
48
- prepBuild,
49
- cloudrun,
50
- affected,
51
- constant,
52
- registry,
53
- internalCurl,
54
- jwt,
55
- ];
56
-
57
- const commands: {
13
+ // Types
14
+ type CommandMap = {
58
15
  [key: string]: {
59
16
  oneLiner: string;
60
17
  keyExamples: string;
61
18
  run: CallableFunction;
62
19
  key: string;
63
20
  };
64
- } = {};
65
- allImports.forEach((imported) => {
66
- Object.entries(imported).forEach(([key, object]) => {
67
- const { oneLiner, keyExamples, run } = object;
68
- commands[key] = { oneLiner, keyExamples, run, key };
69
- });
70
- });
21
+ }
71
22
 
72
- const keyLength = Math.max(...Object.keys(commands).map((x) => x.length)) + 10;
23
+ // Presentation
73
24
  const newLine = "\n ";
25
+ function maxKeyLength(commands: CommandMap) {
26
+ return Math.max(...Object.keys(commands).map((x) => x.length)) + 10;
27
+ }
28
+
29
+ // Core commands
30
+ const coreCommands: CommandMap = {};
31
+ Object.entries(coreImports).forEach(([constKey, imported]) => {
32
+ const { oneLiner, keyExamples, run } = imported;
33
+ const key = 'command' in imported ? imported.command : constKey;
34
+ coreCommands[key] = { oneLiner, keyExamples, run, key };
35
+ });
36
+ const coreCommandsKeyLength = maxKeyLength(coreCommands);
37
+
38
+ // Extensions
39
+ const extensionCommands: CommandMap = {};
40
+ const activeExtensions = getConst('extensions', { ignoreIfInvalid: true });
41
+ if (activeExtensions?.length) {
42
+ const availableExtensionsLookup = Object.fromEntries(
43
+ Object.entries(extensionImports).map(([constKey, value]) => {
44
+ const { oneLiner, keyExamples, run } = value;
45
+ const keyInYaml = 'name' in value ? value.name : constKey;
46
+ const key = 'command' in value ? value.command : constKey;
47
+ return [keyInYaml, { oneLiner, keyExamples, run, key }];
48
+ })
49
+ );
50
+ for (const extension of activeExtensions) {
51
+ const extensionData = availableExtensionsLookup[extension];
52
+ if (!extensionData) {
53
+ console.error(`\nExtension "${extension}" referenced in constants.yaml is not supported\n\n`);
54
+ process.exit(1);
55
+ }
56
+ extensionCommands[extensionData.key] = extensionData;
57
+ }
58
+ }
59
+ const extensionCommandsKeyLength = maxKeyLength(extensionCommands);
60
+
61
+ // Plugins
62
+ const pluginCommands: CommandMap = {};
63
+ if (existsSync('.devops/plugins')) {
64
+ const pluginsDir = path.join(process.cwd(), '.devops/plugins');
65
+ const pluginFiles = globSync(path.join(pluginsDir, '*.ts'));
66
+ for (const pluginFile of pluginFiles) {
67
+ const plugin = await import(pluginFile);
68
+ const keys = Object.keys(plugin);
69
+ if (keys.length !== 1) {
70
+ console.error(`Plugin ${pluginFile} must export exactly one command`);
71
+ process.exit(1);
72
+ }
73
+ const constKey = keys[0];
74
+ const { oneLiner, keyExamples, run, command } = plugin[constKey];
75
+ const key = command ?? constKey;
76
+ if (!oneLiner || !keyExamples || !run) {
77
+ console.error(`Plugin ${pluginFile} must export oneLiner, keyExamples, and run`);
78
+ process.exit(1);
79
+ }
80
+ if (typeof run !== 'function') {
81
+ console.error(`Plugin ${pluginFile} must export a run function`);
82
+ process.exit(1);
83
+ }
84
+ pluginCommands[key] = { oneLiner, keyExamples, run, key };
85
+ }
86
+ }
87
+ const pluginCommandsKeyLength = maxKeyLength(pluginCommands);
74
88
 
75
89
  const GENERAL_USAGE = `
76
90
  Devops utilities for the monorepo.
@@ -95,14 +109,36 @@ CHOOSING ENV with <env-options>
95
109
  To skip this check, use --skip-env-check.
96
110
 
97
111
 
98
- COMMANDS
99
- ${Object.values(commands)
112
+ CORE COMMANDS
113
+ ${Object.values(coreCommands)
100
114
  .map((cmd) =>
101
- [cmd.key, " ".repeat(keyLength - cmd.key.length), cmd.oneLiner].join("")
115
+ [cmd.key, " ".repeat(coreCommandsKeyLength - cmd.key.length), cmd.oneLiner].join("")
102
116
  )
103
117
  .join(newLine)}
104
118
  `;
105
119
 
120
+ const EXTENSION_USAGE = Object.keys(extensionCommands).length ? `
121
+ ACTIVE EXTENSIONS
122
+ ${Object.values(extensionCommands)
123
+ .map((cmd) =>
124
+ [cmd.key, " ".repeat(extensionCommandsKeyLength - cmd.key.length), cmd.oneLiner].join("")
125
+ )
126
+ .join(newLine)}
127
+ ` : '';
128
+
129
+ const PLUGIN_USAGE = Object.keys(pluginCommands).length ? `
130
+ ACTIVE PLUGINS
131
+ ${Object.values(pluginCommands)
132
+ .map((cmd) =>
133
+ [cmd.key, " ".repeat(pluginCommandsKeyLength - cmd.key.length), cmd.oneLiner].join("")
134
+ )
135
+ .join(newLine)}
136
+ ` : '';
137
+
138
+ const ALL_USAGE = [GENERAL_USAGE, EXTENSION_USAGE, PLUGIN_USAGE].filter(Boolean).join("");
139
+
140
+ const allCommands = { ...coreCommands, ...extensionCommands, ...pluginCommands };
141
+
106
142
  // EXAMPLES
107
143
  // ${Object.values(commands)
108
144
  // .map((cmd) =>
@@ -115,7 +151,7 @@ COMMANDS
115
151
  // .join(newLine)}
116
152
 
117
153
  const commandObj = new CLICommandParser(commandArgs,);
118
- const chosenCommand = commands[commandObj.command];
119
- if (!chosenCommand) printUsageAndExit(GENERAL_USAGE);
154
+ const chosenCommand = allCommands[commandObj.command];
155
+ if (!chosenCommand) printUsageAndExit(ALL_USAGE);
120
156
 
121
157
  chosenCommand.run(commandObj);
@@ -41,8 +41,7 @@ export function generateImageDeployments(
41
41
  const renderFn = (template: string) => Handlebars.compile(template)(context);
42
42
  return generateManifestForDeployment(projectData.rootPath, projectData.deployment!.template, renderFn);
43
43
  });
44
- const debug = generateDebugDeployment(monorepoEnv, image, gitSha);
45
- const manifest = [debug, ...apps].filter(Boolean).join("\n---\n");
44
+ const manifest = apps.filter(Boolean).join("\n---\n");
46
45
  return ensureProperDomainsPresent(manifest, monorepoEnv, image);
47
46
  }
48
47
 
@@ -55,7 +54,7 @@ export function generateWorkspaceDeployment(packageData: PackageData, monorepoEn
55
54
  return ensureProperDomainsPresent(manifest, monorepoEnv, image);
56
55
  }
57
56
 
58
- export function generateDebugDeployment(
57
+ export function generateDebugPod(
59
58
  monorepoEnv: string,
60
59
  image: string,
61
60
  gitSha: string
@@ -66,7 +65,7 @@ export function generateDebugDeployment(
66
65
  const renderFn = (template: string) => Handlebars.compile(template)(context);
67
66
  const debugTemplate = getImageData(image)["debug-template"];
68
67
  if (!debugTemplate) return;
69
- return generateManifestsFromTemplateName(debugTemplate, renderFn).map(x => yaml.stringify(x)).join("\n---\n");
68
+ return generateManifestsFromTemplateName(debugTemplate, renderFn, { validate: false }).map(x => yaml.stringify(x)).join("\n---\n");
70
69
  }
71
70
 
72
71
  export function generateDbMigrateJob(
@@ -107,13 +106,13 @@ function generateManifestForDeployment(rootPath: string, templateName: string, r
107
106
 
108
107
  // L2 generation
109
108
 
110
- function generateManifestsFromTemplateName(templateName: string, renderFn: RenderFn): object[] {
109
+ function generateManifestsFromTemplateName(templateName: string, renderFn: RenderFn, options: { validate: boolean } = { validate: true }): object[] {
111
110
  const entries = manifestFilesForTemplate(templateName);
112
111
  if (!entries) {
113
112
  console.error(`No entries found for ${templateName} in ${MANIFEST_INDEX_FILE_PATH}`);
114
113
  process.exit(1);
115
114
  }
116
- return generateManifestsFromFileList(entries.map(entry => path.join(MANIFEST_FOLDER_PATH, entry)), renderFn);
115
+ return generateManifestsFromFileList(entries.map(entry => path.join(MANIFEST_FOLDER_PATH, entry)), renderFn, options);
117
116
  }
118
117
 
119
118
  // L2 generation
@@ -129,19 +128,21 @@ function generateManifestFromFilesInFolder(folderPath: string, renderFn: RenderF
129
128
 
130
129
  // L3 generation
131
130
 
132
- function generateManifestsFromFileList(filesList: string[], renderFn: RenderFn): object[] {
131
+ function generateManifestsFromFileList(filesList: string[], renderFn: RenderFn, options: { validate: boolean } = { validate: true }): object[] {
133
132
  return filesList.flatMap((filePath) => {
134
133
  try {
135
134
  const manifestFileStr = fs.readFileSync(filePath, 'utf8');
136
135
  const renderedStr = renderFn(manifestFileStr);
137
136
  const res = yaml.parseAllDocuments(renderedStr);
138
- res.forEach((doc) => {
139
- if (!doc.get("kind") || !doc.getIn(["metadata", "name"])) {
140
- console.error(`Invalid manifest file ${filePath}: kind and metadata.name must be present`);
141
- console.error(doc.toString())
142
- process.exit(1);
143
- }
144
- })
137
+ if (options.validate) {
138
+ res.forEach((doc) => {
139
+ if (!doc.get("kind") || !doc.getIn(["metadata", "name"])) {
140
+ console.error(`Invalid manifest file ${filePath}: kind and metadata.name must be present`);
141
+ console.error(doc.toString())
142
+ process.exit(1);
143
+ }
144
+ })
145
+ }
145
146
  return res.map(x => x.toJSON());
146
147
  } catch (e) {
147
148
  if (e instanceof Error) {
@@ -0,0 +1,16 @@
1
+ import { CommandExecutor } from "../cli/common";
2
+ import { kubectlCommand } from "./k8s-helpers";
3
+
4
+ export function getRedisList() {
5
+ const cmd = kubectlCommand(`get pods -l app=redis-ha -A`);
6
+ const res = new CommandExecutor(cmd, { quiet: true }).exec();
7
+ if (!res) return null;
8
+ return res;
9
+ }
10
+
11
+ export function establishRedisTunnel(namespace: string, port: string) {
12
+ const cmd = kubectlCommand(`port-forward svc/${namespace}-redis-ha ${port}:6379`, {
13
+ namespace,
14
+ });
15
+ new CommandExecutor(cmd).spawn();
16
+ }
package/src/plugins.ts ADDED
@@ -0,0 +1,8 @@
1
+ export { CommandExecutor, CLICommandParser, printUsageAndExit, StrongParams } from "./cli/common";
2
+ export { kubectlCommand } from "./libs/k8s-helpers";
3
+
4
+ import url from "url";
5
+ import path from "path";
6
+ const __file__ = url.fileURLToPath(import.meta.url);
7
+ const __cli__ = path.join(path.dirname(__file__), "cli");
8
+ export const execShPath = path.join(__cli__, "exec.sh");
@@ -1,45 +1,42 @@
1
- apiVersion: apps/v1
2
- kind: Deployment
1
+ apiVersion: v1
2
+ kind: Pod
3
3
  metadata:
4
+ # Name and namespace should not be stated - they are provided by the runner
4
5
  labels:
5
6
  app: {{debug_pod_name}}
6
7
  env: {{monorepo_env}}
7
- name: {{debug_pod_name}}
8
- namespace: {{namespace}}
8
+ ephemeral-shell: "true"
9
9
  spec:
10
- selector:
11
- matchLabels:
12
- app: {{debug_pod_name}}
13
- template:
14
- metadata:
15
- labels:
16
- app: {{debug_pod_name}}
17
- env: {{monorepo_env}}
18
- spec:
19
- volumes:
10
+ volumes:
11
+ - name: secret-injection-hook
12
+ secret:
13
+ secretName: {{env_secret_name}}
14
+ containers:
15
+ - image: {{image_path}}
16
+ name: {{debug_pod_name}}
17
+ stdin: true
18
+ tty: true
19
+ command:
20
+ - ./node-exec.sh
21
+ args:
22
+ - /bin/bash
23
+ env:
24
+ - name: MONOREPO_ENV
25
+ value: {{monorepo_env}}
26
+ - name: MONOREPO_NAMESPACE
27
+ value: {{namespace}}
28
+ - name: IS_KUBERNETES
29
+ value: 'true'
30
+ - name: MONOREPO_BASE_SECRET
31
+ valueFrom:
32
+ secretKeyRef:
33
+ name: {{env_secret_name}}
34
+ key: {{env_base_secret_key}}
35
+ volumeMounts:
20
36
  - name: secret-injection-hook
21
- secret:
22
- secretName: {{env_secret_name}}
23
- containers:
24
- - image: {{image_path}}
25
- name: {{debug_pod_name}}
26
- env:
27
- - name: MONOREPO_ENV
28
- value: {{monorepo_env}}
29
- - name: MONOREPO_NAMESPACE
30
- value: {{namespace}}
31
- - name: IS_KUBERNETES
32
- value: 'true'
33
- - name: MONOREPO_BASE_SECRET
34
- valueFrom:
35
- secretKeyRef:
36
- name: {{env_secret_name}}
37
- key: {{env_base_secret_key}}
38
- volumeMounts:
39
- - name: secret-injection-hook
40
- mountPath: /etc/kubernetes/secrets
41
- readOnly: true
42
- resources:
43
- requests:
44
- memory: 250Mi
45
- cpu: 100m
37
+ mountPath: /etc/kubernetes/secrets
38
+ readOnly: true
39
+ resources:
40
+ requests:
41
+ memory: 250Mi
42
+ cpu: 100m
@@ -14,6 +14,7 @@ export const constFileSchema = z.object({
14
14
  "cloudrun-artifact-registry-repo-path": z.string().optional(),
15
15
  "extra-remote-environments": z.array(z.string()),
16
16
  "extra-local-environments": z.array(z.string()),
17
+ "extensions": z.array(z.string()).optional(),
17
18
  })
18
19
  export type ConstFileSchema = z.infer<typeof constFileSchema>;
19
20
 
@@ -1,11 +0,0 @@
1
- import { CLICommandParser } from "./common";
2
- declare function run(cmdObj: CLICommandParser): Promise<void>;
3
- declare const _default: {
4
- affected: {
5
- oneLiner: string;
6
- keyExamples: string;
7
- run: typeof run;
8
- };
9
- };
10
- export default _default;
11
- //# sourceMappingURL=affected.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"affected.d.ts","sourceRoot":"","sources":["../../src/cli/affected.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAmC,MAAM,UAAU,CAAC;AAoD7E,iBAAe,GAAG,CAAC,MAAM,EAAE,gBAAgB,iBAoD1C;;;;;;;;AAED,wBAEE"}
@@ -1,11 +0,0 @@
1
- import { CLICommandParser } from "./common";
2
- declare function run(cmdObj: CLICommandParser): Promise<void>;
3
- declare const _default: {
4
- cloudrun: {
5
- oneLiner: string;
6
- keyExamples: string;
7
- run: typeof run;
8
- };
9
- };
10
- export default _default;
11
- //# sourceMappingURL=cloudrun.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cloudrun.d.ts","sourceRoot":"","sources":["../../src/cli/cloudrun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAmC,MAAM,UAAU,CAAC;AA6E7E,iBAAe,GAAG,CAAC,MAAM,EAAE,gBAAgB,iBAmD1C;;;;;;;;AAED,wBAEE"}
@@ -1,11 +0,0 @@
1
- import { CLICommandParser } from "./common";
2
- declare function run(cmdObj: CLICommandParser): void;
3
- declare const _default: {
4
- console: {
5
- oneLiner: string;
6
- keyExamples: string;
7
- run: typeof run;
8
- };
9
- };
10
- export default _default;
11
- //# sourceMappingURL=console.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/cli/console.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAqB,MAAM,UAAU,CAAC;AAgB/D,iBAAS,GAAG,CAAC,MAAM,EAAE,gBAAgB,QAmBpC;;;;;;;;AAED,wBAEE"}
@@ -1,35 +0,0 @@
1
- import { getConst } from "../libs/config";
2
- import { envToNamespace, imageDebugName, } from "../libs/k8s-constants";
3
- import { kubectlCommand } from "../libs/k8s-helpers";
4
- import { CLICommandParser, printUsageAndExit } from "./common";
5
- const oneLiner = "Get a shell into the debug pod of an image";
6
- const keyExamples = `
7
- $ devops console main-node
8
- `.trim();
9
- const usage = `
10
- ${oneLiner}
11
-
12
- Each image has a debug pod. This command gets a shell into the debug pod of the specified image.
13
-
14
- EXAMPLES
15
- ${keyExamples}
16
- `;
17
- function run(cmdObj) {
18
- if (cmdObj.help || cmdObj.args.length === 0)
19
- printUsageAndExit(usage);
20
- const image = cmdObj.args[0];
21
- const debugName = imageDebugName(image);
22
- const namespace = envToNamespace(cmdObj.env);
23
- const podName = cmdObj
24
- .executorFromEnv(kubectlCommand(`get pod -n ${namespace} -l app=${debugName} -o name`, {
25
- namespace,
26
- }), { quiet: true })
27
- .exec()
28
- .trim();
29
- cmdObj
30
- .executorFromEnv(kubectlCommand(`exec -it ${podName} -- /bin/bash`, { namespace }))
31
- .spawn();
32
- }
33
- export default {
34
- console: { oneLiner, keyExamples, run },
35
- };
@@ -1,11 +0,0 @@
1
- import { CLICommandParser } from "./common";
2
- declare function run(cmdObj: CLICommandParser): Promise<void>;
3
- declare const _default: {
4
- constant: {
5
- oneLiner: string;
6
- keyExamples: string;
7
- run: typeof run;
8
- };
9
- };
10
- export default _default;
11
- //# sourceMappingURL=constant.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constant.d.ts","sourceRoot":"","sources":["../../src/cli/constant.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAqB,MAAM,UAAU,CAAC;AAe/D,iBAAe,GAAG,CAAC,MAAM,EAAE,gBAAgB,iBAI1C;;;;;;;;AAED,wBAEE"}
package/dist/cli/db.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { CLICommandParser } from "./common";
2
- declare function run(cmdObj: CLICommandParser): void;
3
- declare const _default: {
4
- db: {
5
- oneLiner: string;
6
- keyExamples: string;
7
- run: typeof run;
8
- };
9
- };
10
- export default _default;
11
- //# sourceMappingURL=db.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/cli/db.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAmC,MAAM,UAAU,CAAC;AAsG7E,iBAAS,GAAG,CAAC,MAAM,EAAE,gBAAgB,QAiBpC;;;;;;;;AAED,wBAEE"}
package/dist/cli/dml.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { CLICommandParser } from "./common";
2
- declare function run(cmdObj: CLICommandParser): void;
3
- declare const _default: {
4
- dml: {
5
- oneLiner: string;
6
- keyExamples: string;
7
- run: typeof run;
8
- };
9
- };
10
- export default _default;
11
- //# sourceMappingURL=dml.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dml.d.ts","sourceRoot":"","sources":["../../src/cli/dml.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAqB,MAAM,UAAU,CAAC;AAoG/D,iBAAS,GAAG,CAAC,MAAM,EAAE,gBAAgB,QAoBpC;;;;;;;;AAED,wBAEE"}
package/dist/cli/env.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { CLICommandParser } from "./common";
2
- declare function run(cmdObj: CLICommandParser): void;
3
- declare const _default: {
4
- env: {
5
- oneLiner: string;
6
- keyExamples: string;
7
- run: typeof run;
8
- };
9
- };
10
- export default _default;
11
- //# sourceMappingURL=env.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/cli/env.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,gBAAgB,EAGjB,MAAM,UAAU,CAAC;AAwBlB,iBAAS,GAAG,CAAC,MAAM,EAAE,gBAAgB,QA+CpC;;;;;;;;AAED,wBAEE"}
@@ -1,11 +0,0 @@
1
- import { CLICommandParser } from "./common";
2
- declare function run(cmdObj: CLICommandParser): void;
3
- declare const _default: {
4
- exec: {
5
- oneLiner: string;
6
- keyExamples: string;
7
- run: typeof run;
8
- };
9
- };
10
- export default _default;
11
- //# sourceMappingURL=exec.d.ts.map