pepr 0.2.10 → 0.3.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 (71) hide show
  1. package/README.md +3 -46
  2. package/dist/package.json +21 -39
  3. package/dist/src/cli/build.js +3 -1
  4. package/dist/src/cli/dev.js +31 -19
  5. package/dist/src/cli/index.js +1 -0
  6. package/dist/src/cli/init/index.js +3 -1
  7. package/dist/src/cli/init/templates.js +3 -2
  8. package/dist/src/cli/init/utils.js +1 -1
  9. package/dist/src/cli/init/walkthrough.js +1 -1
  10. package/dist/src/cli/run.js +17 -17
  11. package/dist/src/cli/update.js +3 -1
  12. package/dist/src/lib/capability.js +1 -1
  13. package/dist/src/lib/controller.js +9 -1
  14. package/dist/src/lib/fetch.js +39 -6
  15. package/dist/src/lib/k8s/webhook.js +22 -22
  16. package/dist/src/lib/processor.js +4 -1
  17. package/{dist/index.d.ts → index.ts} +21 -3
  18. package/package.json +21 -39
  19. package/src/lib/capability.ts +158 -0
  20. package/src/lib/controller.ts +127 -0
  21. package/src/lib/fetch.ts +75 -0
  22. package/src/lib/filter.ts +87 -0
  23. package/{dist/src/lib/k8s/index.d.ts → src/lib/k8s/index.ts} +6 -0
  24. package/src/lib/k8s/kinds.ts +489 -0
  25. package/src/lib/k8s/tls.ts +90 -0
  26. package/src/lib/k8s/types.ts +183 -0
  27. package/src/lib/k8s/upstream.ts +49 -0
  28. package/src/lib/k8s/webhook.ts +547 -0
  29. package/src/lib/logger.ts +136 -0
  30. package/src/lib/module.ts +63 -0
  31. package/src/lib/processor.ts +98 -0
  32. package/src/lib/request.ts +140 -0
  33. package/src/lib/types.ts +211 -0
  34. package/dist/cli.d.ts +0 -2
  35. package/dist/cli.js +0 -4
  36. package/dist/run.d.ts +0 -2
  37. package/dist/run.js +0 -4
  38. package/dist/src/cli/banner.d.ts +0 -1
  39. package/dist/src/cli/build.d.ts +0 -7
  40. package/dist/src/cli/capability.d.ts +0 -2
  41. package/dist/src/cli/deploy.d.ts +0 -2
  42. package/dist/src/cli/dev.d.ts +0 -2
  43. package/dist/src/cli/index.d.ts +0 -1
  44. package/dist/src/cli/init/index.d.ts +0 -2
  45. package/dist/src/cli/init/templates.d.ts +0 -94
  46. package/dist/src/cli/init/utils.d.ts +0 -20
  47. package/dist/src/cli/init/walkthrough.d.ts +0 -7
  48. package/dist/src/cli/root.d.ts +0 -4
  49. package/dist/src/cli/run.d.ts +0 -1
  50. package/dist/src/cli/test.d.ts +0 -2
  51. package/dist/src/cli/update.d.ts +0 -2
  52. package/dist/src/lib/capability.d.ts +0 -28
  53. package/dist/src/lib/controller.d.ts +0 -17
  54. package/dist/src/lib/fetch.d.ts +0 -23
  55. package/dist/src/lib/filter.d.ts +0 -10
  56. package/dist/src/lib/k8s/kinds.d.ts +0 -11
  57. package/dist/src/lib/k8s/tls.d.ts +0 -17
  58. package/dist/src/lib/k8s/types.d.ts +0 -147
  59. package/dist/src/lib/k8s/upstream.d.ts +0 -3
  60. package/dist/src/lib/k8s/webhook.d.ts +0 -34
  61. package/dist/src/lib/logger.d.ts +0 -55
  62. package/dist/src/lib/module.d.ts +0 -32
  63. package/dist/src/lib/processor.d.ts +0 -4
  64. package/dist/src/lib/request.d.ts +0 -77
  65. package/dist/src/lib/types.d.ts +0 -187
  66. package/docs/.prettierrc.json +0 -13
  67. package/docs/actions.md +0 -58
  68. package/docs/capabilities.md +0 -17
  69. package/docs/cli.md +0 -58
  70. package/docs/module.md +0 -90
  71. package/osv-scanner.toml +0 -4
package/README.md CHANGED
@@ -9,7 +9,7 @@ Pepr is on a mission to save Kubernetes from the tyranny of YAML, intimidating g
9
9
  - Zero-config K8s webhook mutations and [validations soon](https://github.com/defenseunicorns/pepr/issues/73).
10
10
  - Human-readable fluent API for generating [Pepr Capabilities](#capability)
11
11
  - Generate new K8s resources based off of cluster resource changes
12
- - Perform other exec/API calls based off of cluster resources changes or any other abitrary schedule
12
+ - Perform other exec/API calls based off of cluster resources changes or any other arbitrary schedule
13
13
  - Out of the box airgap support with [Zarf](https://zarf.dev)
14
14
  - Entire NPM ecosystem available for advanced operations
15
15
  - Realtime K8s debugging system for testing/reacting to cluster changes
@@ -76,7 +76,7 @@ https://user-images.githubusercontent.com/882485/230895880-c5623077-f811-4870-bb
76
76
 
77
77
  ### Module
78
78
 
79
- A module is the top-level collection of capabilities. It is a single, complete TypeScript project that includes an entry point to load all the configuration and capabilities, along with their CapabilityActions. During the Pepr build process, each module produces a unique Kubernetes MutatingWebhookConfiguration and ValidatingWebhookConfiguration, along with a secret containing the transpiled and compressed TypeScript code. The webhooks and secret are deployed into the Kubernetes cluster for processing by a common Pepr controller.
79
+ A module is the top-level collection of capabilities. It is a single, complete TypeScript project that includes an entry point to load all the configuration and capabilities, along with their CapabilityActions. During the Pepr build process, each module produces a unique Kubernetes MutatingWebhookConfiguration and ValidatingWebhookConfiguration, along with a secret containing the transpiled and compressed TypeScript code. The webhooks and secret are deployed into the Kubernetes cluster with their own isolated controller.
80
80
 
81
81
  See [Module](./docs/module.md) for more details.
82
82
 
@@ -95,50 +95,7 @@ For example, a CapabilityAction could be responsible for adding a specific label
95
95
  See [CapabilityActions](./docs/actions.md) for more details.
96
96
 
97
97
  ## Logical Pepr Flow
98
-
99
- ```mermaid
100
- graph LR
101
-
102
- subgraph "Module 3 (Validate Only)"
103
- direction LR
104
- Q[entrypoint 3] --> R[Validate Webhook];
105
- R --> S[Capability a <br><i>- action 1<br>- action 2</i>];
106
- S --> T[Capability b <br><i>- action 1<br>- action 2</i>];
107
- end
108
-
109
- subgraph "Module 2 (Mutate Only)"
110
- direction LR
111
- K[entrypoint 2] --> L[Mutate Webhook];
112
- L --> M[Capability a <br><i>- action 1<br>- action 2</i>];
113
- M --> N[Capability b <br><i>- action 1<br>- action 2<br>- action 3</i>];
114
- N --> O[Capability c <br><i>- action 1</i>];
115
- end
116
-
117
- subgraph "Module 1 (Mutate & Validate)"
118
- direction LR
119
- A[entrypoint 1] --> B[Mutate Webhook];
120
- A --> C[Validate Webhook];
121
- B --> D[Capability a <br><i>- action 1</i>];
122
- D --> E[Capability b <br><i>- action 1<br>- action 2</i>];
123
- E --> F[Capability c <br><i>- action 1<br>- action 2</i>];
124
- C --> G[Capability d <br><i>- action 1<br>- action 2</i>];
125
- G --> H[Capability e <br><i>- action 1</i>];
126
- H --> I[Capability f <br><i>- action 1<br>- action 2<br>- action 3</i>];
127
- end
128
-
129
-
130
-
131
- %% Defining node styles
132
- classDef Validate fill:#66ff66,color:#000;
133
- classDef Mutate fill:#5786ea,color:#000;
134
-
135
-
136
- class L,M,N,O Mutate;
137
- class B,D,E,F Mutate;
138
-
139
- class R,S,T Validate;
140
- class C,G,H,I Validate;
141
- ```
98
+ ![Module Diagram](./.images/modules.svg)
142
99
 
143
100
  ## TypeScript
144
101
 
package/dist/package.json CHANGED
@@ -4,29 +4,17 @@
4
4
  "author": "Defense Unicorns",
5
5
  "homepage": "https://github.com/defenseunicorns/pepr",
6
6
  "license": "Apache-2.0",
7
- "bin": "dist/cli.js",
7
+ "bin": "dist/src/cli/index.js",
8
8
  "repository": "defenseunicorns/pepr",
9
9
  "engines": {
10
10
  "node": ">=18.0.0"
11
11
  },
12
- "version": "0.2.10",
12
+ "version": "0.3.0",
13
13
  "main": "dist/index.js",
14
- "types": "dist/index.d.ts",
15
- "pepr": {
16
- "name": "Development Module",
17
- "uuid": "20e17cf6-a2e4-46b2-b626-75d88d96c88b",
18
- "description": "Development module for pepr",
19
- "version": "dev",
20
- "onError": "ignore",
21
- "alwaysIgnore": {
22
- "namespaces": [],
23
- "labels": []
24
- }
25
- },
26
14
  "scripts": {
27
15
  "prebuild": "rm -fr dist/* && node hack/build-template-data.js",
28
- "build": "tsc -p tsconfig.build.json",
29
- "test:unit": "npm run build && ava",
16
+ "build": "tsc",
17
+ "test:unit": "npm run build && ava dist/**/*.test.js",
30
18
  "test:e2e": "npm run test:e2e:k3d && npm run test:e2e:build && npm run test:e2e:image && npm run test:e2e:run",
31
19
  "test:e2e:k3d": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'",
32
20
  "test:e2e:build": "npm run build && npm uninstall pepr -g && npm install -g . && pepr",
@@ -37,45 +25,39 @@
37
25
  },
38
26
  "dependencies": {
39
27
  "@kubernetes/client-node": "0.18.1",
40
- "@rollup/plugin-json": "6.0.0",
41
- "@rollup/plugin-node-resolve": "15.0.2",
42
- "@rollup/plugin-typescript": "11.1.0",
43
- "@types/ramda": "0.29.1",
44
- "chokidar": "3.5.3",
45
- "commander": "10.0.1",
46
28
  "express": "4.18.2",
47
29
  "fast-json-patch": "3.1.1",
48
30
  "http-status-codes": "2.2.0",
49
31
  "node-fetch": "2.6.9",
50
- "node-forge": "1.3.1",
51
- "prettier": "2.8.8",
52
- "prompts": "2.4.2",
53
- "ramda": "0.29.0",
54
- "rollup": "3.21.4",
55
- "ts-node": "10.9.1",
56
- "tslib": "2.5.0",
57
- "typescript": "5.0.4",
58
- "uuid": "9.0.0"
32
+ "ramda": "0.29.0"
59
33
  },
60
34
  "devDependencies": {
61
35
  "@types/express": "4.17.17",
62
36
  "@types/node-fetch": "2.6.3",
63
37
  "@types/node-forge": "1.3.2",
64
38
  "@types/prompts": "2.4.4",
39
+ "@types/ramda": "0.29.1",
65
40
  "@types/uuid": "9.0.1",
66
41
  "@typescript-eslint/eslint-plugin": "5.59.2",
67
42
  "@typescript-eslint/parser": "5.59.2",
68
43
  "ava": "5.2.0",
69
- "eslint": "8.39.0",
70
- "nock": "13.3.1"
44
+ "eslint": "8.40.0",
45
+ "nock": "13.3.1",
46
+ "prettier": "2.8.8"
47
+ },
48
+ "peerDependencies": {
49
+ "@rollup/plugin-json": "6.0.0",
50
+ "@rollup/plugin-node-resolve": "15.0.2",
51
+ "@rollup/plugin-typescript": "11.1.0",
52
+ "chokidar": "3.5.3",
53
+ "commander": "10.0.1",
54
+ "node-forge": "1.3.1",
55
+ "prompts": "2.4.2",
56
+ "rollup": "3.21.5",
57
+ "typescript": "5.0.4",
58
+ "uuid": "9.0.0"
71
59
  },
72
60
  "ava": {
73
- "extensions": [
74
- "ts"
75
- ],
76
- "require": [
77
- "ts-node/register"
78
- ],
79
61
  "failFast": true,
80
62
  "verbose": true
81
63
  }
@@ -111,7 +111,9 @@ async function buildModule() {
111
111
  catch (e) {
112
112
  // On any other error, exit with a non-zero exit code
113
113
  logger_1.default.debug(e);
114
- logger_1.default.error(e.message);
114
+ if (e instanceof Error) {
115
+ logger_1.default.error(e.message);
116
+ }
115
117
  process.exit(1);
116
118
  }
117
119
  }
@@ -47,23 +47,38 @@ function default_1(program) {
47
47
  try {
48
48
  await webhook.deploy(code);
49
49
  logger_1.default.info(`Module deployed successfully`);
50
- const moduleFiles = (0, path_1.resolve)(".", "**", "*.ts");
51
- const watcher = (0, chokidar_1.watch)(moduleFiles);
52
- const peprTS = (0, path_1.resolve)(".", "pepr.ts");
53
- let program;
54
- // Run the module once to start the server
55
- runDev(peprTS);
50
+ const moduleFiles = [
51
+ (0, path_1.resolve)(".", "pepr.ts"),
52
+ (0, path_1.resolve)(".", "capabilities", "*.ts"),
53
+ (0, path_1.resolve)(".", "capabilities", "**", "*.ts"),
54
+ ];
55
+ const watcher = (0, chokidar_1.watch)(moduleFiles, {
56
+ awaitWriteFinish: {
57
+ stabilityThreshold: 3000,
58
+ pollInterval: 500,
59
+ },
60
+ });
56
61
  // Watch for changes
57
- watcher.on("ready", () => {
62
+ watcher.on("ready", async () => {
63
+ let building = false;
64
+ // Run the module once to start the server
65
+ let program = await runDev();
58
66
  logger_1.default.info(`Watching for changes in ${moduleFiles}`);
59
67
  watcher.on("all", async (event, path) => {
60
68
  logger_1.default.debug({ event, path }, "File changed");
61
- // Kill the running process
62
- if (program) {
63
- program.kill("SIGKILL");
69
+ // If we're already building, skip this event
70
+ if (building) {
71
+ return;
64
72
  }
65
- // Start the process again
66
- program = runDev(peprTS);
73
+ // Set building to true
74
+ building = true;
75
+ // Don't start a new process until the old one exits
76
+ program.once("exit", async () => {
77
+ program = await runDev();
78
+ building = false;
79
+ });
80
+ // Kill the running process
81
+ program.kill();
67
82
  });
68
83
  });
69
84
  }
@@ -74,9 +89,11 @@ function default_1(program) {
74
89
  });
75
90
  }
76
91
  exports.default = default_1;
77
- function runDev(path) {
92
+ async function runDev() {
78
93
  try {
79
- const program = (0, child_process_1.spawn)("./node_modules/.bin/ts-node", [path], {
94
+ const { path } = await (0, build_1.buildModule)();
95
+ logger_1.default.info(`Running module ${path}`);
96
+ const program = (0, child_process_1.fork)(path, {
80
97
  env: {
81
98
  ...process.env,
82
99
  LOG_LEVEL: "debug",
@@ -84,11 +101,6 @@ function runDev(path) {
84
101
  SSL_CERT_PATH: "insecure-tls.crt",
85
102
  },
86
103
  });
87
- program.stdout.on("data", data => console.log(data.toString()));
88
- program.stderr.on("data", data => console.error(data.toString()));
89
- program.on("close", code => {
90
- logger_1.default.info(`Process exited with code ${code}`);
91
- });
92
104
  return program;
93
105
  }
94
106
  catch (e) {
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  // SPDX-License-Identifier: Apache-2.0
3
4
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
@@ -70,7 +70,9 @@ function default_1(program) {
70
70
  }
71
71
  catch (e) {
72
72
  logger_1.default.debug(e);
73
- logger_1.default.error(e.message);
73
+ if (e instanceof Error) {
74
+ logger_1.default.error(e.message);
75
+ }
74
76
  process.exit(1);
75
77
  }
76
78
  }
@@ -22,7 +22,8 @@ function genPkgJSON(opts, pgkVerOverride) {
22
22
  // Generate a name for the module based on the module name
23
23
  const name = (0, utils_1.sanitizeName)(opts.name);
24
24
  // Make typescript a dev dependency
25
- const { typescript, "ts-node": tsNode } = package_json_1.dependencies;
25
+ const { typescript } = package_json_1.peerDependencies;
26
+ const { prettier } = package_json_1.devDependencies;
26
27
  const data = {
27
28
  name,
28
29
  version: "0.0.1",
@@ -47,8 +48,8 @@ function genPkgJSON(opts, pgkVerOverride) {
47
48
  pepr: pgkVerOverride || `${package_json_1.version}`,
48
49
  },
49
50
  devDependencies: {
51
+ prettier,
50
52
  typescript,
51
- "ts-node": tsNode,
52
53
  },
53
54
  };
54
55
  return {
@@ -31,7 +31,7 @@ async function createDir(dir) {
31
31
  }
32
32
  catch (err) {
33
33
  // The directory already exists
34
- if (err.code === "EEXIST") {
34
+ if (err && err.code === "EEXIST") {
35
35
  throw new Error(`Directory ${dir} already exists`);
36
36
  }
37
37
  else {
@@ -35,7 +35,7 @@ function walkthrough() {
35
35
  const askErrorBehavior = {
36
36
  type: "select",
37
37
  name: "errorBehavior",
38
- validate: val => types_1.ErrorBehavior[val],
38
+ validate: (val) => types_1.ErrorBehavior[val],
39
39
  message: "How do you want Pepr to handle errors encountered during K8s operations?",
40
40
  choices: [
41
41
  {
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  // SPDX-License-Identifier: Apache-2.0
3
4
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
@@ -5,32 +6,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
6
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
7
  };
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
- const commander_1 = require("commander");
9
+ const child_process_1 = require("child_process");
9
10
  const crypto_1 = __importDefault(require("crypto"));
10
11
  const fs_1 = __importDefault(require("fs"));
11
12
  const zlib_1 = require("zlib");
12
13
  const package_json_1 = require("../../package.json");
13
14
  const logger_1 = __importDefault(require("../lib/logger"));
14
- commander_1.program
15
- .version(package_json_1.version)
16
- .description(`Pepr Kubernetes Runtime (v${package_json_1.version})`)
17
- .argument("<hash>", "Hash of the module to run")
18
- .option("-l, --log-level [level]", "Log level: debug, info, warn, error", "info")
19
- .action((expectedHash, opts) => {
20
- const gzPath = `/app/load/module-${expectedHash}.js.gz`;
21
- const jsPath = `/app/module-${expectedHash}.js`;
22
- // Require the has to be 64 characters long
23
- if (expectedHash.length !== 64) {
15
+ function validateHash(expectedHash) {
16
+ // Require the hash to be 64 characters long
17
+ if (!expectedHash || expectedHash.length !== 64) {
24
18
  logger_1.default.error("Invalid hash");
25
19
  process.exit(1);
26
20
  }
21
+ }
22
+ function runModule(expectedHash) {
23
+ const gzPath = `/app/load/module-${expectedHash}.js.gz`;
24
+ const jsPath = `/app/module-${expectedHash}.js`;
25
+ // Set the log level
26
+ logger_1.default.SetLogLevel("debug");
27
27
  // Check if the path is a valid file
28
28
  if (!fs_1.default.existsSync(gzPath)) {
29
29
  logger_1.default.error(`File not found: ${gzPath}`);
30
30
  process.exit(1);
31
31
  }
32
- // Set the log level
33
- logger_1.default.SetLogLevel(opts.logLevel);
34
32
  try {
35
33
  logger_1.default.info(`Loading module ${gzPath}`);
36
34
  // Extract the code from the file
@@ -47,12 +45,14 @@ commander_1.program
47
45
  // Write the code to a file
48
46
  fs_1.default.writeFileSync(jsPath, code);
49
47
  // Run the module
50
- // @todo: evaluate vm (isolate) vs require
51
- require(jsPath);
48
+ (0, child_process_1.fork)(jsPath);
52
49
  }
53
50
  catch (e) {
54
51
  logger_1.default.error(`Failed to decompress module: ${e}`);
55
52
  process.exit(1);
56
53
  }
57
- });
58
- commander_1.program.parse();
54
+ }
55
+ logger_1.default.info(`Pepr Controller (v${package_json_1.version})`);
56
+ const hash = process.argv[2];
57
+ validateHash(hash);
58
+ runModule(hash);
@@ -48,7 +48,9 @@ function default_1(program) {
48
48
  }
49
49
  catch (e) {
50
50
  logger_1.default.debug(e);
51
- logger_1.default.error(e.message);
51
+ if (e instanceof Error) {
52
+ logger_1.default.error(e.message);
53
+ }
52
54
  process.exit(1);
53
55
  }
54
56
  });
@@ -56,7 +56,7 @@ class Capability {
56
56
  labels: {},
57
57
  annotations: {},
58
58
  },
59
- callback: () => null,
59
+ callback: () => undefined,
60
60
  };
61
61
  const prefix = `${this._name}: ${model.name}`;
62
62
  logger_1.default.info(`Binding created`, prefix);
@@ -29,11 +29,19 @@ class Controller {
29
29
  throw new Error("Cannot start Pepr module: Pepr module was not instantiated with deferStart=true");
30
30
  }
31
31
  // Create HTTPS server
32
- https_1.default.createServer(options, this.app).listen(port, () => {
32
+ const server = https_1.default.createServer(options, this.app).listen(port, () => {
33
33
  console.log(`Server listening on port ${port}`);
34
34
  // Track that the server is running
35
35
  this.running = true;
36
36
  });
37
+ // Listen for the SIGTERM signal and gracefully close the server
38
+ process.on("SIGTERM", () => {
39
+ console.log("Received SIGTERM, closing server");
40
+ server.close(() => {
41
+ console.log("Server closed");
42
+ process.exit(0);
43
+ });
44
+ });
37
45
  };
38
46
  this.logger = (req, res, next) => {
39
47
  const startTime = Date.now();
@@ -1,13 +1,36 @@
1
1
  "use strict";
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
+ desc = { enumerable: true, get: function() { return m[k]; } };
9
+ }
10
+ Object.defineProperty(o, k2, desc);
11
+ }) : (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ o[k2] = m[k];
14
+ }));
15
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
17
+ }) : function(o, v) {
18
+ o["default"] = v;
19
+ });
20
+ var __importStar = (this && this.__importStar) || function (mod) {
21
+ if (mod && mod.__esModule) return mod;
22
+ var result = {};
23
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
24
+ __setModuleDefault(result, mod);
25
+ return result;
26
+ };
4
27
  var __importDefault = (this && this.__importDefault) || function (mod) {
5
28
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
29
  };
7
30
  Object.defineProperty(exports, "__esModule", { value: true });
8
31
  exports.fetch = exports.fetchRaw = void 0;
9
32
  const http_status_codes_1 = require("http-status-codes");
10
- const node_fetch_1 = __importDefault(require("node-fetch"));
33
+ const node_fetch_1 = __importStar(require("node-fetch"));
11
34
  exports.fetchRaw = node_fetch_1.default;
12
35
  const logger_1 = __importDefault(require("./logger"));
13
36
  /**
@@ -24,11 +47,11 @@ const logger_1 = __importDefault(require("./logger"));
24
47
  * @returns
25
48
  */
26
49
  async function fetch(url, init) {
50
+ let data = undefined;
27
51
  try {
28
52
  logger_1.default.debug(`Fetching ${url}`);
29
53
  const resp = await (0, node_fetch_1.default)(url, init);
30
54
  const contentType = resp.headers.get("content-type") || "";
31
- let data;
32
55
  if (resp.ok) {
33
56
  // Parse the response as JSON if the content type is JSON
34
57
  if (contentType.includes("application/json")) {
@@ -47,12 +70,22 @@ async function fetch(url, init) {
47
70
  };
48
71
  }
49
72
  catch (e) {
50
- logger_1.default.debug(`Fetch failed: ${e.message}`);
73
+ if (e instanceof node_fetch_1.FetchError) {
74
+ logger_1.default.debug(`Fetch failed: ${e instanceof Error ? e.message : e}`);
75
+ // Parse the error code from the FetchError or default to 400 (Bad Request)
76
+ const status = parseInt(e.code || "400");
77
+ return {
78
+ data,
79
+ ok: false,
80
+ status,
81
+ statusText: e.message,
82
+ };
83
+ }
51
84
  return {
52
- data: null,
85
+ data,
53
86
  ok: false,
54
- status: e.code || http_status_codes_1.StatusCodes.BAD_REQUEST,
55
- statusText: e.message,
87
+ status: http_status_codes_1.StatusCodes.BAD_REQUEST,
88
+ statusText: "Unknown error",
56
89
  };
57
90
  }
58
91
  }
@@ -106,7 +106,7 @@ class Webhook {
106
106
  const { name } = this;
107
107
  const ignore = [peprIgnore];
108
108
  // Add any namespaces to ignore
109
- if (this.config.alwaysIgnore.namespaces.length > 0) {
109
+ if (this.config.alwaysIgnore.namespaces && this.config.alwaysIgnore.namespaces.length > 0) {
110
110
  ignore.push({
111
111
  key: "kubernetes.io/metadata.name",
112
112
  operator: "NotIn",
@@ -193,7 +193,7 @@ class Webhook {
193
193
  name: "server",
194
194
  image: this.image,
195
195
  imagePullPolicy: "IfNotPresent",
196
- command: ["node", "/app/node_modules/pepr/dist/run.js", hash, "-l", "debug"],
196
+ command: ["node", "/app/node_modules/pepr/dist/src/cli/run.js", hash],
197
197
  livenessProbe: {
198
198
  httpGet: {
199
199
  path: "/healthz",
@@ -386,7 +386,7 @@ class Webhook {
386
386
  await coreV1Api.readNamespace(namespace);
387
387
  }
388
388
  catch (e) {
389
- logger_1.default.debug(e.body);
389
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
390
390
  logger_1.default.info("Creating namespace");
391
391
  await coreV1Api.createNamespace(ns);
392
392
  }
@@ -396,9 +396,9 @@ class Webhook {
396
396
  await admissionApi.createMutatingWebhookConfiguration(wh);
397
397
  }
398
398
  catch (e) {
399
- logger_1.default.debug(e.body);
399
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
400
400
  logger_1.default.info("Removing and re-creating mutating webhook");
401
- await admissionApi.deleteMutatingWebhookConfiguration(wh.metadata.name);
401
+ await admissionApi.deleteMutatingWebhookConfiguration(wh.metadata?.name ?? "");
402
402
  await admissionApi.createMutatingWebhookConfiguration(wh);
403
403
  }
404
404
  // If a host is specified, we don't need to deploy the rest of the resources
@@ -408,10 +408,10 @@ class Webhook {
408
408
  const netpol = this.networkPolicy();
409
409
  try {
410
410
  logger_1.default.info("Checking for network policy");
411
- await networkApi.readNamespacedNetworkPolicy(netpol.metadata.name, namespace);
411
+ await networkApi.readNamespacedNetworkPolicy(netpol.metadata?.name ?? "", namespace);
412
412
  }
413
413
  catch (e) {
414
- logger_1.default.debug(e.body);
414
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
415
415
  logger_1.default.info("Creating network policy");
416
416
  await networkApi.createNamespacedNetworkPolicy(namespace, netpol);
417
417
  }
@@ -421,9 +421,9 @@ class Webhook {
421
421
  await rbacApi.createClusterRoleBinding(crb);
422
422
  }
423
423
  catch (e) {
424
- logger_1.default.debug(e.body);
424
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
425
425
  logger_1.default.info("Removing and re-creating cluster role binding");
426
- await rbacApi.deleteClusterRoleBinding(crb.metadata.name);
426
+ await rbacApi.deleteClusterRoleBinding(crb.metadata?.name ?? "");
427
427
  await rbacApi.createClusterRoleBinding(crb);
428
428
  }
429
429
  const cr = this.clusterRole();
@@ -432,14 +432,14 @@ class Webhook {
432
432
  await rbacApi.createClusterRole(cr);
433
433
  }
434
434
  catch (e) {
435
- logger_1.default.debug(e.body);
435
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
436
436
  logger_1.default.info("Removing and re-creating the cluster role");
437
437
  try {
438
- await rbacApi.deleteClusterRole(cr.metadata.name);
438
+ await rbacApi.deleteClusterRole(cr.metadata?.name ?? "");
439
439
  await rbacApi.createClusterRole(cr);
440
440
  }
441
441
  catch (e) {
442
- logger_1.default.debug(e.body);
442
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
443
443
  }
444
444
  }
445
445
  const sa = this.serviceAccount();
@@ -448,9 +448,9 @@ class Webhook {
448
448
  await coreV1Api.createNamespacedServiceAccount(namespace, sa);
449
449
  }
450
450
  catch (e) {
451
- logger_1.default.debug(e.body);
451
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
452
452
  logger_1.default.info("Removing and re-creating service account");
453
- await coreV1Api.deleteNamespacedServiceAccount(sa.metadata.name, namespace);
453
+ await coreV1Api.deleteNamespacedServiceAccount(sa.metadata?.name ?? "", namespace);
454
454
  await coreV1Api.createNamespacedServiceAccount(namespace, sa);
455
455
  }
456
456
  const mod = this.moduleSecret(code, hash);
@@ -459,9 +459,9 @@ class Webhook {
459
459
  await coreV1Api.createNamespacedSecret(namespace, mod);
460
460
  }
461
461
  catch (e) {
462
- logger_1.default.debug(e.body);
462
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
463
463
  logger_1.default.info("Removing and re-creating module secret");
464
- await coreV1Api.deleteNamespacedSecret(mod.metadata.name, namespace);
464
+ await coreV1Api.deleteNamespacedSecret(mod.metadata?.name ?? "", namespace);
465
465
  await coreV1Api.createNamespacedSecret(namespace, mod);
466
466
  }
467
467
  const svc = this.service();
@@ -470,9 +470,9 @@ class Webhook {
470
470
  await coreV1Api.createNamespacedService(namespace, svc);
471
471
  }
472
472
  catch (e) {
473
- logger_1.default.debug(e.body);
473
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
474
474
  logger_1.default.info("Removing and re-creating service");
475
- await coreV1Api.deleteNamespacedService(svc.metadata.name, namespace);
475
+ await coreV1Api.deleteNamespacedService(svc.metadata?.name ?? "", namespace);
476
476
  await coreV1Api.createNamespacedService(namespace, svc);
477
477
  }
478
478
  const tls = this.tlsSecret();
@@ -481,9 +481,9 @@ class Webhook {
481
481
  await coreV1Api.createNamespacedSecret(namespace, tls);
482
482
  }
483
483
  catch (e) {
484
- logger_1.default.debug(e.body);
484
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
485
485
  logger_1.default.info("Removing and re-creating TLS secret");
486
- await coreV1Api.deleteNamespacedSecret(tls.metadata.name, namespace);
486
+ await coreV1Api.deleteNamespacedSecret(tls.metadata?.name ?? "", namespace);
487
487
  await coreV1Api.createNamespacedSecret(namespace, tls);
488
488
  }
489
489
  const dep = this.deployment(hash);
@@ -492,9 +492,9 @@ class Webhook {
492
492
  await appsApi.createNamespacedDeployment(namespace, dep);
493
493
  }
494
494
  catch (e) {
495
- logger_1.default.debug(e.body);
495
+ logger_1.default.debug(e instanceof client_node_1.HttpError ? e.body : e);
496
496
  logger_1.default.info("Removing and re-creating deployment");
497
- await appsApi.deleteNamespacedDeployment(dep.metadata.name, namespace);
497
+ await appsApi.deleteNamespacedDeployment(dep.metadata?.name ?? "", namespace);
498
498
  await appsApi.createNamespacedDeployment(namespace, dep);
499
499
  }
500
500
  }