pepr 0.40.1 → 0.42.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 (107) hide show
  1. package/README.md +11 -5
  2. package/dist/cli/build.d.ts +1 -0
  3. package/dist/cli/build.d.ts.map +1 -1
  4. package/dist/cli/build.helpers.d.ts +66 -0
  5. package/dist/cli/build.helpers.d.ts.map +1 -1
  6. package/dist/cli/deploy.d.ts.map +1 -1
  7. package/dist/cli/init/templates.d.ts +2 -2
  8. package/dist/cli/monitor.d.ts +23 -0
  9. package/dist/cli/monitor.d.ts.map +1 -1
  10. package/dist/cli.js +536 -429
  11. package/dist/controller.js +52 -27
  12. package/dist/lib/assets/destroy.d.ts.map +1 -1
  13. package/dist/lib/assets/helm.d.ts +1 -1
  14. package/dist/lib/assets/helm.d.ts.map +1 -1
  15. package/dist/lib/assets/index.d.ts.map +1 -1
  16. package/dist/lib/assets/pods.d.ts +5 -19
  17. package/dist/lib/assets/pods.d.ts.map +1 -1
  18. package/dist/lib/assets/webhooks.d.ts.map +1 -1
  19. package/dist/lib/assets/yaml.d.ts.map +1 -1
  20. package/dist/lib/capability.d.ts.map +1 -1
  21. package/dist/lib/controller/index.d.ts.map +1 -1
  22. package/dist/lib/controller/index.util.d.ts +10 -0
  23. package/dist/lib/controller/index.util.d.ts.map +1 -0
  24. package/dist/lib/controller/store.d.ts +0 -1
  25. package/dist/lib/controller/store.d.ts.map +1 -1
  26. package/dist/lib/controller/storeCache.d.ts +1 -0
  27. package/dist/lib/controller/storeCache.d.ts.map +1 -1
  28. package/dist/lib/deploymentChecks.d.ts +3 -0
  29. package/dist/lib/deploymentChecks.d.ts.map +1 -0
  30. package/dist/lib/enums.d.ts +5 -5
  31. package/dist/lib/enums.d.ts.map +1 -1
  32. package/dist/lib/filesystemService.d.ts +2 -0
  33. package/dist/lib/filesystemService.d.ts.map +1 -0
  34. package/dist/lib/filter/adjudicators/adjudicators.d.ts +73 -0
  35. package/dist/lib/filter/adjudicators/adjudicators.d.ts.map +1 -0
  36. package/dist/lib/filter/adjudicators/defaultTestObjects.d.ts +7 -0
  37. package/dist/lib/filter/adjudicators/defaultTestObjects.d.ts.map +1 -0
  38. package/dist/lib/helpers.d.ts +1 -4
  39. package/dist/lib/helpers.d.ts.map +1 -1
  40. package/dist/lib/mutate-request.d.ts +2 -2
  41. package/dist/lib/mutate-request.d.ts.map +1 -1
  42. package/dist/lib/queue.d.ts.map +1 -1
  43. package/dist/lib/schedule.d.ts.map +1 -1
  44. package/dist/lib/storage.d.ts +5 -5
  45. package/dist/lib/storage.d.ts.map +1 -1
  46. package/dist/lib/{logger.d.ts → telemetry/logger.d.ts} +1 -1
  47. package/dist/lib/telemetry/logger.d.ts.map +1 -0
  48. package/dist/lib/{metrics.d.ts → telemetry/metrics.d.ts} +3 -1
  49. package/dist/lib/telemetry/metrics.d.ts.map +1 -0
  50. package/dist/lib/types.d.ts +10 -9
  51. package/dist/lib/types.d.ts.map +1 -1
  52. package/dist/lib/utils.d.ts.map +1 -1
  53. package/dist/lib/validate-processor.d.ts +4 -1
  54. package/dist/lib/validate-processor.d.ts.map +1 -1
  55. package/dist/lib/watch-processor.d.ts.map +1 -1
  56. package/dist/lib.d.ts +1 -1
  57. package/dist/lib.d.ts.map +1 -1
  58. package/dist/lib.js +283 -231
  59. package/dist/lib.js.map +4 -4
  60. package/dist/sdk/sdk.d.ts +3 -4
  61. package/dist/sdk/sdk.d.ts.map +1 -1
  62. package/package.json +5 -5
  63. package/src/cli/build.helpers.ts +180 -0
  64. package/src/cli/build.ts +85 -132
  65. package/src/cli/deploy.ts +2 -1
  66. package/src/cli/init/templates.ts +1 -1
  67. package/src/cli/monitor.ts +108 -65
  68. package/src/lib/assets/deploy.ts +7 -7
  69. package/src/lib/assets/destroy.ts +2 -2
  70. package/src/lib/assets/helm.ts +6 -6
  71. package/src/lib/assets/index.ts +110 -89
  72. package/src/lib/assets/pods.ts +10 -5
  73. package/src/lib/assets/webhooks.ts +3 -3
  74. package/src/lib/assets/yaml.ts +12 -9
  75. package/src/lib/capability.ts +29 -19
  76. package/src/lib/controller/index.ts +41 -69
  77. package/src/lib/controller/index.util.ts +47 -0
  78. package/src/lib/controller/store.ts +24 -11
  79. package/src/lib/controller/storeCache.ts +11 -2
  80. package/src/lib/deploymentChecks.ts +43 -0
  81. package/src/lib/enums.ts +5 -5
  82. package/src/lib/filesystemService.ts +16 -0
  83. package/src/lib/filter/{adjudicators.ts → adjudicators/adjudicators.ts} +67 -35
  84. package/src/lib/filter/adjudicators/defaultTestObjects.ts +46 -0
  85. package/src/lib/filter/filter.ts +1 -1
  86. package/src/lib/finalizer.ts +1 -1
  87. package/src/lib/helpers.ts +31 -88
  88. package/src/lib/mutate-processor.ts +1 -1
  89. package/src/lib/mutate-request.ts +11 -11
  90. package/src/lib/queue.ts +13 -5
  91. package/src/lib/schedule.ts +8 -8
  92. package/src/lib/storage.ts +48 -39
  93. package/src/lib/{logger.ts → telemetry/logger.ts} +1 -1
  94. package/src/lib/{metrics.ts → telemetry/metrics.ts} +18 -17
  95. package/src/lib/types.ts +12 -9
  96. package/src/lib/utils.ts +6 -6
  97. package/src/lib/validate-processor.ts +48 -40
  98. package/src/lib/watch-processor.ts +19 -15
  99. package/src/lib.ts +1 -1
  100. package/src/runtime/controller.ts +1 -1
  101. package/src/sdk/cosign.ts +4 -4
  102. package/src/sdk/sdk.ts +6 -9
  103. package/src/templates/capabilities/hello-pepr.ts +19 -9
  104. package/dist/lib/filter/adjudicators.d.ts +0 -69
  105. package/dist/lib/filter/adjudicators.d.ts.map +0 -1
  106. package/dist/lib/logger.d.ts.map +0 -1
  107. package/dist/lib/metrics.d.ts.map +0 -1
package/dist/sdk/sdk.d.ts CHANGED
@@ -1,15 +1,14 @@
1
1
  import { PeprValidateRequest } from "../lib/validate-request";
2
2
  import { PeprMutateRequest } from "../lib/mutate-request";
3
- import { V1OwnerReference } from "@kubernetes/client-node";
4
- import { GenericKind } from "kubernetes-fluent-client";
5
- import { kind } from "kubernetes-fluent-client";
3
+ import { V1OwnerReference, V1Container } from "@kubernetes/client-node";
4
+ import { GenericKind, kind } from "kubernetes-fluent-client";
6
5
  /**
7
6
  * Returns all containers in a pod
8
7
  * @param request the request/pod to get the containers from
9
8
  * @param containerType the type of container to get
10
9
  * @returns the list of containers in the pod
11
10
  */
12
- export declare function containers(request: PeprValidateRequest<kind.Pod> | PeprMutateRequest<kind.Pod>, containerType?: "containers" | "initContainers" | "ephemeralContainers"): import("@kubernetes/client-node").V1Container[];
11
+ export declare function containers(request: PeprValidateRequest<kind.Pod> | PeprMutateRequest<kind.Pod>, containerType?: "containers" | "initContainers" | "ephemeralContainers"): V1Container[];
13
12
  /**
14
13
  * Write a K8s event for a CRD
15
14
  *
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/sdk/sdk.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAO,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAGrD;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,EACpE,aAAa,CAAC,EAAE,YAAY,GAAG,gBAAgB,GAAG,qBAAqB,mDAgBxE;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,WAAW,EACf,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,MAAM,EAC1B,iBAAiB,EAAE,MAAM,iBAwB1B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,WAAW,EAC3B,kBAAkB,CAAC,EAAE,OAAO,EAC5B,UAAU,CAAC,EAAE,OAAO,GACnB,gBAAgB,EAAE,CAcpB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,UAYhD"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/sdk/sdk.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAO,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAElE;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,EACpE,aAAa,CAAC,EAAE,YAAY,GAAG,gBAAgB,GAAG,qBAAqB,GACtE,WAAW,EAAE,CAef;AAED;;;;;;;;;GASG;AAEH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,WAAW,EACf,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,MAAM,EAC1B,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,WAAW,EAC3B,kBAAkB,CAAC,EAAE,OAAO,EAC5B,UAAU,CAAC,EAAE,OAAO,GACnB,gBAAgB,EAAE,CAcpB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYzD"}
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "!src/**/*.test.ts",
16
16
  "!dist/**/*.test.d.ts*"
17
17
  ],
18
- "version": "0.40.1",
18
+ "version": "0.42.1",
19
19
  "main": "dist/lib.js",
20
20
  "types": "dist/lib.d.ts",
21
21
  "scripts": {
@@ -41,12 +41,12 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@types/ramda": "0.30.2",
44
- "express": "4.21.1",
44
+ "express": "4.21.2",
45
45
  "fast-json-patch": "3.1.1",
46
46
  "follow-redirects": "1.15.9",
47
47
  "http-status-codes": "^2.3.0",
48
48
  "json-pointer": "^0.6.2",
49
- "kubernetes-fluent-client": "3.3.4",
49
+ "kubernetes-fluent-client": "3.3.7",
50
50
  "pino": "9.5.0",
51
51
  "pino-pretty": "13.0.0",
52
52
  "prom-client": "15.1.3",
@@ -69,8 +69,8 @@
69
69
  "husky": "^9.1.6",
70
70
  "jest": "29.7.0",
71
71
  "js-yaml": "^4.1.0",
72
- "nock": "^13.5.4",
73
- "ts-jest": "29.2.5"
72
+ "ts-jest": "29.2.5",
73
+ "undici": "^7.0.1"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "@types/prompts": "2.4.9",
@@ -1,3 +1,15 @@
1
+ import { createDirectoryIfNotExists } from "../lib/filesystemService";
2
+ import { sanitizeResourceName } from "../sdk/sdk";
3
+ import { createDockerfile } from "../lib/included-files";
4
+ import { execSync } from "child_process";
5
+ import { CapabilityExport } from "../lib/types";
6
+ import { validateCapabilityNames } from "../lib/helpers";
7
+ import { BuildOptions, BuildResult, context, BuildContext } from "esbuild";
8
+ import { Assets } from "../lib/assets";
9
+ import { resolve } from "path";
10
+ import { promises as fs } from "fs";
11
+
12
+ export type Reloader = (opts: BuildResult<BuildOptions>) => void | Promise<void>;
1
13
  /**
2
14
  * Determine the RBAC mode based on the CLI options and the module's config
3
15
  * @param opts CLI options
@@ -26,3 +38,171 @@ export function determineRbacMode(
26
38
  // if nothing is defined return admin, else return scoped
27
39
  return cfg.pepr.rbacMode || "admin";
28
40
  }
41
+
42
+ /**
43
+ * Handle the custom output directory
44
+ * @param outputDir the desired output directory
45
+ * @returns The desired output directory or the default one
46
+ */
47
+
48
+ export async function handleCustomOutputDir(outputDir: string): Promise<string> {
49
+ const defaultOutputDir = "dist";
50
+ if (outputDir) {
51
+ try {
52
+ await createDirectoryIfNotExists(outputDir);
53
+ return outputDir;
54
+ } catch (error) {
55
+ console.error(`Error creating output directory: ${error.message}`);
56
+ process.exit(1);
57
+ }
58
+ }
59
+ return defaultOutputDir;
60
+ }
61
+
62
+ /**
63
+ * Check if the image is from Iron Bank and return the correct image
64
+ * @param registry The registry of the image
65
+ * @param image The image to check
66
+ * @param peprVersion The version of the PEPR controller
67
+ * @returns The image string
68
+ * @example
69
+ */
70
+ export function checkIronBankImage(registry: string, image: string, peprVersion: string): string {
71
+ return registry === "Iron Bank"
72
+ ? `registry1.dso.mil/ironbank/opensource/defenseunicorns/pepr/controller:v${peprVersion}`
73
+ : image;
74
+ }
75
+
76
+ /**
77
+ * Check if the image pull secret is a valid Kubernetes name
78
+ * @param imagePullSecret
79
+ * @returns boolean
80
+ */
81
+ export function validImagePullSecret(imagePullSecretName: string): void {
82
+ if (imagePullSecretName) {
83
+ const error = "Invalid imagePullSecret. Please provide a valid name as defined in RFC 1123.";
84
+ if (sanitizeResourceName(imagePullSecretName) !== imagePullSecretName) {
85
+ // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
86
+ console.error(error);
87
+ process.exit(1);
88
+ }
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Constraint to majke sure customImage and registry are not both used
94
+ * @param customImage
95
+ * @param registry
96
+ * @returns
97
+ */
98
+ export function handleCustomImage(customImage: string, registry: string): string {
99
+ let defaultImage = "";
100
+ if (customImage) {
101
+ if (registry) {
102
+ console.error(`Custom Image and registry cannot be used together.`);
103
+ process.exit(1);
104
+ }
105
+ defaultImage = customImage;
106
+ }
107
+ return defaultImage;
108
+ }
109
+
110
+ /**
111
+ * Creates and pushes a custom image for WASM or any other included files
112
+ * @param includedFiles
113
+ * @param peprVersion
114
+ * @param description
115
+ * @param image
116
+ */
117
+ export async function handleCustomImageBuild(
118
+ includedFiles: string[],
119
+ peprVersion: string,
120
+ description: string,
121
+ image: string,
122
+ ): Promise<void> {
123
+ if (includedFiles.length > 0) {
124
+ await createDockerfile(peprVersion, description, includedFiles);
125
+ execSync(`docker build --tag ${image} -f Dockerfile.controller .`, {
126
+ stdio: "inherit",
127
+ });
128
+ execSync(`docker push ${image}`, { stdio: "inherit" });
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Disables embedding of deployment files into output module
134
+ * @param embed
135
+ * @param path
136
+ * @returns
137
+ */
138
+ export function handleEmbedding(embed: boolean, path: string): void {
139
+ if (!embed) {
140
+ console.info(`✅ Module built successfully at ${path}`);
141
+ return;
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Check if the capability names are valid
147
+ * @param capabilities The capabilities to check
148
+ */
149
+ export function handleValidCapabilityNames(capabilities: CapabilityExport[]): void {
150
+ try {
151
+ // wait for capabilities to be loaded and test names
152
+ validateCapabilityNames(capabilities);
153
+ } catch (e) {
154
+ console.error(`Error loading capability:`, e);
155
+ process.exit(1);
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Watch for changes in the module
161
+ * @param ctxCfg The build options
162
+ * @param reloader The reloader function
163
+ * @returns The build context
164
+ */
165
+ export async function watchForChanges(
166
+ ctxCfg: BuildOptions,
167
+ reloader: Reloader | undefined,
168
+ ): Promise<BuildContext<BuildOptions>> {
169
+ const ctx = await context(ctxCfg);
170
+
171
+ // If the reloader function is defined, watch the module for changes
172
+ if (reloader) {
173
+ await ctx.watch();
174
+ } else {
175
+ // Otherwise, just build the module once
176
+ await ctx.rebuild();
177
+ await ctx.dispose();
178
+ }
179
+
180
+ return ctx;
181
+ }
182
+
183
+ export async function generateYamlAndWriteToDisk(obj: {
184
+ uuid: string;
185
+ imagePullSecret: string;
186
+ outputDir: string;
187
+ assets: Assets;
188
+ zarf: string;
189
+ }): Promise<void> {
190
+ const { uuid, imagePullSecret, outputDir, assets, zarf } = obj;
191
+ const yamlFile = `pepr-module-${uuid}.yaml`;
192
+ const chartPath = `${uuid}-chart`;
193
+ const yamlPath = resolve(outputDir, yamlFile);
194
+ const yaml = await assets.allYaml(imagePullSecret);
195
+ const zarfPath = resolve(outputDir, "zarf.yaml");
196
+
197
+ let localZarf = "";
198
+ if (zarf === "chart") {
199
+ localZarf = assets.zarfYamlChart(chartPath);
200
+ } else {
201
+ localZarf = assets.zarfYaml(yamlFile);
202
+ }
203
+ await fs.writeFile(yamlPath, yaml);
204
+ await fs.writeFile(zarfPath, localZarf);
205
+
206
+ await assets.generateHelmChart(outputDir);
207
+ console.info(`✅ K8s resource for the module saved to ${yamlPath}`);
208
+ }
package/src/cli/build.ts CHANGED
@@ -1,24 +1,34 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
3
 
4
- import { execSync, execFileSync } from "child_process";
5
- import { BuildOptions, BuildResult, analyzeMetafile, context } from "esbuild";
4
+ import { execFileSync } from "child_process";
5
+ import { BuildOptions, BuildResult, analyzeMetafile } from "esbuild";
6
6
  import { promises as fs } from "fs";
7
7
  import { basename, dirname, extname, resolve } from "path";
8
- import { createDockerfile } from "../lib/included-files";
9
8
  import { Assets } from "../lib/assets";
10
9
  import { dependencies, version } from "./init/templates";
11
10
  import { RootCmd } from "./root";
12
- import { peprFormat } from "./format";
13
11
  import { Option } from "commander";
14
- import { createDirectoryIfNotExists, validateCapabilityNames, parseTimeout } from "../lib/helpers";
15
- import { sanitizeResourceName } from "../sdk/sdk";
16
- import { determineRbacMode } from "./build.helpers";
12
+ import { parseTimeout } from "../lib/helpers";
13
+ import { peprFormat } from "./format";
14
+ import {
15
+ watchForChanges,
16
+ determineRbacMode,
17
+ handleEmbedding,
18
+ handleCustomOutputDir,
19
+ handleValidCapabilityNames,
20
+ handleCustomImage,
21
+ handleCustomImageBuild,
22
+ checkIronBankImage,
23
+ validImagePullSecret,
24
+ generateYamlAndWriteToDisk,
25
+ } from "./build.helpers";
26
+
17
27
  const peprTS = "pepr.ts";
18
28
  let outputDir: string = "dist";
19
29
  export type Reloader = (opts: BuildResult<BuildOptions>) => void | Promise<void>;
20
30
 
21
- export default function (program: RootCmd) {
31
+ export default function (program: RootCmd): void {
22
32
  program
23
33
  .command("build")
24
34
  .description("Build a Pepr Module for deployment")
@@ -72,13 +82,7 @@ export default function (program: RootCmd) {
72
82
  )
73
83
  .action(async opts => {
74
84
  // assign custom output directory if provided
75
- if (opts.outputDir) {
76
- outputDir = opts.outputDir;
77
- createDirectoryIfNotExists(outputDir).catch(error => {
78
- console.error(`Error creating output directory: ${error.message}`);
79
- process.exit(1);
80
- });
81
- }
85
+ outputDir = await handleCustomOutputDir(opts.outputDir);
82
86
 
83
87
  // Build the module
84
88
  const buildModuleResult = await buildModule(undefined, opts.entryPoint, opts.embed);
@@ -87,16 +91,7 @@ export default function (program: RootCmd) {
87
91
  // Files to include in controller image for WASM support
88
92
  const { includedFiles } = cfg.pepr;
89
93
 
90
- let image: string = "";
91
-
92
- // Build Kubernetes manifests with custom image
93
- if (opts.customImage) {
94
- if (opts.registry) {
95
- console.error(`Custom Image and registry cannot be used together.`);
96
- process.exit(1);
97
- }
98
- image = opts.customImage;
99
- }
94
+ let image = handleCustomImage(opts.customImage, opts.registry);
100
95
 
101
96
  // Check if there is a custom timeout defined
102
97
  if (opts.timeout !== undefined) {
@@ -110,25 +105,14 @@ export default function (program: RootCmd) {
110
105
  image = `${opts.registryInfo}/custom-pepr-controller:${cfg.pepr.peprVersion}`;
111
106
 
112
107
  // only actually build/push if there are files to include
113
- if (includedFiles.length > 0) {
114
- await createDockerfile(cfg.pepr.peprVersion, cfg.description, includedFiles);
115
- execSync(`docker build --tag ${image} -f Dockerfile.controller .`, {
116
- stdio: "inherit",
117
- });
118
- execSync(`docker push ${image}`, { stdio: "inherit" });
119
- }
108
+ await handleCustomImageBuild(includedFiles, cfg.pepr.peprVersion, cfg.description, image);
120
109
  }
121
110
 
122
111
  // If building without embedding, exit after building
123
- if (!opts.embed) {
124
- console.info(`✅ Module built successfully at ${path}`);
125
- return;
126
- }
112
+ handleEmbedding(opts.embed, path);
127
113
 
128
114
  // set the image version if provided
129
- if (opts.version) {
130
- cfg.pepr.peprVersion = opts.version;
131
- }
115
+ opts.version ? (cfg.pepr.peprVersion = opts.version) : null;
132
116
 
133
117
  // Generate a secret for the module
134
118
  const assets = new Assets(
@@ -143,56 +127,22 @@ export default function (program: RootCmd) {
143
127
  );
144
128
 
145
129
  // If registry is set to Iron Bank, use Iron Bank image
146
- if (opts?.registry === "Iron Bank") {
147
- console.info(
148
- `\n\tThis command assumes the latest release. Pepr's Iron Bank image release cycle is dictated by renovate and is typically released a few days after the GitHub release.\n\tAs an alternative you may consider custom --custom-image to target a specific image and version.`,
149
- );
150
- image = `registry1.dso.mil/ironbank/opensource/defenseunicorns/pepr/controller:v${cfg.pepr.peprVersion}`;
151
- }
130
+ image = checkIronBankImage(opts.registry, image, cfg.pepr.peprVersion);
152
131
 
153
132
  // if image is a custom image, use that instead of the default
154
- if (image !== "") {
155
- assets.image = image;
156
- }
133
+ image !== "" ? (assets.image = image) : null;
157
134
 
158
135
  // Ensure imagePullSecret is valid
159
- if (opts.withPullSecret) {
160
- if (sanitizeResourceName(opts.withPullSecret) !== opts.withPullSecret) {
161
- // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
162
- console.error(
163
- "Invalid imagePullSecret. Please provide a valid name as defined in RFC 1123.",
164
- );
165
- process.exit(1);
166
- }
167
- }
168
-
169
- const yamlFile = `pepr-module-${uuid}.yaml`;
170
- const chartPath = `${uuid}-chart`;
171
- const yamlPath = resolve(outputDir, yamlFile);
172
- const yaml = await assets.allYaml(opts.withPullSecret);
173
-
174
- try {
175
- // wait for capabilities to be loaded and test names
176
- validateCapabilityNames(assets.capabilities);
177
- } catch (e) {
178
- console.error(`Error loading capability:`, e);
179
- process.exit(1);
180
- }
181
-
182
- const zarfPath = resolve(outputDir, "zarf.yaml");
183
-
184
- let zarf = "";
185
- if (opts.zarf === "chart") {
186
- zarf = assets.zarfYamlChart(chartPath);
187
- } else {
188
- zarf = assets.zarfYaml(yamlFile);
189
- }
190
- await fs.writeFile(yamlPath, yaml);
191
- await fs.writeFile(zarfPath, zarf);
192
-
193
- await assets.generateHelmChart(outputDir);
194
-
195
- console.info(`✅ K8s resource for the module saved to ${yamlPath}`);
136
+ validImagePullSecret(opts.withPullSecret);
137
+
138
+ handleValidCapabilityNames(assets.capabilities);
139
+ await generateYamlAndWriteToDisk({
140
+ uuid,
141
+ outputDir,
142
+ imagePullSecret: opts.withPullSecret,
143
+ zarf: opts.zarf,
144
+ assets,
145
+ });
196
146
  }
197
147
  });
198
148
  }
@@ -251,15 +201,7 @@ export async function buildModule(reloader?: Reloader, entryPoint = peprTS, embe
251
201
  try {
252
202
  const { cfg, modulePath, path, uuid } = await loadModule(entryPoint);
253
203
 
254
- const validFormat = await peprFormat(true);
255
-
256
- if (!validFormat) {
257
- console.log(
258
- "\x1b[33m%s\x1b[0m",
259
- "Formatting errors were found. The build will continue, but you may want to run `npx pepr format` to address any issues.",
260
- );
261
- }
262
-
204
+ await checkFormat();
263
205
  // Resolve node_modules folder (in support of npm workspaces!)
264
206
  const npmRoot = execFileSync("npm", ["root"]).toString().trim();
265
207
 
@@ -281,7 +223,7 @@ export async function buildModule(reloader?: Reloader, entryPoint = peprTS, embe
281
223
  plugins: [
282
224
  {
283
225
  name: "reload-server",
284
- setup(build) {
226
+ setup(build): void | Promise<void> {
285
227
  build.onEnd(async r => {
286
228
  // Print the build size analysis
287
229
  if (r?.metafile) {
@@ -321,53 +263,64 @@ export async function buildModule(reloader?: Reloader, entryPoint = peprTS, embe
321
263
  ctxCfg.treeShaking = false;
322
264
  }
323
265
 
324
- const ctx = await context(ctxCfg);
325
-
326
- // If the reloader function is defined, watch the module for changes
327
- if (reloader) {
328
- await ctx.watch();
329
- } else {
330
- // Otherwise, just build the module once
331
- await ctx.rebuild();
332
- await ctx.dispose();
333
- }
266
+ const ctx = await watchForChanges(ctxCfg, reloader);
334
267
 
335
268
  return { ctx, path, cfg, uuid };
336
269
  } catch (e) {
337
- console.error(`Error building module:`, e);
270
+ handleModuleBuildError(e);
271
+ }
272
+ }
338
273
 
339
- if (!e.stdout) process.exit(1); // Exit with a non-zero exit code on any other error
274
+ interface BuildModuleResult {
275
+ stdout?: Buffer;
276
+ stderr: Buffer;
277
+ }
340
278
 
341
- const out = e.stdout.toString() as string;
342
- const err = e.stderr.toString();
279
+ function handleModuleBuildError(e: BuildModuleResult): void {
280
+ console.error(`Error building module:`, e);
343
281
 
344
- console.log(out);
345
- console.error(err);
282
+ if (!e.stdout) process.exit(1); // Exit with a non-zero exit code on any other error
346
283
 
347
- // Check for version conflicts
348
- if (out.includes("Types have separate declarations of a private property '_name'.")) {
349
- // Try to find the conflicting package
350
- const pgkErrMatch = /error TS2322: .*? 'import\("\/.*?\/node_modules\/(.*?)\/node_modules/g;
351
- out.matchAll(pgkErrMatch);
284
+ const out = e.stdout.toString() as string;
285
+ const err = e.stderr.toString();
352
286
 
353
- // Look for package conflict errors
354
- const conflicts = [...out.matchAll(pgkErrMatch)];
287
+ console.log(out);
288
+ console.error(err);
355
289
 
356
- // If the regex didn't match, leave a generic error
357
- if (conflicts.length < 1) {
358
- console.info(
359
- `\n\tOne or more imported Pepr Capabilities seem to be using an incompatible version of Pepr.\n\tTry updating your Pepr Capabilities to their latest versions.`,
360
- "Version Conflict",
361
- );
362
- }
290
+ // Check for version conflicts
291
+ if (out.includes("Types have separate declarations of a private property '_name'.")) {
292
+ // Try to find the conflicting package
293
+ const pgkErrMatch = /error TS2322: .*? 'import\("\/.*?\/node_modules\/(.*?)\/node_modules/g;
294
+ out.matchAll(pgkErrMatch);
363
295
 
364
- // Otherwise, loop through each conflicting package and print an error
365
- conflicts.forEach(match => {
366
- console.info(
367
- `\n\tPackage '${match[1]}' seems to be incompatible with your current version of Pepr.\n\tTry updating to the latest version.`,
368
- "Version Conflict",
369
- );
370
- });
296
+ // Look for package conflict errors
297
+ const conflicts = [...out.matchAll(pgkErrMatch)];
298
+
299
+ // If the regex didn't match, leave a generic error
300
+ if (conflicts.length < 1) {
301
+ console.info(
302
+ `\n\tOne or more imported Pepr Capabilities seem to be using an incompatible version of Pepr.\n\tTry updating your Pepr Capabilities to their latest versions.`,
303
+ "Version Conflict",
304
+ );
371
305
  }
306
+
307
+ // Otherwise, loop through each conflicting package and print an error
308
+ conflicts.forEach(match => {
309
+ console.info(
310
+ `\n\tPackage '${match[1]}' seems to be incompatible with your current version of Pepr.\n\tTry updating to the latest version.`,
311
+ "Version Conflict",
312
+ );
313
+ });
314
+ }
315
+ }
316
+
317
+ export async function checkFormat() {
318
+ const validFormat = await peprFormat(true);
319
+
320
+ if (!validFormat) {
321
+ console.log(
322
+ "\x1b[33m%s\x1b[0m",
323
+ "Formatting errors were found. The build will continue, but you may want to run `npx pepr format` to address any issues.",
324
+ );
372
325
  }
373
326
  }
package/src/cli/deploy.ts CHANGED
@@ -6,10 +6,11 @@ import prompt from "prompts";
6
6
  import { Assets } from "../lib/assets";
7
7
  import { buildModule } from "./build";
8
8
  import { RootCmd } from "./root";
9
- import { validateCapabilityNames, namespaceDeploymentsReady } from "../lib/helpers";
9
+ import { validateCapabilityNames } from "../lib/helpers";
10
10
  import { ImagePullSecret } from "../lib/types";
11
11
  import { sanitizeName } from "./init/utils";
12
12
  import { deployImagePullSecret } from "../lib/assets/deploy";
13
+ import { namespaceDeploymentsReady } from "../lib/deploymentChecks";
13
14
 
14
15
  export default function (program: RootCmd) {
15
16
  program
@@ -58,7 +58,7 @@ export function genPkgJSON(opts: InitOptions, pgkVerOverride?: string) {
58
58
  },
59
59
  dependencies: {
60
60
  pepr: pgkVerOverride || version,
61
- nock: "13.5.4",
61
+ undici: "^7.0.1",
62
62
  },
63
63
  devDependencies: {
64
64
  typescript,