pepr 0.38.2 → 0.39.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 (95) hide show
  1. package/dist/cli/build.d.ts +1 -1
  2. package/dist/cli/build.d.ts.map +1 -1
  3. package/dist/cli/build.helpers.d.ts +19 -0
  4. package/dist/cli/build.helpers.d.ts.map +1 -0
  5. package/dist/cli/deploy.d.ts.map +1 -1
  6. package/dist/cli/format.d.ts.map +1 -1
  7. package/dist/cli/init/index.d.ts.map +1 -1
  8. package/dist/cli/init/templates.d.ts +6 -2
  9. package/dist/cli/init/templates.d.ts.map +1 -1
  10. package/dist/cli/monitor.d.ts.map +1 -1
  11. package/dist/cli.js +278 -225
  12. package/dist/controller.js +37 -27
  13. package/dist/lib/assets/deploy.d.ts.map +1 -1
  14. package/dist/lib/assets/helm.d.ts +1 -0
  15. package/dist/lib/assets/helm.d.ts.map +1 -1
  16. package/dist/lib/assets/index.d.ts +1 -1
  17. package/dist/lib/assets/index.d.ts.map +1 -1
  18. package/dist/lib/assets/rbac.d.ts +31 -4
  19. package/dist/lib/assets/rbac.d.ts.map +1 -1
  20. package/dist/lib/assets/yaml.d.ts +2 -2
  21. package/dist/lib/assets/yaml.d.ts.map +1 -1
  22. package/dist/lib/capability.d.ts +2 -8
  23. package/dist/lib/capability.d.ts.map +1 -1
  24. package/dist/lib/controller/store.d.ts +1 -5
  25. package/dist/lib/controller/store.d.ts.map +1 -1
  26. package/dist/lib/controller/storeCache.d.ts +11 -0
  27. package/dist/lib/controller/storeCache.d.ts.map +1 -0
  28. package/dist/lib/enums.d.ts +17 -0
  29. package/dist/lib/enums.d.ts.map +1 -0
  30. package/dist/lib/{adjudicators.d.ts → filter/adjudicators.d.ts} +15 -13
  31. package/dist/lib/filter/adjudicators.d.ts.map +1 -0
  32. package/dist/lib/{filter.d.ts → filter/filter.d.ts} +1 -1
  33. package/dist/lib/filter/filter.d.ts.map +1 -0
  34. package/dist/lib/helpers.d.ts +1 -2
  35. package/dist/lib/helpers.d.ts.map +1 -1
  36. package/dist/lib/k8s.d.ts +1 -1
  37. package/dist/lib/k8s.d.ts.map +1 -1
  38. package/dist/lib/logger.d.ts +4 -0
  39. package/dist/lib/logger.d.ts.map +1 -1
  40. package/dist/lib/metrics.d.ts.map +1 -1
  41. package/dist/lib/module.d.ts +5 -0
  42. package/dist/lib/module.d.ts.map +1 -1
  43. package/dist/lib/mutate-processor.d.ts.map +1 -1
  44. package/dist/lib/mutate-request.d.ts +1 -60
  45. package/dist/lib/mutate-request.d.ts.map +1 -1
  46. package/dist/lib/types.d.ts +8 -24
  47. package/dist/lib/types.d.ts.map +1 -1
  48. package/dist/lib/validate-request.d.ts.map +1 -1
  49. package/dist/lib/watch-processor.d.ts.map +1 -1
  50. package/dist/lib.js +220 -295
  51. package/dist/lib.js.map +4 -4
  52. package/dist/sdk/cosign.d.ts +18 -0
  53. package/dist/sdk/cosign.d.ts.map +1 -0
  54. package/dist/sdk/heredoc.d.ts +2 -0
  55. package/dist/sdk/heredoc.d.ts.map +1 -0
  56. package/dist/sdk/sdk.d.ts +1 -2
  57. package/dist/sdk/sdk.d.ts.map +1 -1
  58. package/package.json +11 -7
  59. package/src/cli/build.helpers.ts +28 -0
  60. package/src/cli/build.ts +124 -121
  61. package/src/cli/deploy.ts +27 -24
  62. package/src/cli/dev.ts +3 -3
  63. package/src/cli/format.ts +3 -6
  64. package/src/cli/init/index.ts +23 -19
  65. package/src/cli/monitor.ts +34 -36
  66. package/src/lib/assets/deploy.ts +12 -3
  67. package/src/lib/assets/helm.ts +14 -0
  68. package/src/lib/assets/index.ts +12 -8
  69. package/src/lib/assets/rbac.ts +69 -17
  70. package/src/lib/assets/webhooks.ts +1 -1
  71. package/src/lib/assets/yaml.ts +8 -4
  72. package/src/lib/capability.ts +7 -12
  73. package/src/lib/controller/index.ts +3 -3
  74. package/src/lib/controller/store.ts +42 -202
  75. package/src/lib/controller/storeCache.ts +63 -0
  76. package/src/lib/enums.ts +21 -0
  77. package/src/lib/{adjudicators.ts → filter/adjudicators.ts} +39 -28
  78. package/src/lib/{filter.ts → filter/filter.ts} +3 -2
  79. package/src/lib/finalizer.ts +1 -1
  80. package/src/lib/helpers.ts +19 -15
  81. package/src/lib/k8s.ts +2 -2
  82. package/src/lib/logger.ts +41 -0
  83. package/src/lib/metrics.ts +3 -1
  84. package/src/lib/module.ts +5 -0
  85. package/src/lib/mutate-processor.ts +14 -12
  86. package/src/lib/mutate-request.ts +4 -69
  87. package/src/lib/types.ts +9 -28
  88. package/src/lib/validate-processor.ts +1 -1
  89. package/src/lib/validate-request.ts +2 -1
  90. package/src/lib/watch-processor.ts +34 -20
  91. package/src/sdk/cosign.ts +327 -0
  92. package/src/sdk/heredoc.ts +36 -0
  93. package/src/sdk/sdk.ts +1 -2
  94. package/dist/lib/adjudicators.d.ts.map +0 -1
  95. package/dist/lib/filter.d.ts.map +0 -1
@@ -0,0 +1,18 @@
1
+ export declare enum MediaTypeDockerV2 {
2
+ Manifest = "application/vnd.docker.distribution.manifest.v2+json"
3
+ }
4
+ export declare enum MediaTypeOciV1 {
5
+ Manifest = "application/vnd.oci.image.manifest.v1+json",
6
+ Index = "application/vnd.oci.image.index.v1+json"
7
+ }
8
+ export declare function head(rawUrl: string, mediaType: string, optsParam?: Record<string, any>): Promise<any>;
9
+ export declare function get(rawUrl: string, mediaType: string, optsParam?: Record<string, any>): Promise<any>;
10
+ export declare function download(rawUrl: string, localPath: string, optsParam?: Record<string, any>): Promise<void>;
11
+ /**
12
+ * Returns all containers in a pod
13
+ * @param {string} iref image reference
14
+ * @param {array} pubkeys list of paths to node crypto code signing pubkeys
15
+ * @returns {boolean} whether the iref was signed by a key in the pubkeys
16
+ */
17
+ export declare function verifyImage(iref: string, pubkeys: string[], tlsCrts?: string[]): Promise<boolean>;
18
+ //# sourceMappingURL=cosign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cosign.d.ts","sourceRoot":"","sources":["../../src/sdk/cosign.ts"],"names":[],"mappings":"AAWA,oBAAY,iBAAiB;IAC3B,QAAQ,yDAAyD;CAClE;AAED,oBAAY,cAAc;IACxB,QAAQ,+CAA+C;IACvD,KAAK,4CAA4C;CAClD;AAGD,wBAAsB,IAAI,CACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,OAAO,CAAC,GAAG,CAAC,CAwCd;AAGD,wBAAsB,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,OAAO,CAAC,GAAG,CAAC,CAmDd;AAGD,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,OAAO,CAAC,IAAI,CAAC,CA8Cf;AAMD;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,OAAO,CAAC,CAsIlB"}
@@ -0,0 +1,2 @@
1
+ export declare function heredoc(strings: TemplateStringsArray, ...values: string[]): string;
2
+ //# sourceMappingURL=heredoc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heredoc.d.ts","sourceRoot":"","sources":["../../src/sdk/heredoc.ts"],"names":[],"mappings":"AAGA,wBAAgB,OAAO,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,UAgCzE"}
package/dist/sdk/sdk.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { PeprValidateRequest } from "../lib/validate-request";
2
2
  import { PeprMutateRequest } from "../lib/mutate-request";
3
- import { a } from "../lib";
4
3
  import { V1OwnerReference } from "@kubernetes/client-node";
5
4
  import { GenericKind } from "kubernetes-fluent-client";
6
5
  import { kind } from "kubernetes-fluent-client";
@@ -10,7 +9,7 @@ import { kind } from "kubernetes-fluent-client";
10
9
  * @param containerType the type of container to get
11
10
  * @returns the list of containers in the pod
12
11
  */
13
- export declare function containers(request: PeprValidateRequest<a.Pod> | PeprMutateRequest<a.Pod>, containerType?: "containers" | "initContainers" | "ephemeralContainers"): import("@kubernetes/client-node").V1Container[];
12
+ export declare function containers(request: PeprValidateRequest<kind.Pod> | PeprMutateRequest<kind.Pod>, containerType?: "containers" | "initContainers" | "ephemeralContainers"): import("@kubernetes/client-node").V1Container[];
14
13
  /**
15
14
  * Write a K8s event for a CRD
16
15
  *
@@ -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,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,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,CAAC,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,EAC9D,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,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"}
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "!src/**/*.test.ts",
16
16
  "!dist/**/*.test.d.ts*"
17
17
  ],
18
- "version": "0.38.2",
18
+ "version": "0.39.0",
19
19
  "main": "dist/lib.js",
20
20
  "types": "dist/lib.d.ts",
21
21
  "scripts": {
@@ -26,7 +26,7 @@
26
26
  "build": "tsc && node build.mjs && npm pack",
27
27
  "build:image": "npm run build && docker buildx build --output type=docker --tag pepr:dev .",
28
28
  "test": "npm run test:unit && npm run test:journey",
29
- "test:unit": "npm run gen-data-json && jest src --coverage --detectOpenHandles --coverageDirectory=./coverage",
29
+ "test:unit": "npm run gen-data-json && jest src --coverage --detectOpenHandles --coverageDirectory=./coverage --testPathIgnorePatterns='cosign.e2e.test.ts'",
30
30
  "test:journey": "npm run test:journey:k3d && npm run build && npm run test:journey:image && npm run test:journey:run",
31
31
  "test:journey:prep": "if [ ! -d ./pepr-upgrade-test ]; then git clone https://github.com/defenseunicorns/pepr-upgrade-test.git ; fi",
32
32
  "test:journey-wasm": "npm run test:journey:k3d && npm run build && npm run test:journey:image && npm run test:journey:run-wasm",
@@ -43,12 +43,15 @@
43
43
  "@types/ramda": "0.30.2",
44
44
  "express": "4.21.1",
45
45
  "fast-json-patch": "3.1.1",
46
+ "follow-redirects": "1.15.9",
47
+ "http-status-codes": "^2.3.0",
46
48
  "json-pointer": "^0.6.2",
47
- "kubernetes-fluent-client": "3.1.3",
49
+ "kubernetes-fluent-client": "3.3.0",
48
50
  "pino": "9.5.0",
49
51
  "pino-pretty": "11.3.0",
50
52
  "prom-client": "15.1.3",
51
- "ramda": "0.30.1"
53
+ "ramda": "0.30.1",
54
+ "sigstore": "3.0.0"
52
55
  },
53
56
  "devDependencies": {
54
57
  "@commitlint/cli": "19.5.0",
@@ -57,18 +60,20 @@
57
60
  "@jest/globals": "29.7.0",
58
61
  "@types/eslint": "9.6.1",
59
62
  "@types/express": "5.0.0",
63
+ "@types/follow-redirects": "1.14.4",
60
64
  "@types/json-pointer": "^1.0.34",
61
65
  "@types/node": "22.x.x",
62
66
  "@types/node-forge": "1.3.11",
63
67
  "@types/uuid": "10.0.0",
64
68
  "fast-check": "^3.19.0",
69
+ "husky": "^9.1.6",
65
70
  "jest": "29.7.0",
66
71
  "js-yaml": "^4.1.0",
67
72
  "nock": "^13.5.4",
68
- "ts-jest": "29.2.5",
69
- "husky": "^9.1.6"
73
+ "ts-jest": "29.2.5"
70
74
  },
71
75
  "peerDependencies": {
76
+ "@types/prompts": "2.4.9",
72
77
  "@typescript-eslint/eslint-plugin": "7.18.0",
73
78
  "@typescript-eslint/parser": "7.18.0",
74
79
  "commander": "12.1.0",
@@ -76,7 +81,6 @@
76
81
  "eslint": "8.57.0",
77
82
  "node-forge": "1.3.1",
78
83
  "prettier": "3.3.3",
79
- "@types/prompts": "2.4.9",
80
84
  "prompts": "2.4.2",
81
85
  "typescript": "5.3.3",
82
86
  "uuid": "10.0.0"
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Determine the RBAC mode based on the CLI options and the module's config
3
+ * @param opts CLI options
4
+ * @param cfg Module's config
5
+ * @returns The determined RBAC mode
6
+ * @example
7
+ * const opts = { rbacMode: "admin" };
8
+ * const cfg = { pepr: { rbacMode: "scoped" } };
9
+ * const result = determineRbacMode(opts, cfg);
10
+ * console.log(result); // "admin"
11
+ */
12
+ export function determineRbacMode(
13
+ opts: { rbacMode?: string },
14
+ cfg: { pepr: { rbacMode?: string } },
15
+ ): string {
16
+ // CLI overrides the module's config
17
+ if (opts.rbacMode) {
18
+ return opts.rbacMode;
19
+ }
20
+
21
+ // if rbacMode is defined and not scoped, return admin
22
+ if (cfg.pepr.rbacMode && cfg.pepr.rbacMode !== "scoped") {
23
+ return "admin";
24
+ }
25
+
26
+ // if nothing is defined return admin, else return scoped
27
+ return cfg.pepr.rbacMode || "admin";
28
+ }
package/src/cli/build.ts CHANGED
@@ -13,7 +13,7 @@ import { peprFormat } from "./format";
13
13
  import { Option } from "commander";
14
14
  import { createDirectoryIfNotExists, validateCapabilityNames, parseTimeout } from "../lib/helpers";
15
15
  import { sanitizeResourceName } from "../sdk/sdk";
16
-
16
+ import { determineRbacMode } from "./build.helpers";
17
17
  const peprTS = "pepr.ts";
18
18
  let outputDir: string = "dist";
19
19
  export type Reloader = (opts: BuildResult<BuildOptions>) => void | Promise<void>;
@@ -66,9 +66,9 @@ export default function (program: RootCmd) {
66
66
  .default("manifest"),
67
67
  )
68
68
  .addOption(
69
- new Option("--rbac-mode [admin|scoped]", "Rbac Mode: admin, scoped (default: admin)")
70
- .choices(["admin", "scoped"])
71
- .default("admin"),
69
+ new Option("--rbac-mode [admin|scoped]", "Rbac Mode: admin, scoped (default: admin)").choices(
70
+ ["admin", "scoped"],
71
+ ),
72
72
  )
73
73
  .action(async opts => {
74
74
  // assign custom output directory if provided
@@ -81,113 +81,119 @@ export default function (program: RootCmd) {
81
81
  }
82
82
 
83
83
  // Build the module
84
- const { cfg, path, uuid } = await buildModule(undefined, opts.entryPoint, opts.embed);
85
-
86
- // Files to include in controller image for WASM support
87
- const { includedFiles } = cfg.pepr;
88
-
89
- let image: string = "";
84
+ const buildModuleResult = await buildModule(undefined, opts.entryPoint, opts.embed);
85
+ if (buildModuleResult?.cfg && buildModuleResult.path && buildModuleResult.uuid) {
86
+ const { cfg, path, uuid } = buildModuleResult;
87
+ // Files to include in controller image for WASM support
88
+ const { includedFiles } = cfg.pepr;
89
+
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
+ }
90
100
 
91
- // Build Kubernetes manifests with custom image
92
- if (opts.customImage) {
93
- if (opts.registry) {
94
- console.error(`Custom Image and registry cannot be used together.`);
95
- process.exit(1);
101
+ // Check if there is a custom timeout defined
102
+ if (opts.timeout !== undefined) {
103
+ cfg.pepr.webhookTimeout = opts.timeout;
96
104
  }
97
- image = opts.customImage;
98
- }
99
105
 
100
- // Check if there is a custom timeout defined
101
- if (opts.timeout !== undefined) {
102
- cfg.pepr.webhookTimeout = opts.timeout;
103
- }
106
+ if (opts.registryInfo !== undefined) {
107
+ console.info(`Including ${includedFiles.length} files in controller image.`);
104
108
 
105
- if (opts.registryInfo !== undefined) {
106
- console.info(`Including ${includedFiles.length} files in controller image.`);
109
+ // for journey test to make sure the image is built
110
+ image = `${opts.registryInfo}/custom-pepr-controller:${cfg.pepr.peprVersion}`;
107
111
 
108
- // for journey test to make sure the image is built
109
- image = `${opts.registryInfo}/custom-pepr-controller:${cfg.pepr.peprVersion}`;
112
+ // 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
+ }
120
+ }
110
121
 
111
- // only actually build/push if there are files to include
112
- if (includedFiles.length > 0) {
113
- await createDockerfile(cfg.pepr.peprVersion, cfg.description, includedFiles);
114
- execSync(`docker build --tag ${image} -f Dockerfile.controller .`, { stdio: "inherit" });
115
- execSync(`docker push ${image}`, { stdio: "inherit" });
122
+ // If building without embedding, exit after building
123
+ if (!opts.embed) {
124
+ console.info(`✅ Module built successfully at ${path}`);
125
+ return;
116
126
  }
117
- }
118
127
 
119
- // If building without embedding, exit after building
120
- if (!opts.embed) {
121
- console.info(`✅ Module built successfully at ${path}`);
122
- return;
123
- }
128
+ // set the image version if provided
129
+ if (opts.version) {
130
+ cfg.pepr.peprVersion = opts.version;
131
+ }
124
132
 
125
- // set the image version if provided
126
- if (opts.version) {
127
- cfg.pepr.peprVersion = opts.version;
128
- }
133
+ // Generate a secret for the module
134
+ const assets = new Assets(
135
+ {
136
+ ...cfg.pepr,
137
+ appVersion: cfg.version,
138
+ description: cfg.description,
139
+ // Can override the rbacMode with the CLI option
140
+ rbacMode: determineRbacMode(opts, cfg),
141
+ },
142
+ path,
143
+ );
129
144
 
130
- // Generate a secret for the module
131
- const assets = new Assets(
132
- {
133
- ...cfg.pepr,
134
- appVersion: cfg.version,
135
- description: cfg.description,
136
- },
137
- path,
138
- );
145
+ // 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
+ }
139
152
 
140
- // If registry is set to Iron Bank, use Iron Bank image
141
- if (opts?.registry === "Iron Bank") {
142
- console.info(
143
- `\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.`,
144
- );
145
- image = `registry1.dso.mil/ironbank/opensource/defenseunicorns/pepr/controller:v${cfg.pepr.peprVersion}`;
146
- }
153
+ // if image is a custom image, use that instead of the default
154
+ if (image !== "") {
155
+ assets.image = image;
156
+ }
147
157
 
148
- // if image is a custom image, use that instead of the default
149
- if (image !== "") {
150
- assets.image = image;
151
- }
158
+ // 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
+ }
152
168
 
153
- // Ensure imagePullSecret is valid
154
- if (opts.withPullSecret) {
155
- if (sanitizeResourceName(opts.withPullSecret) !== opts.withPullSecret) {
156
- // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
157
- console.error(
158
- "Invalid imagePullSecret. Please provide a valid name as defined in RFC 1123.",
159
- );
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);
160
179
  process.exit(1);
161
180
  }
162
- }
163
181
 
164
- const yamlFile = `pepr-module-${uuid}.yaml`;
165
- const chartPath = `${uuid}-chart`;
166
- const yamlPath = resolve(outputDir, yamlFile);
167
- const yaml = await assets.allYaml(opts.rbacMode, opts.withPullSecret);
168
-
169
- try {
170
- // wait for capabilities to be loaded and test names
171
- validateCapabilityNames(assets.capabilities);
172
- } catch (e) {
173
- console.error(`Error loading capability:`, e);
174
- process.exit(1);
175
- }
176
-
177
- const zarfPath = resolve(outputDir, "zarf.yaml");
182
+ const zarfPath = resolve(outputDir, "zarf.yaml");
178
183
 
179
- let zarf = "";
180
- if (opts.zarf === "chart") {
181
- zarf = assets.zarfYamlChart(chartPath);
182
- } else {
183
- zarf = assets.zarfYaml(yamlFile);
184
- }
185
- await fs.writeFile(yamlPath, yaml);
186
- await fs.writeFile(zarfPath, zarf);
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);
187
192
 
188
- await assets.generateHelmChart(outputDir);
193
+ await assets.generateHelmChart(outputDir);
189
194
 
190
- console.info(`✅ K8s resource for the module saved to ${yamlPath}`);
195
+ console.info(`✅ K8s resource for the module saved to ${yamlPath}`);
196
+ }
191
197
  });
192
198
  }
193
199
 
@@ -330,41 +336,38 @@ export async function buildModule(reloader?: Reloader, entryPoint = peprTS, embe
330
336
  } catch (e) {
331
337
  console.error(`Error building module:`, e);
332
338
 
333
- if (e.stdout) {
334
- const out = e.stdout.toString() as string;
335
- const err = e.stderr.toString();
339
+ if (!e.stdout) process.exit(1); // Exit with a non-zero exit code on any other error
336
340
 
337
- console.log(out);
338
- console.error(err);
341
+ const out = e.stdout.toString() as string;
342
+ const err = e.stderr.toString();
339
343
 
340
- // Check for version conflicts
341
- if (out.includes("Types have separate declarations of a private property '_name'.")) {
342
- // Try to find the conflicting package
343
- const pgkErrMatch = /error TS2322: .*? 'import\("\/.*?\/node_modules\/(.*?)\/node_modules/g;
344
- out.matchAll(pgkErrMatch);
344
+ console.log(out);
345
+ console.error(err);
345
346
 
346
- // Look for package conflict errors
347
- const conflicts = [...out.matchAll(pgkErrMatch)];
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);
348
352
 
349
- // If the regex didn't match, leave a generic error
350
- if (conflicts.length < 1) {
351
- console.info(
352
- `\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.`,
353
- "Version Conflict",
354
- );
355
- }
353
+ // Look for package conflict errors
354
+ const conflicts = [...out.matchAll(pgkErrMatch)];
356
355
 
357
- // Otherwise, loop through each conflicting package and print an error
358
- conflicts.forEach(match => {
359
- console.info(
360
- `\n\tPackage '${match[1]}' seems to be incompatible with your current version of Pepr.\n\tTry updating to the latest version.`,
361
- "Version Conflict",
362
- );
363
- });
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
+ );
364
362
  }
365
- }
366
363
 
367
- // On any other error, exit with a non-zero exit code
368
- process.exit(1);
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
+ });
371
+ }
369
372
  }
370
373
  }
package/src/cli/deploy.ts CHANGED
@@ -72,34 +72,37 @@ export default function (program: RootCmd) {
72
72
  }
73
73
 
74
74
  // Build the module
75
- const { cfg, path } = await buildModule();
75
+ const buildModuleResult = await buildModule();
76
+ if (buildModuleResult?.cfg && buildModuleResult?.path) {
77
+ const { cfg, path } = buildModuleResult;
76
78
 
77
- // Generate a secret for the module
78
- const webhook = new Assets(
79
- {
80
- ...cfg.pepr,
81
- description: cfg.description,
82
- },
83
- path,
84
- );
79
+ // Generate a secret for the module
80
+ const webhook = new Assets(
81
+ {
82
+ ...cfg.pepr,
83
+ description: cfg.description,
84
+ },
85
+ path,
86
+ );
85
87
 
86
- if (opts.image) {
87
- webhook.image = opts.image;
88
- }
88
+ if (opts.image) {
89
+ webhook.image = opts.image;
90
+ }
89
91
 
90
- // Identify conf'd webhookTimeout to give to deploy call
91
- const timeout = cfg.pepr.webhookTimeout ? cfg.pepr.webhookTimeout : 10;
92
+ // Identify conf'd webhookTimeout to give to deploy call
93
+ const timeout = cfg.pepr.webhookTimeout ? cfg.pepr.webhookTimeout : 10;
92
94
 
93
- try {
94
- await webhook.deploy(opts.force, timeout);
95
- // wait for capabilities to be loaded and test names
96
- validateCapabilityNames(webhook.capabilities);
97
- // Wait for the pepr-system resources to be fully up
98
- await namespaceDeploymentsReady();
99
- console.info(`✅ Module deployed successfully`);
100
- } catch (e) {
101
- console.error(`Error deploying module:`, e);
102
- process.exit(1);
95
+ try {
96
+ await webhook.deploy(opts.force, timeout);
97
+ // wait for capabilities to be loaded and test names
98
+ validateCapabilityNames(webhook.capabilities);
99
+ // Wait for the pepr-system resources to be fully up
100
+ await namespaceDeploymentsReady();
101
+ console.info(`✅ Module deployed successfully`);
102
+ } catch (e) {
103
+ console.error(`Error deploying module:`, e);
104
+ process.exit(1);
105
+ }
103
106
  }
104
107
  });
105
108
  }
package/src/cli/dev.ts CHANGED
@@ -9,7 +9,7 @@ import { Assets } from "../lib/assets";
9
9
  import { buildModule, loadModule } from "./build";
10
10
  import { RootCmd } from "./root";
11
11
  import { K8s, kind } from "kubernetes-fluent-client";
12
- import { PeprStore } from "../lib/k8s";
12
+ import { Store } from "../lib/k8s";
13
13
  export default function (program: RootCmd) {
14
14
  program
15
15
  .command("dev")
@@ -86,8 +86,8 @@ export default function (program: RootCmd) {
86
86
  await Promise.all([
87
87
  K8s(kind.MutatingWebhookConfiguration).Delete(name),
88
88
  K8s(kind.ValidatingWebhookConfiguration).Delete(name),
89
- K8s(PeprStore).InNamespace("pepr-system").Delete(scheduleStore),
90
- K8s(PeprStore).InNamespace("pepr-system").Delete(store),
89
+ K8s(Store).InNamespace("pepr-system").Delete(scheduleStore),
90
+ K8s(Store).InNamespace("pepr-system").Delete(store),
91
91
  ]);
92
92
  });
93
93
 
package/src/cli/format.ts CHANGED
@@ -63,13 +63,10 @@ export async function peprFormat(validateOnly: boolean) {
63
63
  const formatted = await format(content, { filepath: filePath, ...cfg });
64
64
 
65
65
  // If in validate-only mode, check if the file is formatted correctly
66
- if (validateOnly) {
67
- if (formatted !== content) {
68
- hasFailure = true;
69
- console.error(`File ${filePath} is not formatted correctly`);
70
- }
66
+ if (validateOnly && formatted !== content) {
67
+ hasFailure = true;
68
+ console.error(`File ${filePath} is not formatted correctly`);
71
69
  } else {
72
- // Otherwise, write the formatted file
73
70
  await fs.writeFile(filePath, formatted);
74
71
  }
75
72
  }
@@ -74,25 +74,7 @@ export default function (program: RootCmd) {
74
74
  await write(resolve(dirName, "capabilities", helloPepr.path), helloPepr.data);
75
75
 
76
76
  if (!opts.skipPostInit) {
77
- // run npm install from the new directory
78
- process.chdir(dirName);
79
- execSync("npm install", {
80
- stdio: "inherit",
81
- });
82
-
83
- // setup git
84
- execSync("git init --initial-branch=main", {
85
- stdio: "inherit",
86
- });
87
-
88
- // try to open vscode
89
- try {
90
- execSync("code .", {
91
- stdio: "inherit",
92
- });
93
- } catch (e) {
94
- // vscode not found, do nothing
95
- }
77
+ doPostInitActions(dirName);
96
78
  }
97
79
 
98
80
  console.log(`New Pepr module created at ${dirName}`);
@@ -106,3 +88,25 @@ export default function (program: RootCmd) {
106
88
  }
107
89
  });
108
90
  }
91
+
92
+ const doPostInitActions = (dirName: string): void => {
93
+ // run npm install from the new directory
94
+ process.chdir(dirName);
95
+ execSync("npm install", {
96
+ stdio: "inherit",
97
+ });
98
+
99
+ // setup git
100
+ execSync("git init --initial-branch=main", {
101
+ stdio: "inherit",
102
+ });
103
+
104
+ // try to open vscode
105
+ try {
106
+ execSync("code .", {
107
+ stdio: "inherit",
108
+ });
109
+ } catch (e) {
110
+ // vscode not found, do nothing
111
+ }
112
+ };