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.
- package/README.md +3 -46
- package/dist/package.json +21 -39
- package/dist/src/cli/build.js +3 -1
- package/dist/src/cli/dev.js +31 -19
- package/dist/src/cli/index.js +1 -0
- package/dist/src/cli/init/index.js +3 -1
- package/dist/src/cli/init/templates.js +3 -2
- package/dist/src/cli/init/utils.js +1 -1
- package/dist/src/cli/init/walkthrough.js +1 -1
- package/dist/src/cli/run.js +17 -17
- package/dist/src/cli/update.js +3 -1
- package/dist/src/lib/capability.js +1 -1
- package/dist/src/lib/controller.js +9 -1
- package/dist/src/lib/fetch.js +39 -6
- package/dist/src/lib/k8s/webhook.js +22 -22
- package/dist/src/lib/processor.js +4 -1
- package/{dist/index.d.ts → index.ts} +21 -3
- package/package.json +21 -39
- package/src/lib/capability.ts +158 -0
- package/src/lib/controller.ts +127 -0
- package/src/lib/fetch.ts +75 -0
- package/src/lib/filter.ts +87 -0
- package/{dist/src/lib/k8s/index.d.ts → src/lib/k8s/index.ts} +6 -0
- package/src/lib/k8s/kinds.ts +489 -0
- package/src/lib/k8s/tls.ts +90 -0
- package/src/lib/k8s/types.ts +183 -0
- package/src/lib/k8s/upstream.ts +49 -0
- package/src/lib/k8s/webhook.ts +547 -0
- package/src/lib/logger.ts +136 -0
- package/src/lib/module.ts +63 -0
- package/src/lib/processor.ts +98 -0
- package/src/lib/request.ts +140 -0
- package/src/lib/types.ts +211 -0
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -4
- package/dist/run.d.ts +0 -2
- package/dist/run.js +0 -4
- package/dist/src/cli/banner.d.ts +0 -1
- package/dist/src/cli/build.d.ts +0 -7
- package/dist/src/cli/capability.d.ts +0 -2
- package/dist/src/cli/deploy.d.ts +0 -2
- package/dist/src/cli/dev.d.ts +0 -2
- package/dist/src/cli/index.d.ts +0 -1
- package/dist/src/cli/init/index.d.ts +0 -2
- package/dist/src/cli/init/templates.d.ts +0 -94
- package/dist/src/cli/init/utils.d.ts +0 -20
- package/dist/src/cli/init/walkthrough.d.ts +0 -7
- package/dist/src/cli/root.d.ts +0 -4
- package/dist/src/cli/run.d.ts +0 -1
- package/dist/src/cli/test.d.ts +0 -2
- package/dist/src/cli/update.d.ts +0 -2
- package/dist/src/lib/capability.d.ts +0 -28
- package/dist/src/lib/controller.d.ts +0 -17
- package/dist/src/lib/fetch.d.ts +0 -23
- package/dist/src/lib/filter.d.ts +0 -10
- package/dist/src/lib/k8s/kinds.d.ts +0 -11
- package/dist/src/lib/k8s/tls.d.ts +0 -17
- package/dist/src/lib/k8s/types.d.ts +0 -147
- package/dist/src/lib/k8s/upstream.d.ts +0 -3
- package/dist/src/lib/k8s/webhook.d.ts +0 -34
- package/dist/src/lib/logger.d.ts +0 -55
- package/dist/src/lib/module.d.ts +0 -32
- package/dist/src/lib/processor.d.ts +0 -4
- package/dist/src/lib/request.d.ts +0 -77
- package/dist/src/lib/types.d.ts +0 -187
- package/docs/.prettierrc.json +0 -13
- package/docs/actions.md +0 -58
- package/docs/capabilities.md +0 -17
- package/docs/cli.md +0 -58
- package/docs/module.md +0 -90
- 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
|
|
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
|
|
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
|
+

|
|
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.
|
|
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
|
|
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
|
-
"
|
|
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.
|
|
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
|
}
|
package/dist/src/cli/build.js
CHANGED
|
@@ -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
|
-
|
|
114
|
+
if (e instanceof Error) {
|
|
115
|
+
logger_1.default.error(e.message);
|
|
116
|
+
}
|
|
115
117
|
process.exit(1);
|
|
116
118
|
}
|
|
117
119
|
}
|
package/dist/src/cli/dev.js
CHANGED
|
@@ -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 =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
//
|
|
62
|
-
if (
|
|
63
|
-
|
|
69
|
+
// If we're already building, skip this event
|
|
70
|
+
if (building) {
|
|
71
|
+
return;
|
|
64
72
|
}
|
|
65
|
-
//
|
|
66
|
-
|
|
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(
|
|
92
|
+
async function runDev() {
|
|
78
93
|
try {
|
|
79
|
-
const
|
|
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) {
|
package/dist/src/cli/index.js
CHANGED
|
@@ -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
|
|
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 {
|
|
@@ -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
|
{
|
package/dist/src/cli/run.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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);
|
package/dist/src/cli/update.js
CHANGED
|
@@ -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();
|
package/dist/src/lib/fetch.js
CHANGED
|
@@ -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 =
|
|
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
|
-
|
|
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
|
|
85
|
+
data,
|
|
53
86
|
ok: false,
|
|
54
|
-
status:
|
|
55
|
-
statusText:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
497
|
+
await appsApi.deleteNamespacedDeployment(dep.metadata?.name ?? "", namespace);
|
|
498
498
|
await appsApi.createNamespacedDeployment(namespace, dep);
|
|
499
499
|
}
|
|
500
500
|
}
|