pepr 0.45.0 → 0.45.1-nightly.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 (63) hide show
  1. package/README.md +15 -7
  2. package/dist/cli/build.d.ts +1 -1
  3. package/dist/cli/build.d.ts.map +1 -1
  4. package/dist/cli/build.helpers.d.ts +1 -1
  5. package/dist/cli/init/templates.d.ts +5 -2
  6. package/dist/cli/init/templates.d.ts.map +1 -1
  7. package/dist/cli.js +31 -37
  8. package/dist/controller.js +1 -1
  9. package/dist/lib/assets/assets.d.ts +3 -3
  10. package/dist/lib/assets/assets.d.ts.map +1 -1
  11. package/dist/lib/assets/index.d.ts +1 -1
  12. package/dist/lib/assets/index.d.ts.map +1 -1
  13. package/dist/lib/assets/networking.d.ts +1 -1
  14. package/dist/lib/assets/networking.d.ts.map +1 -1
  15. package/dist/lib/assets/pods.d.ts +1 -1
  16. package/dist/lib/assets/pods.d.ts.map +1 -1
  17. package/dist/lib/assets/yaml/overridesFile.d.ts +3 -3
  18. package/dist/lib/assets/yaml/overridesFile.d.ts.map +1 -1
  19. package/dist/lib/controller/index.d.ts +1 -1
  20. package/dist/lib/controller/index.d.ts.map +1 -1
  21. package/dist/lib/core/envChecks.d.ts +4 -0
  22. package/dist/lib/core/envChecks.d.ts.map +1 -0
  23. package/dist/lib/core/module.d.ts +1 -51
  24. package/dist/lib/core/module.d.ts.map +1 -1
  25. package/dist/lib/processors/mutate-processor.d.ts +1 -1
  26. package/dist/lib/processors/mutate-processor.d.ts.map +1 -1
  27. package/dist/lib/processors/validate-processor.d.ts +1 -1
  28. package/dist/lib/processors/validate-processor.d.ts.map +1 -1
  29. package/dist/lib/processors/watch-processor.d.ts +22 -1
  30. package/dist/lib/processors/watch-processor.d.ts.map +1 -1
  31. package/dist/lib/telemetry/metrics.d.ts +2 -3
  32. package/dist/lib/telemetry/metrics.d.ts.map +1 -1
  33. package/dist/lib/types.d.ts +45 -0
  34. package/dist/lib/types.d.ts.map +1 -1
  35. package/dist/lib.js +2019 -2019
  36. package/dist/lib.js.map +4 -4
  37. package/dist/sdk/sdk.d.ts +6 -1
  38. package/dist/sdk/sdk.d.ts.map +1 -1
  39. package/package.json +11 -8
  40. package/src/cli/build.helpers.ts +1 -1
  41. package/src/cli/build.ts +3 -11
  42. package/src/cli/dev.ts +1 -1
  43. package/src/cli/init/templates.ts +1 -1
  44. package/src/lib/assets/assets.ts +8 -8
  45. package/src/lib/assets/deploy.ts +4 -4
  46. package/src/lib/assets/destroy.ts +1 -1
  47. package/src/lib/assets/helm.ts +4 -4
  48. package/src/lib/assets/index.ts +2 -3
  49. package/src/lib/assets/networking.ts +3 -3
  50. package/src/lib/assets/pods.ts +5 -5
  51. package/src/lib/assets/webhooks.ts +5 -5
  52. package/src/lib/assets/yaml/generateAllYaml.ts +3 -3
  53. package/src/lib/assets/yaml/overridesFile.ts +4 -4
  54. package/src/lib/controller/index.ts +20 -19
  55. package/src/lib/core/capability.ts +1 -1
  56. package/src/lib/core/envChecks.ts +6 -0
  57. package/src/lib/core/module.ts +3 -62
  58. package/src/lib/processors/mutate-processor.ts +1 -1
  59. package/src/lib/processors/validate-processor.ts +1 -1
  60. package/src/lib/processors/watch-processor.ts +58 -33
  61. package/src/lib/telemetry/metrics.ts +4 -4
  62. package/src/lib/types.ts +48 -0
  63. package/src/sdk/sdk.ts +8 -4
package/dist/sdk/sdk.d.ts CHANGED
@@ -19,7 +19,12 @@ export declare function containers(request: PeprValidateRequest<kind.Pod> | Pepr
19
19
  * @param reportingComponent The component that is reporting the event, for example "uds.dev/operator"
20
20
  * @param reportingInstance The instance of the component that is reporting the event, for example process.env.HOSTNAME
21
21
  */
22
- export declare function writeEvent(cr: GenericKind, event: Partial<kind.CoreEvent>, eventType: string, eventReason: string, reportingComponent: string, reportingInstance: string): Promise<void>;
22
+ export declare function writeEvent(cr: GenericKind, event: Partial<kind.CoreEvent>, options: {
23
+ eventType: string;
24
+ eventReason: string;
25
+ reportingComponent: string;
26
+ reportingInstance: string;
27
+ }): Promise<void>;
23
28
  /**
24
29
  * Get the owner reference for a custom resource
25
30
  * @param customResource the custom resource to get the owner reference for
@@ -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,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"}
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,OAAO,EAAE;IACP,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GACA,OAAO,CAAC,IAAI,CAAC,CAuBf;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.45.0",
18
+ "version": "0.45.1-nightly.0",
19
19
  "main": "dist/lib.js",
20
20
  "types": "dist/lib.d.ts",
21
21
  "scripts": {
@@ -24,18 +24,21 @@
24
24
  "prebuild": "rm -fr dist/* && npm run gen-data-json",
25
25
  "build": "tsc && node build.mjs && npm pack",
26
26
  "build:image": "npm run build && docker buildx build --output type=docker --tag pepr:dev .",
27
+ "build:image:unicorn": "npm run build && docker buildx build -f Dockerfile.unicorn --output type=docker --tag pepr:dev .",
27
28
  "set:version": "node scripts/set-version.js",
28
- "test": "npm run test:unit && npm run test:journey",
29
+ "test": "npm run test:unit && npm run test:journey && npm run test:journey-wasm",
29
30
  "test:unit": "npm run gen-data-json && jest src --coverage --detectOpenHandles --coverageDirectory=./coverage --testPathIgnorePatterns='cosign.e2e.test.ts'",
30
31
  "test:integration": "npm run test:integration:prep && npm run test:integration:run",
31
32
  "test:integration:prep": "./integration/prep.sh",
32
33
  "test:integration:run": "jest --maxWorkers=4 integration",
33
34
  "test:journey": "npm run test:journey:k3d && npm run build && npm run test:journey:image && npm run test:journey:run",
34
- "test:journey:prep": "if [ ! -d ./pepr-upgrade-test ]; then git clone https://github.com/defenseunicorns/pepr-upgrade-test.git ; fi",
35
+ "test:journey:unicorn": "npm run test:journey:k3d && npm run build && npm run test:journey:image:unicorn && npm run test:journey:run",
35
36
  "test:journey-wasm": "npm run test:journey:k3d && npm run build && npm run test:journey:image && npm run test:journey:run-wasm",
37
+ "test:journey-wasm:unicorn": "npm run test:journey:k3d && npm run build && npm run test:journey:image:unicorn && npm run test:journey:run-wasm",
36
38
  "test:journey:k3d": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0' --wait && kubectl rollout status deployment -n kube-system",
37
39
  "test:journey:image": "docker buildx build --output type=docker --tag pepr:dev . && k3d image import pepr:dev -c pepr-dev",
38
- "test:journey:run": "jest --detectOpenHandles journey/entrypoint.test.ts && npm run test:journey:prep && npm run test:journey:upgrade",
40
+ "test:journey:image:unicorn": "docker buildx build -f Dockerfile.unicorn --output type=docker --tag pepr:dev . && k3d image import pepr:dev -c pepr-dev",
41
+ "test:journey:run": "jest --detectOpenHandles journey/entrypoint.test.ts && npm run test:journey:upgrade",
39
42
  "test:journey:run-wasm": "jest --detectOpenHandles journey/entrypoint-wasm.test.ts",
40
43
  "test:journey:upgrade": "npm run test:journey:k3d && npm run test:journey:image && jest --detectOpenHandles journey/pepr-upgrade.test.ts",
41
44
  "format:check": "eslint src && prettier src --check",
@@ -49,12 +52,12 @@
49
52
  "follow-redirects": "1.15.9",
50
53
  "http-status-codes": "^2.3.0",
51
54
  "json-pointer": "^0.6.2",
52
- "kubernetes-fluent-client": "3.3.8",
55
+ "kubernetes-fluent-client": "3.4.0",
53
56
  "pino": "9.6.0",
54
57
  "pino-pretty": "13.0.0",
55
58
  "prom-client": "15.1.3",
56
59
  "ramda": "0.30.1",
57
- "sigstore": "3.0.0"
60
+ "sigstore": "3.1.0"
58
61
  },
59
62
  "devDependencies": {
60
63
  "@commitlint/cli": "19.7.1",
@@ -84,7 +87,7 @@
84
87
  "@typescript-eslint/eslint-plugin": "8.23.0",
85
88
  "@typescript-eslint/parser": "8.23.0",
86
89
  "commander": "13.1.0",
87
- "esbuild": "0.24.2",
90
+ "esbuild": "0.25.0",
88
91
  "eslint": "8.57.0",
89
92
  "node-forge": "1.3.1",
90
93
  "prettier": "3.4.2",
@@ -92,4 +95,4 @@
92
95
  "typescript": "5.7.3",
93
96
  "uuid": "11.0.5"
94
97
  }
95
- }
98
+ }
@@ -94,7 +94,7 @@ export async function handleCustomOutputDir(outputDir: string): Promise<string>
94
94
  * Check if the image is from Iron Bank and return the correct image
95
95
  * @param registry The registry of the image
96
96
  * @param image The image to check
97
- * @param peprVersion The version of the PEPR controller
97
+ * @param peprVersion The version of the Pepr controller
98
98
  * @returns The image string
99
99
  * @example
100
100
  */
package/src/cli/build.ts CHANGED
@@ -11,7 +11,7 @@ import { RootCmd } from "./root";
11
11
  import { Option } from "commander";
12
12
  import { parseTimeout } from "../lib/helpers";
13
13
  import { peprFormat } from "./format";
14
- import { ModuleConfig } from "../lib/core/module";
14
+ import { ModuleConfig } from "../lib/types";
15
15
  import {
16
16
  watchForChanges,
17
17
  determineRbacMode,
@@ -77,13 +77,13 @@ export default function (program: RootCmd): void {
77
77
  new Option(
78
78
  "-i, --custom-image <custom-image>",
79
79
  "Specify a custom image (including version) for Admission and Watch Deployments. Example: 'docker.io/username/custom-pepr-controller:v1.0.0'",
80
- ).conflicts(["version", "registryInfo", "registry"]),
80
+ ).conflicts(["registryInfo", "registry"]),
81
81
  )
82
82
  .addOption(
83
83
  new Option(
84
84
  "-r, --registry-info [<registry>/<username>]",
85
85
  "Provide the image registry and username for building and pushing a custom WASM container. Requires authentication. Builds and pushes 'registry/username/custom-pepr-controller:<current-version>'.",
86
- ).conflicts(["customImage", "version", "registry"]),
86
+ ).conflicts(["customImage", "registry"]),
87
87
  )
88
88
 
89
89
  .option("-o, --output-dir <output directory>", "Define where to place build output")
@@ -92,12 +92,6 @@ export default function (program: RootCmd): void {
92
92
  "How long the API server should wait for a webhook to respond before treating the call as a failure",
93
93
  parseTimeout,
94
94
  )
95
- .addOption(
96
- new Option(
97
- "-v, --version <version>",
98
- "The version of the Pepr image to use in the deployment manifests. Example: '0.27.3'.",
99
- ).conflicts(["customImage", "registryInfo"]),
100
- )
101
95
  .option(
102
96
  "--withPullSecret <imagePullSecret>",
103
97
  "Image Pull Secret: Use image pull secret for controller Deployment.",
@@ -164,8 +158,6 @@ export default function (program: RootCmd): void {
164
158
  console.info(`✅ Module built successfully at ${path}`);
165
159
  return;
166
160
  }
167
- // set the image version if provided
168
- if (opts.version) cfg.pepr.peprVersion = opts.version;
169
161
 
170
162
  // Generate a secret for the module
171
163
  const assets = new Assets(
package/src/cli/dev.ts CHANGED
@@ -77,7 +77,7 @@ export default function (program: RootCmd): void {
77
77
  ...process.env,
78
78
  LOG_LEVEL: "debug",
79
79
  PEPR_MODE: "dev",
80
- PEPR_API_TOKEN: webhook.apiToken,
80
+ PEPR_API_PATH: webhook.apiPath,
81
81
  PEPR_PRETTY_LOGS: "true",
82
82
  SSL_KEY_PATH: "insecure-tls.key",
83
83
  SSL_CERT_PATH: "insecure-tls.crt",
@@ -11,7 +11,7 @@ import prettierJSON from "../../templates/.prettierrc.json";
11
11
  import samplesJSON from "../../templates/capabilities/hello-pepr.samples.json";
12
12
  import settingsJSON from "../../templates/settings.json";
13
13
  import tsConfigJSON from "../../templates/tsconfig.module.json";
14
- import { CustomLabels } from "../../lib/core/module";
14
+ import { CustomLabels } from "../../lib/types";
15
15
  import { InitOptions } from "../types";
16
16
  import { OnError, RbacMode } from "./enums";
17
17
  import { V1PolicyRule as PolicyRule } from "@kubernetes/client-node";
@@ -1,6 +1,6 @@
1
1
  import crypto from "crypto";
2
2
  import { CapabilityExport } from "../types";
3
- import { ModuleConfig } from "../core/module";
3
+ import { ModuleConfig } from "../types";
4
4
  import { TLSOut, genTLS } from "../tls";
5
5
  import { WebhookIgnore } from "../k8s";
6
6
  import {
@@ -24,13 +24,13 @@ import { loadCapabilities } from "./loader";
24
24
  import { namespaceComplianceValidator, dedent } from "../helpers";
25
25
  import { promises as fs } from "fs";
26
26
  import { storeRole, storeRoleBinding, clusterRoleBinding, serviceAccount } from "./rbac";
27
- import { watcherService, service, tlsSecret, apiTokenSecret } from "./networking";
27
+ import { watcherService, service, tlsSecret, apiPathSecret } from "./networking";
28
28
  import { WebhookType } from "../enums";
29
29
 
30
30
  export class Assets {
31
31
  readonly name: string;
32
32
  readonly tls: TLSOut;
33
- readonly apiToken: string;
33
+ readonly apiPath: string;
34
34
  readonly config: ModuleConfig;
35
35
  readonly path: string;
36
36
  readonly alwaysIgnore!: WebhookIgnore;
@@ -53,8 +53,8 @@ export class Assets {
53
53
  // Generate the ephemeral tls things
54
54
  this.tls = genTLS(host || `${this.name}.pepr-system.svc`);
55
55
 
56
- // Generate the api token for the controller / webhook
57
- this.apiToken = crypto.randomBytes(32).toString("hex");
56
+ // Generate the api path for the controller / webhook
57
+ this.apiPath = crypto.randomBytes(32).toString("hex");
58
58
  }
59
59
 
60
60
  async deploy(
@@ -81,7 +81,7 @@ export class Assets {
81
81
 
82
82
  allYaml = async (
83
83
  yamlGenerationFunction: (
84
- assyts: Assets,
84
+ assets: Assets,
85
85
  deployments: { default: V1Deployment; watch: V1Deployment | null },
86
86
  ) => Promise<string>,
87
87
  imagePullSecret?: string,
@@ -149,7 +149,7 @@ export class Assets {
149
149
  [helm.files.watcherServiceYaml, (): string => toYaml(watcherService(this.name))],
150
150
  [helm.files.admissionServiceYaml, (): string => toYaml(service(this.name))],
151
151
  [helm.files.tlsSecretYaml, (): string => toYaml(tlsSecret(this.name, this.tls))],
152
- [helm.files.apiTokenSecretYaml, (): string => toYaml(apiTokenSecret(this.name, this.apiToken))],
152
+ [helm.files.apiPathSecretYaml, (): string => toYaml(apiPathSecret(this.name, this.apiPath))],
153
153
  [helm.files.storeRoleYaml, (): string => toYaml(storeRole(this.name))],
154
154
  [helm.files.storeRoleBindingYaml, (): string => toYaml(storeRoleBinding(this.name))],
155
155
  [helm.files.clusterRoleYaml, (): string => dedent(clusterRoleTemplate())],
@@ -164,7 +164,7 @@ export class Assets {
164
164
  name: this.name,
165
165
  image: this.image,
166
166
  config: this.config,
167
- apiToken: this.apiToken,
167
+ apiPath: this.apiPath,
168
168
  capabilities: this.capabilities,
169
169
  };
170
170
  await overridesFile(overrideData, helm.files.valuesYaml, this.imagePullSecrets);
@@ -8,7 +8,7 @@ import { V1PolicyRule as PolicyRule } from "@kubernetes/client-node";
8
8
 
9
9
  import { Assets } from "./assets";
10
10
  import Log from "../telemetry/logger";
11
- import { apiTokenSecret, service, tlsSecret, watcherService } from "./networking";
11
+ import { apiPathSecret, service, tlsSecret, watcherService } from "./networking";
12
12
  import { getDeployment, getModuleSecret, getNamespace, getWatcher } from "./pods";
13
13
  import { clusterRole, clusterRoleBinding, serviceAccount, storeRole, storeRoleBinding } from "./rbac";
14
14
  import { peprStoreCRD } from "./store";
@@ -136,9 +136,9 @@ async function setupController(assets: Assets, code: Buffer, hash: string, force
136
136
  const tls = tlsSecret(name, assets.tls);
137
137
  await K8s(kind.Secret).Apply(tls, { force });
138
138
 
139
- Log.info("Applying API token secret");
140
- const apiToken = apiTokenSecret(name, assets.apiToken);
141
- await K8s(kind.Secret).Apply(apiToken, { force });
139
+ Log.info("Applying API path secret");
140
+ const apiPath = apiPathSecret(name, assets.apiPath);
141
+ await K8s(kind.Secret).Apply(apiPath, { force });
142
142
 
143
143
  Log.info("Applying deployment");
144
144
  const dep = getDeployment(assets, hash, assets.buildTimestamp);
@@ -25,7 +25,7 @@ export async function destroyModule(name: string): Promise<void> {
25
25
  K8s(kind.Secret, { namespace }).Delete(`${name}-module`),
26
26
  K8s(kind.Service, { namespace }).Delete(name),
27
27
  K8s(kind.Secret, { namespace }).Delete(`${name}-tls`),
28
- K8s(kind.Secret, { namespace }).Delete(`${name}-api-token`),
28
+ K8s(kind.Secret, { namespace }).Delete(`${name}-api-path`),
29
29
  K8s(kind.Deployment, { namespace }).Delete(name),
30
30
  K8s(kind.Deployment, { namespace }).Delete(`${name}-watcher`),
31
31
  K8s(kind.Service, { namespace }).Delete(`${name}-watcher`),
@@ -221,8 +221,8 @@ export function admissionDeployTemplate(buildTimestamp: string): string {
221
221
  - name: tls-certs
222
222
  mountPath: /etc/certs
223
223
  readOnly: true
224
- - name: api-token
225
- mountPath: /app/api-token
224
+ - name: api-path
225
+ mountPath: /app/api-path
226
226
  readOnly: true
227
227
  - name: module
228
228
  mountPath: /app/load
@@ -234,9 +234,9 @@ export function admissionDeployTemplate(buildTimestamp: string): string {
234
234
  - name: tls-certs
235
235
  secret:
236
236
  secretName: {{ .Values.uuid }}-tls
237
- - name: api-token
237
+ - name: api-path
238
238
  secret:
239
- secretName: {{ .Values.uuid }}-api-token
239
+ secretName: {{ .Values.uuid }}-api-path
240
240
  - name: module
241
241
  secret:
242
242
  secretName: {{ .Values.uuid }}-module
@@ -5,14 +5,13 @@ import { dumpYaml } from "@kubernetes/client-node";
5
5
  import { kind } from "kubernetes-fluent-client";
6
6
  import { replaceString } from "../helpers";
7
7
  import { resolve } from "path";
8
- import { ModuleConfig } from "../core/module";
8
+ import { ModuleConfig } from "../types";
9
9
 
10
10
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
11
  export function toYaml(obj: any): string {
12
12
  return dumpYaml(obj, { noRefs: true });
13
13
  }
14
14
 
15
- // Unit Test Me!!
16
15
  export function createWebhookYaml(
17
16
  name: string,
18
17
  config: ModuleConfig,
@@ -81,7 +80,7 @@ export function helmLayout(basePath: string, unique: string): Record<string, Rec
81
80
  watcherDeploymentYaml: `${helm.dirs.tmpls}/watcher-deployment.yaml`,
82
81
  watcherServiceMonitorYaml: `${helm.dirs.tmpls}/watcher-service-monitor.yaml`,
83
82
  tlsSecretYaml: `${helm.dirs.tmpls}/tls-secret.yaml`,
84
- apiTokenSecretYaml: `${helm.dirs.tmpls}/api-token-secret.yaml`,
83
+ apiPathSecretYaml: `${helm.dirs.tmpls}/api-path-secret.yaml`,
85
84
  moduleSecretYaml: `${helm.dirs.tmpls}/module-secret.yaml`,
86
85
  storeRoleYaml: `${helm.dirs.tmpls}/store-role.yaml`,
87
86
  storeRoleBindingYaml: `${helm.dirs.tmpls}/store-role-binding.yaml`,
@@ -5,17 +5,17 @@ import { kind } from "kubernetes-fluent-client";
5
5
 
6
6
  import { TLSOut } from "../tls";
7
7
 
8
- export function apiTokenSecret(name: string, apiToken: string): kind.Secret {
8
+ export function apiPathSecret(name: string, apiPath: string): kind.Secret {
9
9
  return {
10
10
  apiVersion: "v1",
11
11
  kind: "Secret",
12
12
  metadata: {
13
- name: `${name}-api-token`,
13
+ name: `${name}-api-path`,
14
14
  namespace: "pepr-system",
15
15
  },
16
16
  type: "Opaque",
17
17
  data: {
18
- value: Buffer.from(apiToken).toString("base64"),
18
+ value: Buffer.from(apiPath).toString("base64"),
19
19
  },
20
20
  };
21
21
  }
@@ -6,7 +6,7 @@ import { kind } from "kubernetes-fluent-client";
6
6
  import { gzipSync } from "zlib";
7
7
  import { secretOverLimit } from "../helpers";
8
8
  import { Assets } from "./assets";
9
- import { ModuleConfig } from "../core/module";
9
+ import { ModuleConfig } from "../types";
10
10
  import { Binding } from "../types";
11
11
 
12
12
  /** Generate the pepr-system namespace */
@@ -297,8 +297,8 @@ export function getDeployment(
297
297
  readOnly: true,
298
298
  },
299
299
  {
300
- name: "api-token",
301
- mountPath: "/app/api-token",
300
+ name: "api-path",
301
+ mountPath: "/app/api-path",
302
302
  readOnly: true,
303
303
  },
304
304
  {
@@ -317,9 +317,9 @@ export function getDeployment(
317
317
  },
318
318
  },
319
319
  {
320
- name: "api-token",
320
+ name: "api-path",
321
321
  secret: {
322
- secretName: `${name}-api-token`,
322
+ secretName: `${name}-api-path`,
323
323
  },
324
324
  },
325
325
  {
@@ -75,7 +75,7 @@ export async function webhookConfigGenerator(
75
75
  ): Promise<kind.MutatingWebhookConfiguration | kind.ValidatingWebhookConfiguration | null> {
76
76
  const ignore: V1LabelSelectorRequirement[] = [];
77
77
 
78
- const { name, tls, config, apiToken, host } = assets;
78
+ const { name, tls, config, apiPath, host } = assets;
79
79
  const ignoreNS = concat(peprIgnoreNamespaces, resolveIgnoreNamespaces(config?.alwaysIgnore?.namespaces));
80
80
 
81
81
  // Add any namespaces to ignore
@@ -91,18 +91,18 @@ export async function webhookConfigGenerator(
91
91
  caBundle: tls.ca,
92
92
  };
93
93
 
94
- // The URL must include the API Token
95
- const apiPath = `/${mutateOrValidate}/${apiToken}`;
94
+ // The URL must include the API Path
95
+ const fullApiPath = `/${mutateOrValidate}/${apiPath}`;
96
96
 
97
97
  // If a host is specified, use that with a port of 3000
98
98
  if (host) {
99
- clientConfig.url = `https://${host}:3000${apiPath}`;
99
+ clientConfig.url = `https://${host}:3000${fullApiPath}`;
100
100
  } else {
101
101
  // Otherwise, use the service
102
102
  clientConfig.service = {
103
103
  name: name,
104
104
  namespace: "pepr-system",
105
- path: apiPath,
105
+ path: fullApiPath,
106
106
  };
107
107
  }
108
108
 
@@ -4,7 +4,7 @@
4
4
  import crypto from "crypto";
5
5
  import { Assets } from "../assets";
6
6
  import { WebhookType } from "../../enums";
7
- import { apiTokenSecret, service, tlsSecret, watcherService } from "../networking";
7
+ import { apiPathSecret, service, tlsSecret, watcherService } from "../networking";
8
8
  import { clusterRole, clusterRoleBinding, serviceAccount, storeRole, storeRoleBinding } from "../rbac";
9
9
  import { dumpYaml, V1Deployment } from "@kubernetes/client-node";
10
10
  import { getModuleSecret, getNamespace } from "../pods";
@@ -14,7 +14,7 @@ import { webhookConfigGenerator } from "../webhooks";
14
14
  type deployments = { default: V1Deployment; watch: V1Deployment | null };
15
15
 
16
16
  export async function generateAllYaml(assets: Assets, deployments: deployments): Promise<string> {
17
- const { name, tls, apiToken, path, config } = assets;
17
+ const { name, tls, apiPath, path, config } = assets;
18
18
  const code = await fs.readFile(path);
19
19
  const hash = crypto.createHash("sha256").update(code).digest("hex");
20
20
 
@@ -23,7 +23,7 @@ export async function generateAllYaml(assets: Assets, deployments: deployments):
23
23
  clusterRole(name, assets.capabilities, config.rbacMode, config.rbac),
24
24
  clusterRoleBinding(name),
25
25
  serviceAccount(name),
26
- apiTokenSecret(name, apiToken),
26
+ apiPathSecret(name, apiPath),
27
27
  tlsSecret(name, tls),
28
28
  deployments.default,
29
29
  service(name),
@@ -1,12 +1,12 @@
1
1
  import { genEnv } from "../pods";
2
- import { ModuleConfig } from "../../core/module";
2
+ import { ModuleConfig } from "../../types";
3
3
  import { CapabilityExport } from "../../types";
4
4
  import { dumpYaml } from "@kubernetes/client-node";
5
5
  import { clusterRole } from "../rbac";
6
6
  import { promises as fs } from "fs";
7
7
 
8
8
  type ChartOverrides = {
9
- apiToken: string;
9
+ apiPath: string;
10
10
  capabilities: CapabilityExport[];
11
11
  config: ModuleConfig;
12
12
  hash: string;
@@ -16,7 +16,7 @@ type ChartOverrides = {
16
16
 
17
17
  // Helm Chart overrides file (values.yaml) generated from assets
18
18
  export async function overridesFile(
19
- { hash, name, image, config, apiToken, capabilities }: ChartOverrides,
19
+ { hash, name, image, config, apiPath, capabilities }: ChartOverrides,
20
20
  path: string,
21
21
  imagePullSecrets: string[],
22
22
  ): Promise<void> {
@@ -27,7 +27,7 @@ export async function overridesFile(
27
27
  additionalIgnoredNamespaces: [],
28
28
  rbac: rbacOverrides,
29
29
  secrets: {
30
- apiToken: Buffer.from(apiToken).toString("base64"),
30
+ apiPath: Buffer.from(apiPath).toString("base64"),
31
31
  },
32
32
  hash,
33
33
  namespace: {
@@ -9,7 +9,8 @@ import { Capability } from "../core/capability";
9
9
  import { MutateResponse, ValidateResponse } from "../k8s";
10
10
  import Log from "../telemetry/logger";
11
11
  import { metricsCollector, MetricsCollector } from "../telemetry/metrics";
12
- import { ModuleConfig, isWatchMode } from "../core/module";
12
+ import { isWatchMode } from "../core/envChecks";
13
+ import { ModuleConfig } from "../types";
13
14
  import { mutateProcessor } from "../processors/mutate-processor";
14
15
  import { validateProcessor } from "../processors/validate-processor";
15
16
  import { StoreController } from "./store";
@@ -33,8 +34,8 @@ export class Controller {
33
34
  // Metrics collector
34
35
  #metricsCollector = metricsCollector;
35
36
 
36
- // The token used to authenticate requests
37
- #token = "";
37
+ // The path used to authenticate requests
38
+ #path = "";
38
39
 
39
40
  // The express app instance
40
41
  readonly #app = express();
@@ -92,14 +93,14 @@ export class Controller {
92
93
  cert: fs.readFileSync(process.env.SSL_CERT_PATH || "/etc/certs/tls.crt"),
93
94
  };
94
95
 
95
- // Get the API token if not in watch mode
96
+ // Get the API path if not in watch mode
96
97
  if (!isWatchMode()) {
97
- // Get the API token from the environment variable or the mounted secret
98
- this.#token = process.env.PEPR_API_TOKEN || fs.readFileSync("/app/api-token/value").toString().trim();
99
- Log.info(`Using API token: ${this.#token}`);
98
+ // Get the API path from the environment variable or the mounted secret
99
+ this.#path = process.env.PEPR_API_PATH || fs.readFileSync("/app/api-path/value").toString().trim();
100
+ Log.info(`Using API path: ${this.#path}`);
100
101
 
101
- if (!this.#token) {
102
- throw new Error("API token not found");
102
+ if (!this.#path) {
103
+ throw new Error("API path not found");
103
104
  }
104
105
  }
105
106
 
@@ -148,35 +149,35 @@ export class Controller {
148
149
  }
149
150
 
150
151
  // Require auth for webhook endpoints
151
- this.#app.use(["/mutate/:token", "/validate/:token"], this.#validateToken);
152
+ this.#app.use(["/mutate/:path", "/validate/:path"], this.#validatepath);
152
153
 
153
154
  // Mutate endpoint
154
- this.#app.post("/mutate/:token", this.#admissionReq("Mutate"));
155
+ this.#app.post("/mutate/:path", this.#admissionReq("Mutate"));
155
156
 
156
157
  // Validate endpoint
157
- this.#app.post("/validate/:token", this.#admissionReq("Validate"));
158
+ this.#app.post("/validate/:path", this.#admissionReq("Validate"));
158
159
  };
159
160
 
160
161
  /**
161
- * Validate the token in the request path
162
+ * Validate the path in the request path
162
163
  *
163
164
  * @param req The incoming request
164
165
  * @param res The outgoing response
165
166
  * @param next The next middleware function
166
167
  * @returns
167
168
  */
168
- #validateToken = (req: express.Request, res: express.Response, next: NextFunction): void => {
169
- // Validate the token
170
- const { token } = req.params;
171
- if (token !== this.#token) {
172
- const err = `Unauthorized: invalid token '${token.replace(/[^\w]/g, "_")}'`;
169
+ #validatepath = (req: express.Request, res: express.Response, next: NextFunction): void => {
170
+ // Validate the path
171
+ const { path } = req.params;
172
+ if (path !== this.#path) {
173
+ const err = `Unauthorized: invalid path '${path.replace(/[^\w]/g, "_")}'`;
173
174
  Log.info(err);
174
175
  res.status(401).send(err);
175
176
  this.#metricsCollector.alert();
176
177
  return;
177
178
  }
178
179
 
179
- // Token is valid, continue
180
+ // path is valid, continue
180
181
  next();
181
182
  };
182
183
 
@@ -4,7 +4,7 @@
4
4
  import { GenericClass, GroupVersionKind, modelToGroupVersionKind } from "kubernetes-fluent-client";
5
5
  import { pickBy } from "ramda";
6
6
  import Log from "../telemetry/logger";
7
- import { isBuildMode, isDevMode, isWatchMode } from "./module";
7
+ import { isBuildMode, isDevMode, isWatchMode } from "./envChecks";
8
8
  import { PeprStore, Storage } from "./storage";
9
9
  import { OnSchedule, Schedule } from "./schedule";
10
10
  import { Event } from "../enums";
@@ -0,0 +1,6 @@
1
+ export const isWatchMode = (): boolean => process.env.PEPR_WATCH_MODE === "true";
2
+ // Track if Pepr is running in build mode
3
+
4
+ export const isBuildMode = (): boolean => process.env.PEPR_MODE === "build";
5
+
6
+ export const isDevMode = (): boolean => process.env.PEPR_MODE === "dev";
@@ -4,71 +4,12 @@ import { clone } from "ramda";
4
4
  import { Capability } from "./capability";
5
5
  import { Controller, ControllerHooks } from "../controller";
6
6
  import { ValidateError } from "../errors";
7
- import { MutateResponse, ValidateResponse, WebhookIgnore } from "../k8s";
8
- import { CapabilityExport, AdmissionRequest } from "../types";
7
+ import { CapabilityExport } from "../types";
9
8
  import { setupWatch } from "../processors/watch-processor";
10
9
  import { Log } from "../../lib";
11
- import { V1PolicyRule as PolicyRule } from "@kubernetes/client-node";
12
10
  import { resolveIgnoreNamespaces } from "../assets/webhooks";
13
-
14
- /** Custom Labels Type for package.json */
15
-
16
- export type CustomLabels = { namespace: Record<string, string> } | Record<string, never>;
17
-
18
- /** Configuration that MAY be set a Pepr module's package.json. */
19
- export type ModuleConfigOptions = {
20
- /** The Pepr version this module uses */
21
- peprVersion: string;
22
- /** The user-defined version of the module */
23
- appVersion: string;
24
- /** A description of the Pepr module and what it does. */
25
- description: string;
26
- /** The webhookTimeout */
27
- webhookTimeout: number;
28
- /** Reject K8s resource AdmissionRequests on error. */
29
- onError: string;
30
- /** Define the log level for the in-cluster controllers */
31
- logLevel: string;
32
- /** Propagate env variables to in-cluster controllers */
33
- env: Record<string, string>;
34
- /** Custom RBAC rules */
35
- rbac: PolicyRule[];
36
- /** The RBAC mode; if "scoped", generates scoped rules, otherwise uses wildcard rules. */
37
- rbacMode: string;
38
- /** Custom Labels for Kubernetes Objects */
39
- customLabels: CustomLabels;
40
- };
41
-
42
- /** Global configuration for the Pepr runtime. */
43
- export type ModuleConfig = {
44
- /** A unique identifier for this Pepr module. This is automatically generated by Pepr. */
45
- uuid: string;
46
- /** Configure global exclusions that will never be processed by Pepr. */
47
- alwaysIgnore: WebhookIgnore;
48
- } & Partial<ModuleConfigOptions>;
49
-
50
- export type PackageJSON = {
51
- description: string;
52
- pepr: ModuleConfig;
53
- };
54
-
55
- export type PeprModuleOptions = {
56
- deferStart?: boolean;
57
-
58
- /** A user-defined callback to pre-process or intercept a Pepr request from K8s immediately before it is processed */
59
- beforeHook?: (req: AdmissionRequest) => void;
60
-
61
- /** A user-defined callback to post-process or intercept a Pepr response just before it is returned to K8s */
62
- afterHook?: (res: MutateResponse | ValidateResponse) => void;
63
- };
64
-
65
- // Track if this is a watch mode controller
66
- export const isWatchMode = (): boolean => process.env.PEPR_WATCH_MODE === "true";
67
-
68
- // Track if Pepr is running in build mode
69
- export const isBuildMode = (): boolean => process.env.PEPR_MODE === "build";
70
-
71
- export const isDevMode = (): boolean => process.env.PEPR_MODE === "dev";
11
+ import { isBuildMode, isDevMode, isWatchMode } from "./envChecks";
12
+ import { PackageJSON, PeprModuleOptions, ModuleConfig } from "../types";
72
13
 
73
14
  export class PeprModule {
74
15
  #controller!: Controller;