pepr 0.28.3 → 0.28.5
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/SECURITY.md +18 -0
- package/dist/cli.js +72 -102
- package/dist/controller.js +1 -1
- package/dist/lib/filter.d.ts.map +1 -1
- package/dist/lib/queue.d.ts.map +1 -1
- package/dist/lib/watch-processor.d.ts.map +1 -1
- package/dist/lib.js +24 -25
- package/dist/lib.js.map +3 -3
- package/package.json +6 -6
- package/src/lib/assets/pods.ts +7 -11
- package/src/lib/assets/yaml.ts +2 -2
- package/src/lib/controller/index.ts +1 -1
- package/src/lib/filter.ts +6 -5
- package/src/lib/queue.ts +12 -3
- package/src/lib/watch-processor.ts +0 -14
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"engines": {
|
|
10
10
|
"node": ">=18.0.0"
|
|
11
11
|
},
|
|
12
|
-
"version": "0.28.
|
|
12
|
+
"version": "0.28.5",
|
|
13
13
|
"main": "dist/lib.js",
|
|
14
14
|
"types": "dist/lib.d.ts",
|
|
15
15
|
"scripts": {
|
|
@@ -32,19 +32,19 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@types/ramda": "0.29.11",
|
|
35
|
-
"express": "4.
|
|
35
|
+
"express": "4.19.1",
|
|
36
36
|
"fast-json-patch": "3.1.1",
|
|
37
|
-
"kubernetes-fluent-client": "2.
|
|
37
|
+
"kubernetes-fluent-client": "2.3.0",
|
|
38
38
|
"pino": "8.19.0",
|
|
39
|
-
"pino-pretty": "
|
|
39
|
+
"pino-pretty": "11.0.0",
|
|
40
40
|
"prom-client": "15.1.0",
|
|
41
41
|
"ramda": "0.29.1"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@commitlint/cli": "19.1
|
|
44
|
+
"@commitlint/cli": "19.2.1",
|
|
45
45
|
"@commitlint/config-conventional": "19.1.0",
|
|
46
46
|
"@jest/globals": "29.7.0",
|
|
47
|
-
"@types/eslint": "8.56.
|
|
47
|
+
"@types/eslint": "8.56.6",
|
|
48
48
|
"@types/express": "4.17.21",
|
|
49
49
|
"@types/node": "18.x.x",
|
|
50
50
|
"@types/node-forge": "1.3.11",
|
package/src/lib/assets/pods.ts
CHANGED
|
@@ -341,17 +341,13 @@ export function moduleSecret(name: string, data: Buffer, hash: string): kind.Sec
|
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
function genEnv(config: ModuleConfig, watchMode = false): V1EnvVar[] {
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
for (const [name, value] of Object.entries(config.env)) {
|
|
352
|
-
env.push({ name, value });
|
|
353
|
-
}
|
|
354
|
-
}
|
|
344
|
+
const def = {
|
|
345
|
+
PEPR_WATCH_MODE: watchMode ? "true" : "false",
|
|
346
|
+
PEPR_PRETTY_LOG: "false",
|
|
347
|
+
LOG_LEVEL: config.logLevel || "info",
|
|
348
|
+
};
|
|
349
|
+
const cfg = config.env || {};
|
|
350
|
+
const env = Object.entries({ ...def, ...cfg }).map(([name, value]) => ({ name, value }));
|
|
355
351
|
|
|
356
352
|
return env;
|
|
357
353
|
}
|
package/src/lib/assets/yaml.ts
CHANGED
|
@@ -32,7 +32,7 @@ export async function overridesFile({ hash, name, image, config, apiToken }: Ass
|
|
|
32
32
|
env: [
|
|
33
33
|
{ name: "PEPR_WATCH_MODE", value: "false" },
|
|
34
34
|
{ name: "PEPR_PRETTY_LOG", value: "false" },
|
|
35
|
-
{ name: "LOG_LEVEL", value: "
|
|
35
|
+
{ name: "LOG_LEVEL", value: "info" },
|
|
36
36
|
],
|
|
37
37
|
image,
|
|
38
38
|
annotations: {
|
|
@@ -77,7 +77,7 @@ export async function overridesFile({ hash, name, image, config, apiToken }: Ass
|
|
|
77
77
|
env: [
|
|
78
78
|
{ name: "PEPR_WATCH_MODE", value: "true" },
|
|
79
79
|
{ name: "PEPR_PRETTY_LOG", value: "false" },
|
|
80
|
-
{ name: "LOG_LEVEL", value: "
|
|
80
|
+
{ name: "LOG_LEVEL", value: "info" },
|
|
81
81
|
],
|
|
82
82
|
image,
|
|
83
83
|
annotations: {
|
|
@@ -235,7 +235,7 @@ export class Controller {
|
|
|
235
235
|
responseList.map(res => {
|
|
236
236
|
this.#afterHook && this.#afterHook(res);
|
|
237
237
|
// Log the response
|
|
238
|
-
Log.
|
|
238
|
+
Log.info({ ...reqMetadata, res }, "Check response");
|
|
239
239
|
});
|
|
240
240
|
|
|
241
241
|
let kubeAdmissionResponse: ValidateResponse[] | MutateResponse | ResponseItem;
|
package/src/lib/filter.ts
CHANGED
|
@@ -16,6 +16,7 @@ export function shouldSkipRequest(binding: Binding, req: AdmissionRequest, capab
|
|
|
16
16
|
const { group, kind, version } = binding.kind || {};
|
|
17
17
|
const { namespaces, labels, annotations, name } = binding.filters || {};
|
|
18
18
|
const operation = req.operation.toUpperCase();
|
|
19
|
+
const uid = req.uid;
|
|
19
20
|
// Use the old object if the request is a DELETE operation
|
|
20
21
|
const srcObject = operation === Operation.DELETE ? req.oldObject : req.object;
|
|
21
22
|
const { metadata } = srcObject || {};
|
|
@@ -65,7 +66,7 @@ export function shouldSkipRequest(binding: Binding, req: AdmissionRequest, capab
|
|
|
65
66
|
label = binding.watchCallback!.name;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
logger.debug(`${type} binding (${label}) does not match request namespace "${req.namespace}"`);
|
|
69
|
+
logger.debug({ uid }, `${type} binding (${label}) does not match request namespace "${req.namespace}"`);
|
|
69
70
|
|
|
70
71
|
return true;
|
|
71
72
|
}
|
|
@@ -76,13 +77,13 @@ export function shouldSkipRequest(binding: Binding, req: AdmissionRequest, capab
|
|
|
76
77
|
|
|
77
78
|
// First check if the label exists
|
|
78
79
|
if (!testKey) {
|
|
79
|
-
logger.debug(`Label ${key} does not exist`);
|
|
80
|
+
logger.debug({ uid }, `Label ${key} does not exist`);
|
|
80
81
|
return true;
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
// Then check if the value matches, if specified
|
|
84
85
|
if (value && testKey !== value) {
|
|
85
|
-
logger.debug(`${testKey} does not match ${value}`);
|
|
86
|
+
logger.debug({ uid }, `${testKey} does not match ${value}`);
|
|
86
87
|
return true;
|
|
87
88
|
}
|
|
88
89
|
}
|
|
@@ -93,13 +94,13 @@ export function shouldSkipRequest(binding: Binding, req: AdmissionRequest, capab
|
|
|
93
94
|
|
|
94
95
|
// First check if the annotation exists
|
|
95
96
|
if (!testKey) {
|
|
96
|
-
logger.debug(`Annotation ${key} does not exist`);
|
|
97
|
+
logger.debug({ uid }, `Annotation ${key} does not exist`);
|
|
97
98
|
return true;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
// Then check if the value matches, if specified
|
|
101
102
|
if (value && testKey !== value) {
|
|
102
|
-
logger.debug(`${testKey} does not match ${value}`);
|
|
103
|
+
logger.debug({ uid }, `${testKey} does not match ${value}`);
|
|
103
104
|
return true;
|
|
104
105
|
}
|
|
105
106
|
}
|
package/src/lib/queue.ts
CHANGED
|
@@ -46,28 +46,37 @@ export class Queue<K extends KubernetesObject> {
|
|
|
46
46
|
*/
|
|
47
47
|
async #dequeue() {
|
|
48
48
|
// If there is a pending promise, do nothing
|
|
49
|
-
if (this.#pendingPromise)
|
|
49
|
+
if (this.#pendingPromise) {
|
|
50
|
+
Log.debug("Pending promise, not dequeuing");
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
50
53
|
|
|
51
54
|
// Take the next element from the queue
|
|
52
55
|
const element = this.#queue.shift();
|
|
53
56
|
|
|
54
57
|
// If there is no element, do nothing
|
|
55
|
-
if (!element)
|
|
58
|
+
if (!element) {
|
|
59
|
+
Log.debug("No element, not dequeuing");
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
56
62
|
|
|
57
63
|
try {
|
|
58
64
|
// Set the pending promise flag to avoid concurrent reconciliations
|
|
59
65
|
this.#pendingPromise = true;
|
|
60
66
|
|
|
61
|
-
// Reconcile the
|
|
67
|
+
// Reconcile the element
|
|
62
68
|
if (this.#reconcile) {
|
|
69
|
+
Log.debug(`Reconciling ${element.item.metadata!.name}`);
|
|
63
70
|
await this.#reconcile(element.item);
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
element.resolve();
|
|
67
74
|
} catch (e) {
|
|
75
|
+
Log.debug(`Error reconciling ${element.item.metadata!.name}`, { error: e });
|
|
68
76
|
element.reject(e);
|
|
69
77
|
} finally {
|
|
70
78
|
// Reset the pending promise flag
|
|
79
|
+
Log.debug("Resetting pending promise and dequeuing");
|
|
71
80
|
this.#pendingPromise = false;
|
|
72
81
|
|
|
73
82
|
// After the element is reconciled, dequeue the next element
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
3
|
-
|
|
4
|
-
import { createHash } from "crypto";
|
|
5
3
|
import { K8s, WatchCfg, WatchEvent } from "kubernetes-fluent-client";
|
|
6
4
|
import { WatchPhase } from "kubernetes-fluent-client/dist/fluent/types";
|
|
7
5
|
import { Queue } from "./queue";
|
|
@@ -12,8 +10,6 @@ import { Watcher } from "kubernetes-fluent-client/dist/fluent/watch";
|
|
|
12
10
|
import { GenericClass } from "kubernetes-fluent-client";
|
|
13
11
|
import { filterMatcher } from "./helpers";
|
|
14
12
|
|
|
15
|
-
const store: Record<string, string> = {};
|
|
16
|
-
|
|
17
13
|
export function setupWatch(capabilities: Capability[]) {
|
|
18
14
|
capabilities.map(capability =>
|
|
19
15
|
capability.bindings
|
|
@@ -86,10 +82,6 @@ async function runBinding(binding: Binding, capabilityNamespaces: string[]) {
|
|
|
86
82
|
}, watchCfg);
|
|
87
83
|
}
|
|
88
84
|
|
|
89
|
-
// Create a unique cache ID for this watch binding in case multiple bindings are watching the same resource
|
|
90
|
-
const cacheSuffix = createHash("sha224").update(binding.watchCallback!.toString()).digest("hex").substring(0, 5);
|
|
91
|
-
const cacheID = [watcher.getCacheID(), cacheSuffix].join("-");
|
|
92
|
-
|
|
93
85
|
// If failure continues, log and exit
|
|
94
86
|
watcher.events.on(WatchEvent.GIVE_UP, err => {
|
|
95
87
|
Log.error(err, "Watch failed after 5 attempts, giving up");
|
|
@@ -98,12 +90,6 @@ async function runBinding(binding: Binding, capabilityNamespaces: string[]) {
|
|
|
98
90
|
|
|
99
91
|
// Start the watch
|
|
100
92
|
try {
|
|
101
|
-
const resourceVersion = store[cacheID];
|
|
102
|
-
if (resourceVersion) {
|
|
103
|
-
Log.debug(`Starting watch ${binding.model.name} from version ${resourceVersion}`);
|
|
104
|
-
watcher.resourceVersion = resourceVersion;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
93
|
await watcher.start();
|
|
108
94
|
} catch (err) {
|
|
109
95
|
Log.error(err, "Error starting watch");
|