pepr 0.51.6 → 0.52.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 (75) hide show
  1. package/dist/cli/build.d.ts +2 -2
  2. package/dist/cli/build.d.ts.map +1 -1
  3. package/dist/cli/build.helpers.d.ts +1 -1
  4. package/dist/cli/build.helpers.d.ts.map +1 -1
  5. package/dist/cli/crd/create.d.ts +0 -1
  6. package/dist/cli/crd/create.d.ts.map +1 -1
  7. package/dist/cli/crd/generate.d.ts.map +1 -1
  8. package/dist/cli/crd/index.d.ts +2 -2
  9. package/dist/cli/crd/index.d.ts.map +1 -1
  10. package/dist/cli/deploy.d.ts +3 -3
  11. package/dist/cli/deploy.d.ts.map +1 -1
  12. package/dist/cli/dev.d.ts +2 -2
  13. package/dist/cli/dev.d.ts.map +1 -1
  14. package/dist/cli/format/index.d.ts +2 -2
  15. package/dist/cli/format/index.d.ts.map +1 -1
  16. package/dist/cli/init/index.d.ts +2 -2
  17. package/dist/cli/init/index.d.ts.map +1 -1
  18. package/dist/cli/init/templates.d.ts +13 -12
  19. package/dist/cli/init/templates.d.ts.map +1 -1
  20. package/dist/cli/init/walkthrough.d.ts.map +1 -1
  21. package/dist/cli/kfc.d.ts +2 -2
  22. package/dist/cli/kfc.d.ts.map +1 -1
  23. package/dist/cli/monitor.d.ts +2 -2
  24. package/dist/cli/monitor.d.ts.map +1 -1
  25. package/dist/cli/update/index.d.ts +2 -2
  26. package/dist/cli/update/index.d.ts.map +1 -1
  27. package/dist/cli/uuid.d.ts +2 -2
  28. package/dist/cli/uuid.d.ts.map +1 -1
  29. package/dist/cli.js +296 -204
  30. package/dist/controller.js +1 -1
  31. package/dist/lib/assets/assets.d.ts +13 -2
  32. package/dist/lib/assets/assets.d.ts.map +1 -1
  33. package/dist/lib/assets/deploy.d.ts.map +1 -1
  34. package/dist/lib/assets/{envrionment.d.ts → environment.d.ts} +1 -1
  35. package/dist/lib/assets/environment.d.ts.map +1 -0
  36. package/dist/lib/assets/helm.d.ts +4 -3
  37. package/dist/lib/assets/helm.d.ts.map +1 -1
  38. package/dist/lib/assets/{pods.d.ts → k8sObjects.d.ts} +4 -2
  39. package/dist/lib/assets/k8sObjects.d.ts.map +1 -0
  40. package/dist/lib/assets/networking.d.ts +0 -2
  41. package/dist/lib/assets/networking.d.ts.map +1 -1
  42. package/dist/lib/assets/yaml/generateAllYaml.d.ts +8 -3
  43. package/dist/lib/assets/yaml/generateAllYaml.d.ts.map +1 -1
  44. package/dist/lib/assets/yaml/overridesFile.d.ts +4 -1
  45. package/dist/lib/assets/yaml/overridesFile.d.ts.map +1 -1
  46. package/package.json +19 -19
  47. package/src/cli/build.helpers.ts +26 -14
  48. package/src/cli/build.ts +37 -47
  49. package/src/cli/crd/create.ts +15 -20
  50. package/src/cli/crd/generate.ts +9 -6
  51. package/src/cli/crd/index.ts +2 -2
  52. package/src/cli/deploy.ts +16 -16
  53. package/src/cli/dev.ts +8 -8
  54. package/src/cli/format/index.ts +5 -4
  55. package/src/cli/init/index.ts +12 -9
  56. package/src/cli/init/walkthrough.ts +2 -4
  57. package/src/cli/kfc.ts +17 -13
  58. package/src/cli/monitor.ts +2 -2
  59. package/src/cli/update/index.ts +11 -11
  60. package/src/cli/uuid.ts +2 -2
  61. package/src/cli.ts +2 -2
  62. package/src/lib/assets/assets.ts +81 -22
  63. package/src/lib/assets/deploy.ts +26 -12
  64. package/src/lib/assets/helm.ts +31 -3
  65. package/src/lib/assets/{pods.ts → k8sObjects.ts} +69 -22
  66. package/src/lib/assets/networking.ts +0 -52
  67. package/src/lib/assets/yaml/generateAllYaml.ts +38 -11
  68. package/src/lib/assets/yaml/overridesFile.ts +4 -1
  69. package/src/templates/tsconfig.module.json +2 -2
  70. package/dist/cli/root.d.ts +0 -5
  71. package/dist/cli/root.d.ts.map +0 -1
  72. package/dist/lib/assets/envrionment.d.ts.map +0 -1
  73. package/dist/lib/assets/pods.d.ts.map +0 -1
  74. package/src/cli/root.ts +0 -12
  75. /package/src/lib/assets/{envrionment.ts → environment.ts} +0 -0
@@ -4,6 +4,7 @@
4
4
  import { Command } from "commander";
5
5
  import fs from "fs";
6
6
  import path from "path";
7
+ import Log from "../../lib/telemetry/logger";
7
8
  import { stringify } from "yaml";
8
9
  import {
9
10
  Project,
@@ -20,8 +21,10 @@ import { V1JSONSchemaProps } from "@kubernetes/client-node";
20
21
  import { WarningMessages, ErrorMessages } from "./messages";
21
22
 
22
23
  export default new Command("generate")
23
- .description("Generate CRD manifests from TypeScript definitions")
24
- .option("--output <output>", "Output directory for generated CRDs", "./crds")
24
+ .description(
25
+ "Generate CRD manifests from TypeScript definitions stored in 'api/' of the current directory.",
26
+ )
27
+ .option("-o, --output <directory>", "Output directory for generated CRDs", "./crds")
25
28
  .action(generateCRDs);
26
29
 
27
30
  export function extractCRDDetails(
@@ -48,7 +51,7 @@ export function extractCRDDetails(
48
51
  }
49
52
 
50
53
  export async function generateCRDs(options: { output: string }): Promise<void> {
51
- console.log("This feature is currently in alpha.\n");
54
+ Log.warn("This feature is currently in alpha.\n");
52
55
  const outputDir = path.resolve(options.output);
53
56
  await createDirectoryIfNotExists(outputDir);
54
57
 
@@ -83,13 +86,13 @@ export function processSourceFile(
83
86
  const { kind, fqdn, scope, plural, shortNames } = extractCRDDetails(content, sourceFile);
84
87
 
85
88
  if (!kind) {
86
- console.warn(WarningMessages.MISSING_KIND_COMMENT(sourceFile.getBaseName()));
89
+ Log.warn(WarningMessages.MISSING_KIND_COMMENT(sourceFile.getBaseName()));
87
90
  return;
88
91
  }
89
92
 
90
93
  const spec = sourceFile.getInterface(`${kind}Spec`);
91
94
  if (!spec) {
92
- console.warn(WarningMessages.MISSING_INTERFACE(sourceFile.getBaseName(), kind));
95
+ Log.warn(WarningMessages.MISSING_INTERFACE(sourceFile.getBaseName(), kind));
93
96
  return;
94
97
  }
95
98
 
@@ -110,7 +113,7 @@ export function processSourceFile(
110
113
 
111
114
  const outPath = path.join(outputDir, `${kind.toLowerCase()}.yaml`);
112
115
  fs.writeFileSync(outPath, stringify(crd), "utf8");
113
- console.log(`✔ Created ${outPath}`);
116
+ Log.info(`✔ Created ${outPath}`);
114
117
  }
115
118
 
116
119
  // Extracts a comment from the content of a file based on a label.
@@ -1,11 +1,11 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
3
 
4
- import { RootCmd } from "../root";
4
+ import { Command } from "commander";
5
5
  import createCmd from "./create";
6
6
  import generateCmd from "./generate";
7
7
 
8
- export default function (program: RootCmd): void {
8
+ export default function (program: Command): void {
9
9
  const crd = program
10
10
  .command("crd")
11
11
  .description("Scaffold and generate Kubernetes CRDs from structured TypeScript definitions");
package/src/cli/deploy.ts CHANGED
@@ -5,7 +5,7 @@ import prompt from "prompts";
5
5
  import { CapabilityExport } from "../lib/types";
6
6
  import { Assets } from "../lib/assets/assets";
7
7
  import { ImagePullSecret } from "../lib/types";
8
- import { RootCmd } from "./root";
8
+ import { Command } from "commander";
9
9
  import { buildModule } from "./build";
10
10
  import { deployImagePullSecret, deployWebhook } from "../lib/assets/deploy";
11
11
  import { namespaceDeploymentsReady } from "../lib/deploymentChecks";
@@ -54,7 +54,7 @@ export function validateImagePullSecretDetails(details: ImagePullSecretDetails):
54
54
  if (missing.length > 0) {
55
55
  return {
56
56
  valid: false,
57
- error: `Error: Must provide ${missing.join(", ")} when providing --pullSecret`,
57
+ error: `Error: Must provide ${missing.join(", ")} when providing --pull-secret`,
58
58
  };
59
59
  }
60
60
 
@@ -79,19 +79,19 @@ function generateImagePullSecret(details: ValidatedImagePullSecretDetails): Imag
79
79
  };
80
80
  }
81
81
 
82
- export async function getUserConfirmation(opts: { confirm: boolean }): Promise<boolean> {
83
- if (opts.confirm) {
82
+ export async function getUserConfirmation(opts: { yes: boolean }): Promise<boolean> {
83
+ if (opts.yes) {
84
84
  return true;
85
85
  }
86
86
 
87
87
  // Prompt the user to confirm
88
- const confirm = await prompt({
88
+ const confirmation = await prompt({
89
89
  type: "confirm",
90
- name: "confirm",
90
+ name: "yes",
91
91
  message: "This will remove and redeploy the module. Continue?",
92
92
  });
93
93
 
94
- return confirm.confirm ? true : false;
94
+ return confirmation.yes ? true : false;
95
95
  }
96
96
 
97
97
  async function buildAndDeployModule(image: string, force: boolean): Promise<void> {
@@ -126,18 +126,18 @@ async function buildAndDeployModule(image: string, force: boolean): Promise<void
126
126
  }
127
127
  }
128
128
 
129
- export default function (program: RootCmd): void {
129
+ export default function (program: Command): void {
130
130
  program
131
131
  .command("deploy")
132
132
  .description("Deploy a Pepr Module")
133
- .option("-i, --image [image]", "Override the image tag")
134
- .option("--confirm", "Skip confirmation prompt")
135
- .option("--pullSecret <name>", "Deploy imagePullSecret for Controller private registry")
136
- .option("--docker-server <server>", "Docker server address")
137
- .option("--docker-username <username>", "Docker registry username")
138
- .option("--docker-email <email>", "Email for Docker registry")
139
- .option("--docker-password <password>", "Password for Docker registry")
140
- .option("--force", "Force deploy the module, override manager field")
133
+ .option("-E, --docker-email <email>", "Email for Docker registry.")
134
+ .option("-P, --docker-password <password>", "Password for Docker registry.")
135
+ .option("-S, --docker-server <server>", "Docker server address.")
136
+ .option("-U, --docker-username <username>", "Docker registry username.")
137
+ .option("-f, --force", "Force deploy the module, override manager field.")
138
+ .option("-i, --image <image>", "Override the image tag.")
139
+ .option("-p, --pull-secret <name>", "Deploy imagePullSecret for Controller private registry.")
140
+ .option("-y, --yes", "Skip confirmation prompts.")
141
141
  .action(async opts => {
142
142
  const valResp = validateImagePullSecretDetails(opts);
143
143
  if (!valResp.valid) {
package/src/cli/dev.ts CHANGED
@@ -5,30 +5,30 @@ import prompt from "prompts";
5
5
  import { Assets } from "../lib/assets/assets";
6
6
  import { ChildProcess, fork } from "child_process";
7
7
  import { K8s, kind } from "kubernetes-fluent-client";
8
- import { RootCmd } from "./root";
8
+ import { Command } from "commander";
9
9
  import { Store } from "../lib/k8s";
10
10
  import { buildModule, loadModule } from "./build";
11
11
  import { deployWebhook } from "../lib/assets/deploy";
12
12
  import { promises as fs } from "fs";
13
13
  import { validateCapabilityNames } from "../lib/helpers";
14
14
 
15
- export default function (program: RootCmd): void {
15
+ export default function (program: Command): void {
16
16
  program
17
17
  .command("dev")
18
18
  .description("Setup a local webhook development environment")
19
- .option("-h, --host [host]", "Host to listen on", "host.k3d.internal")
20
- .option("--confirm", "Skip confirmation prompt")
19
+ .option("-H, --host <host>", "Host to listen on", "host.k3d.internal")
20
+ .option("-y, --yes", "Skip confirmation prompt")
21
21
  .action(async opts => {
22
- // Prompt the user to confirm if they didn't pass the --confirm flag
23
- if (!opts.confirm) {
22
+ // Prompt the user to confirm if they didn't pass the --yes flag
23
+ if (!opts.yes) {
24
24
  const confirm = await prompt({
25
25
  type: "confirm",
26
- name: "confirm",
26
+ name: "yes",
27
27
  message: "This will remove and redeploy the module. Continue?",
28
28
  });
29
29
 
30
30
  // Exit if the user doesn't confirm
31
- if (!confirm.confirm) {
31
+ if (!confirm.yes) {
32
32
  process.exitCode = 0;
33
33
  return;
34
34
  }
@@ -4,9 +4,10 @@
4
4
  import { ESLint } from "eslint";
5
5
  import { formatWithPrettier } from "./format.helpers";
6
6
 
7
- import { RootCmd } from "../root";
7
+ import { Command } from "commander";
8
+ import Log from "../../lib/telemetry/logger";
8
9
 
9
- export default function (program: RootCmd): void {
10
+ export default function (program: Command): void {
10
11
  program
11
12
  .command("format")
12
13
  .description("Lint and format this Pepr module")
@@ -47,7 +48,7 @@ export async function peprFormat(validateOnly: boolean): Promise<boolean> {
47
48
  const resultText = await formatter.format(results, {} as ESLint.LintResultData);
48
49
 
49
50
  if (resultText) {
50
- console.log(resultText);
51
+ Log.info(resultText);
51
52
  }
52
53
 
53
54
  // Write the fixes if not in validate-only mode
@@ -55,7 +56,7 @@ export async function peprFormat(validateOnly: boolean): Promise<boolean> {
55
56
  await ESLint.outputFixes(results);
56
57
  }
57
58
 
58
- hasFailure = await formatWithPrettier(results, validateOnly);
59
+ hasFailure = hasFailure || (await formatWithPrettier(results, validateOnly));
59
60
 
60
61
  return !hasFailure;
61
62
  } catch (e) {
@@ -5,7 +5,7 @@ import { execSync } from "child_process";
5
5
  import { resolve } from "path";
6
6
  import prompts from "prompts";
7
7
 
8
- import { RootCmd } from "../root";
8
+ import { Command } from "commander";
9
9
  import {
10
10
  codeSettings,
11
11
  eslint,
@@ -24,20 +24,22 @@ import { createDir, sanitizeName, write } from "./utils";
24
24
  import { confirm, PromptOptions, walkthrough } from "./walkthrough";
25
25
  import { ErrorList } from "../../lib/errors";
26
26
  import { UUID_LENGTH_LIMIT } from "./enums";
27
+ import { Option } from "commander";
27
28
 
28
- export default function (program: RootCmd): void {
29
+ export default function (program: Command): void {
29
30
  let response = {} as PromptOptions;
30
31
  let pkgOverride = "";
31
32
  program
32
33
  .command("init")
33
34
  .description("Initialize a new Pepr Module")
34
- .option("--confirm", "Skip verification prompt when creating a new module.")
35
- .option("--description <string>", "Explain the purpose of the new module.")
36
- .option("--name <string>", "Set the name of the new module.")
37
- .option("--skip-post-init", "Skip npm install, git init, and VSCode launch.")
38
- .option(`--errorBehavior <${ErrorList.join("|")}>`, "Set an errorBehavior.")
35
+ .option("-d, --description <string>", "Explain the purpose of the new module.")
36
+ .addOption(
37
+ new Option("-e, --error-behavior <behavior>", "Set an error behavior.").choices(ErrorList),
38
+ )
39
+ .option("-n, --name <string>", "Set the name of the new module.")
40
+ .option("-s, --skip-post-init", "Skip npm install, git init, and VSCode launch.")
39
41
  .option(
40
- "--uuid [string]",
42
+ "-u, --uuid <string>",
41
43
  "Unique identifier for your module with a max length of 36 characters.",
42
44
  (uuid: string): string => {
43
45
  if (uuid.length > UUID_LENGTH_LIMIT) {
@@ -46,6 +48,7 @@ export default function (program: RootCmd): void {
46
48
  return uuid.toLocaleLowerCase();
47
49
  },
48
50
  )
51
+ .option("-y, --yes", "Skip verification prompt when creating a new module.")
49
52
  .hook("preAction", async thisCommand => {
50
53
  // TODO: Overrides for testing. Don't be so gross with Node CLI testing
51
54
  // TODO: See pepr/#1140
@@ -68,7 +71,7 @@ export default function (program: RootCmd): void {
68
71
  const dirName = sanitizeName(response.name);
69
72
  const packageJSON = genPkgJSON(response, pkgOverride);
70
73
 
71
- const confirmed = await confirm(dirName, packageJSON, peprTSTemplate.path, opts.confirm);
74
+ const confirmed = await confirm(dirName, packageJSON, peprTSTemplate.path, opts.yes);
72
75
 
73
76
  if (confirmed) {
74
77
  console.log("Creating new Pepr module...");
@@ -137,7 +137,7 @@ export async function confirm(
137
137
  ): Promise<boolean> {
138
138
  const confirmationPrompt: PromptObject = {
139
139
  type: "confirm",
140
- name: "confirm",
140
+ name: "yes",
141
141
  message: "Create the new Pepr module?",
142
142
  };
143
143
  const confirmationMessage = `To be generated:
@@ -162,9 +162,7 @@ ${packageJSON.print.replace(/^/gm, " │ ")}
162
162
  console.log(confirmationMessage);
163
163
  const confirm = await prompt([confirmationPrompt]);
164
164
  const shouldCreateModule =
165
- confirm.confirm === "y" || confirm.confirm === "yes" || confirm.confirm === true
166
- ? true
167
- : false;
165
+ confirm.yes === "y" || confirm.yes === "yes" || confirm.yes === true ? true : false;
168
166
  return shouldCreateModule;
169
167
  }
170
168
  }
package/src/cli/kfc.ts CHANGED
@@ -4,24 +4,28 @@
4
4
  import { execSync } from "child_process";
5
5
  import prompt from "prompts";
6
6
 
7
- import { RootCmd } from "./root";
7
+ import { Command } from "commander";
8
8
 
9
- export default function (program: RootCmd): void {
9
+ export default function (program: Command): void {
10
10
  program
11
11
  .command("kfc [args...]")
12
12
  .description("Execute Kubernetes Fluent Client commands")
13
- .action(async (args: string[]) => {
14
- const { confirm } = await prompt({
15
- type: "confirm",
16
- name: "confirm",
17
- message:
18
- "For commands that generate files, this may overwrite any previously generated files.\n" +
19
- "Are you sure you want to continue?",
20
- });
13
+ .option("-y, --yes", "Skip confirmation prompt.")
14
+ .action(async (args: string[], options) => {
15
+ // Skip confirmation if yes flag is provided
16
+ if (!options.yes) {
17
+ const { confirm } = await prompt({
18
+ type: "confirm",
19
+ name: "confirm",
20
+ message:
21
+ "For commands that generate files, this may overwrite any previously generated files.\n" +
22
+ "Are you sure you want to continue?",
23
+ });
21
24
 
22
- // If the user doesn't confirm, exit
23
- if (!confirm) {
24
- return;
25
+ // If the user doesn't confirm, exit
26
+ if (!confirm) {
27
+ return;
28
+ }
25
29
  }
26
30
 
27
31
  try {
@@ -5,7 +5,7 @@ import { Log as K8sLog, KubeConfig, KubernetesListObject } from "@kubernetes/cli
5
5
  import { K8s, kind } from "kubernetes-fluent-client";
6
6
  import stream from "stream";
7
7
  import { ResponseItem } from "../lib/types";
8
- import { RootCmd } from "./root";
8
+ import { Command } from "commander";
9
9
 
10
10
  interface LogPayload {
11
11
  namespace: string;
@@ -22,7 +22,7 @@ interface LogPayload {
22
22
  };
23
23
  }
24
24
 
25
- export default function (program: RootCmd): void {
25
+ export default function (program: Command): void {
26
26
  program
27
27
  .command("monitor [module-uuid]")
28
28
  .description("Monitor a Pepr Module")
@@ -15,13 +15,14 @@ import {
15
15
  tsConfig,
16
16
  } from "../init/templates";
17
17
  import { write } from "../init/utils";
18
- import { RootCmd } from "../root";
18
+ import { Command } from "commander";
19
+ import Log from "../../lib/telemetry/logger";
19
20
 
20
- export default function (program: RootCmd): void {
21
+ export default function (program: Command): void {
21
22
  program
22
23
  .command("update")
23
24
  .description("Update this Pepr module. Not recommended for prod as it may change files.")
24
- .option("--skip-template-update", "Skip updating the template files")
25
+ .option("-s, --skip-template-update", "Do not update template files")
25
26
  .action(async opts => {
26
27
  if (!opts.skipTemplateUpdate) {
27
28
  const { confirm } = await prompt({
@@ -38,7 +39,7 @@ export default function (program: RootCmd): void {
38
39
  }
39
40
  }
40
41
 
41
- console.log("Updating the Pepr module...");
42
+ Log.info("Updating the Pepr module...");
42
43
 
43
44
  try {
44
45
  // Update Pepr for the module
@@ -53,9 +54,9 @@ export default function (program: RootCmd): void {
53
54
  });
54
55
  }
55
56
 
56
- console.log(`✅ Module updated successfully`);
57
- } catch (e) {
58
- console.error(`Error updating Pepr module:`, e);
57
+ Log.info(`✅ Module updated successfully`);
58
+ } catch (error) {
59
+ Log.error(error, `Error updating Pepr module:`);
59
60
  process.exitCode = 1;
60
61
  }
61
62
  });
@@ -64,7 +65,7 @@ export default function (program: RootCmd): void {
64
65
  .command("update-templates", { hidden: true })
65
66
  .description("Perform template updates")
66
67
  .action(async opts => {
67
- console.log("Updating Pepr config and template tiles...");
68
+ Log.info("Updating Pepr config and template files...");
68
69
 
69
70
  try {
70
71
  // Don't update the template files if the user specified the --skip-template-update flag
@@ -87,9 +88,8 @@ export default function (program: RootCmd): void {
87
88
  await write(tsPath, helloPepr.data);
88
89
  }
89
90
  }
90
- throw new Error("another error, for testing");
91
- } catch (e) {
92
- console.error(`Error updating template files:`, e);
91
+ } catch (error) {
92
+ Log.error(error, `Error updating template files:`);
93
93
  process.exitCode = 1;
94
94
  }
95
95
  });
package/src/cli/uuid.ts CHANGED
@@ -3,9 +3,9 @@
3
3
 
4
4
  import { KubernetesListObject } from "@kubernetes/client-node";
5
5
  import { K8s, kind } from "kubernetes-fluent-client";
6
- import { RootCmd } from "./root";
6
+ import { Command } from "commander";
7
7
 
8
- export default function (program: RootCmd): void {
8
+ export default function (program: Command): void {
9
9
  program
10
10
  .command("uuid [uuid]")
11
11
  .description("Module UUID(s) currently deployed in the cluster")
package/src/cli.ts CHANGED
@@ -12,7 +12,7 @@ import monitor from "./cli/monitor";
12
12
  import init from "./cli/init/index";
13
13
  import uuid from "./cli/uuid";
14
14
  import { version } from "./cli/init/templates";
15
- import { RootCmd } from "./cli/root";
15
+ import { Command } from "commander";
16
16
  import update from "./cli/update";
17
17
  import kfc from "./cli/kfc";
18
18
  import crd from "./cli/crd";
@@ -21,7 +21,7 @@ if (process.env.npm_lifecycle_event !== "npx") {
21
21
  console.info("Pepr should be run via `npx pepr <command>` instead of `pepr <command>`.");
22
22
  }
23
23
 
24
- const program = new RootCmd();
24
+ const program = new Command();
25
25
  if (!process.env.PEPR_NODE_WARNINGS) {
26
26
  process.removeAllListeners("warning");
27
27
  }
@@ -8,6 +8,7 @@ import {
8
8
  namespaceTemplate,
9
9
  clusterRoleTemplate,
10
10
  admissionDeployTemplate,
11
+ serviceTemplate,
11
12
  serviceMonitorTemplate,
12
13
  watcherDeployTemplate,
13
14
  } from "./helm";
@@ -23,10 +24,39 @@ import { loadCapabilities } from "./loader";
23
24
  import { namespaceComplianceValidator, dedent } from "../helpers";
24
25
  import { promises as fs } from "fs";
25
26
  import { storeRole, storeRoleBinding, clusterRoleBinding, serviceAccount } from "./rbac";
26
- import { watcherService, service, tlsSecret, apiPathSecret } from "./networking";
27
+ import { tlsSecret, apiPathSecret } from "./networking";
27
28
  import { WebhookType } from "../enums";
28
29
  import { kind } from "kubernetes-fluent-client";
29
30
 
31
+ export function norWatchOrAdmission(capabilities: CapabilityExport[]): boolean {
32
+ return !isAdmission(capabilities) && !isWatcher(capabilities);
33
+ }
34
+ export function isAdmission(capabilities: CapabilityExport[]): boolean {
35
+ for (const capability of capabilities) {
36
+ const admissionBindings = capability.bindings.filter(
37
+ binding => binding.isFinalize || binding.isMutate || binding.isValidate,
38
+ );
39
+ if (admissionBindings.length > 0) {
40
+ return true;
41
+ }
42
+ }
43
+ return false;
44
+ }
45
+ export function isWatcher(capabilities: CapabilityExport[]): boolean {
46
+ for (const capability of capabilities) {
47
+ if (capability.hasSchedule) {
48
+ return true;
49
+ }
50
+ const watcherBindings = capability.bindings.filter(
51
+ binding => binding.isFinalize || binding.isWatch || binding.isQueue,
52
+ );
53
+ if (watcherBindings.length > 0) {
54
+ return true;
55
+ }
56
+ }
57
+ return false;
58
+ }
59
+
30
60
  export class Assets {
31
61
  readonly name: string;
32
62
  readonly tls: TLSOut;
@@ -82,20 +112,25 @@ export class Assets {
82
112
  allYaml = async (
83
113
  yamlGenerationFunction: (
84
114
  assets: Assets,
85
- deployments: { default: V1Deployment; watch: V1Deployment | null },
115
+ deployments: { admission: V1Deployment | null; watch: V1Deployment | null },
116
+ services: { admission: kind.Service | null; watch: kind.Service | null },
86
117
  ) => Promise<string>,
87
- getDeploymentFunction: (
88
- assets: Assets,
89
- hash: string,
90
- buildTimestamp: string,
91
- imagePullSecret?: string,
92
- ) => kind.Deployment,
93
- getWatcherFunction: (
94
- assets: Assets,
95
- hash: string,
96
- buildTimestamp: string,
97
- imagePullSecret?: string,
98
- ) => kind.Deployment | null,
118
+ getControllerManifests: {
119
+ getDeploymentFunction: (
120
+ assets: Assets,
121
+ hash: string,
122
+ buildTimestamp: string,
123
+ imagePullSecret?: string,
124
+ ) => kind.Deployment | null;
125
+ getWatcherFunction: (
126
+ assets: Assets,
127
+ hash: string,
128
+ buildTimestamp: string,
129
+ imagePullSecret?: string,
130
+ ) => kind.Deployment | null;
131
+ getServiceFunction: (name: string, assets: Assets) => kind.Service | null;
132
+ getWatcherServiceFunction: (name: string, assets: Assets) => kind.Service | null;
133
+ },
99
134
  imagePullSecret?: string,
100
135
  ): Promise<string> => {
101
136
  this.capabilities = await loadCapabilities(this.path);
@@ -116,11 +151,26 @@ export class Assets {
116
151
  const moduleHash = crypto.createHash("sha256").update(code).digest("hex");
117
152
 
118
153
  const deployments = {
119
- default: getDeploymentFunction(this, moduleHash, this.buildTimestamp, imagePullSecret),
120
- watch: getWatcherFunction(this, moduleHash, this.buildTimestamp, imagePullSecret),
154
+ admission: getControllerManifests.getDeploymentFunction(
155
+ this,
156
+ moduleHash,
157
+ this.buildTimestamp,
158
+ imagePullSecret,
159
+ ),
160
+ watch: getControllerManifests.getWatcherFunction(
161
+ this,
162
+ moduleHash,
163
+ this.buildTimestamp,
164
+ imagePullSecret,
165
+ ),
121
166
  };
122
167
 
123
- return yamlGenerationFunction(this, deployments);
168
+ const services = {
169
+ admission: getControllerManifests.getServiceFunction(this.name, this),
170
+ watch: getControllerManifests.getWatcherServiceFunction(this.name, this),
171
+ };
172
+
173
+ return yamlGenerationFunction(this, deployments, services);
124
174
  };
125
175
 
126
176
  writeWebhookFiles = async (
@@ -131,7 +181,7 @@ export class Assets {
131
181
  if (validateWebhook || mutateWebhook) {
132
182
  await fs.writeFile(
133
183
  helm.files.admissionDeploymentYaml,
134
- dedent(admissionDeployTemplate(this.buildTimestamp)),
184
+ dedent(admissionDeployTemplate(this.buildTimestamp, "admission")),
135
185
  );
136
186
  await fs.writeFile(
137
187
  helm.files.admissionServiceMonitorYaml,
@@ -194,8 +244,14 @@ export class Assets {
194
244
  (): string => dedent(chartYaml(this.config.uuid, this.config.description || "")),
195
245
  ],
196
246
  [helm.files.namespaceYaml, (): string => dedent(namespaceTemplate())],
197
- [helm.files.watcherServiceYaml, (): string => toYaml(watcherService(this.name))],
198
- [helm.files.admissionServiceYaml, (): string => toYaml(service(this.name))],
247
+ [
248
+ helm.files.watcherServiceYaml,
249
+ (): string => dedent(serviceTemplate(this.name, "watcher")),
250
+ ],
251
+ [
252
+ helm.files.admissionServiceYaml,
253
+ (): string => dedent(serviceTemplate(this.name, "admission")),
254
+ ],
199
255
  [helm.files.tlsSecretYaml, (): string => toYaml(tlsSecret(this.name, this.tls))],
200
256
  [
201
257
  helm.files.apiPathSecretYaml,
@@ -221,7 +277,10 @@ export class Assets {
221
277
  apiPath: this.apiPath,
222
278
  capabilities: this.capabilities,
223
279
  };
224
- await overridesFile(overrideData, helm.files.valuesYaml, this.imagePullSecrets);
280
+ await overridesFile(overrideData, helm.files.valuesYaml, this.imagePullSecrets, {
281
+ admission: isAdmission(this.capabilities) || norWatchOrAdmission(this.capabilities),
282
+ watcher: isWatcher(this.capabilities),
283
+ });
225
284
 
226
285
  const webhooks = {
227
286
  mutate: await webhookGeneratorFunction(
@@ -242,7 +301,7 @@ export class Assets {
242
301
  if (watchDeployment) {
243
302
  await fs.writeFile(
244
303
  helm.files.watcherDeploymentYaml,
245
- dedent(watcherDeployTemplate(this.buildTimestamp)),
304
+ dedent(watcherDeployTemplate(this.buildTimestamp, "watcher")),
246
305
  );
247
306
  await fs.writeFile(
248
307
  helm.files.watcherServiceMonitorYaml,