pepr 0.43.0 → 0.44.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/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/controller.js +1 -1
- package/dist/lib/processors/mutate-processor.d.ts +2 -0
- package/dist/lib/processors/mutate-processor.d.ts.map +1 -1
- package/dist/lib/processors/validate-processor.d.ts.map +1 -1
- package/dist/lib/telemetry/timeUtils.d.ts +2 -0
- package/dist/lib/telemetry/timeUtils.d.ts.map +1 -0
- package/dist/lib/telemetry/webhookTimeouts.d.ts +9 -0
- package/dist/lib/telemetry/webhookTimeouts.d.ts.map +1 -0
- package/dist/lib.js +42 -4
- package/dist/lib.js.map +3 -3
- package/package.json +1 -1
- package/src/cli/dev.ts +2 -0
- package/src/lib/processors/mutate-processor.ts +13 -6
- package/src/lib/processors/validate-processor.ts +6 -3
- package/src/lib/telemetry/timeUtils.ts +1 -0
- package/src/lib/telemetry/webhookTimeouts.ts +34 -0
package/package.json
CHANGED
package/src/cli/dev.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { buildModule, loadModule } from "./build";
|
|
|
11
11
|
import { deployWebhook } from "../lib/assets/deploy";
|
|
12
12
|
import { promises as fs } from "fs";
|
|
13
13
|
import { validateCapabilityNames } from "../lib/helpers";
|
|
14
|
+
|
|
14
15
|
export default function (program: RootCmd): void {
|
|
15
16
|
program
|
|
16
17
|
.command("dev")
|
|
@@ -42,6 +43,7 @@ export default function (program: RootCmd): void {
|
|
|
42
43
|
description: cfg.description,
|
|
43
44
|
},
|
|
44
45
|
path,
|
|
46
|
+
[],
|
|
45
47
|
opts.host,
|
|
46
48
|
);
|
|
47
49
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import jsonPatch from "fast-json-patch";
|
|
5
5
|
import { kind, KubernetesObject } from "kubernetes-fluent-client";
|
|
6
6
|
import { clone } from "ramda";
|
|
7
|
-
|
|
7
|
+
import { MeasureWebhookTimeout } from "../telemetry/webhookTimeouts";
|
|
8
8
|
import { Capability } from "../core/capability";
|
|
9
9
|
import { shouldSkipRequest } from "../filter/filter";
|
|
10
10
|
import { MutateResponse } from "../k8s";
|
|
@@ -15,7 +15,8 @@ import { PeprMutateRequest } from "../mutate-request";
|
|
|
15
15
|
import { base64Encode, convertFromBase64Map, convertToBase64Map } from "../utils";
|
|
16
16
|
import { OnError } from "../../cli/init/enums";
|
|
17
17
|
import { resolveIgnoreNamespaces } from "../assets/webhooks";
|
|
18
|
-
|
|
18
|
+
import { Operation } from "fast-json-patch";
|
|
19
|
+
import { WebhookType } from "../enums";
|
|
19
20
|
export interface Bindable {
|
|
20
21
|
req: AdmissionRequest;
|
|
21
22
|
config: ModuleConfig;
|
|
@@ -139,6 +140,8 @@ export async function mutateProcessor(
|
|
|
139
140
|
req: AdmissionRequest,
|
|
140
141
|
reqMetadata: Record<string, string>,
|
|
141
142
|
): Promise<MutateResponse> {
|
|
143
|
+
const webhookTimer = new MeasureWebhookTimeout(WebhookType.MUTATE);
|
|
144
|
+
webhookTimer.start(config.webhookTimeout);
|
|
142
145
|
let response: MutateResponse = {
|
|
143
146
|
uid: req.uid,
|
|
144
147
|
warnings: [],
|
|
@@ -207,6 +210,14 @@ export async function mutateProcessor(
|
|
|
207
210
|
// Compare the original request to the modified request to get the patches
|
|
208
211
|
const patches = jsonPatch.compare(req.object, transformed);
|
|
209
212
|
|
|
213
|
+
updateResponsePatchAndWarnings(patches, response);
|
|
214
|
+
|
|
215
|
+
Log.debug({ ...reqMetadata, patches }, `Patches generated`);
|
|
216
|
+
webhookTimer.stop();
|
|
217
|
+
return response;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function updateResponsePatchAndWarnings(patches: Operation[], response: MutateResponse): void {
|
|
210
221
|
// Only add the patch if there are patches to apply
|
|
211
222
|
if (patches.length > 0) {
|
|
212
223
|
response.patchType = "JSONPatch";
|
|
@@ -219,8 +230,4 @@ export async function mutateProcessor(
|
|
|
219
230
|
if (response.warnings && response.warnings.length < 1) {
|
|
220
231
|
delete response.warnings;
|
|
221
232
|
}
|
|
222
|
-
|
|
223
|
-
Log.debug({ ...reqMetadata, patches }, `Patches generated`);
|
|
224
|
-
|
|
225
|
-
return response;
|
|
226
233
|
}
|
|
@@ -11,6 +11,8 @@ import { convertFromBase64Map } from "../utils";
|
|
|
11
11
|
import { PeprValidateRequest } from "../validate-request";
|
|
12
12
|
import { ModuleConfig } from "../core/module";
|
|
13
13
|
import { resolveIgnoreNamespaces } from "../assets/webhooks";
|
|
14
|
+
import { MeasureWebhookTimeout } from "../telemetry/webhookTimeouts";
|
|
15
|
+
import { WebhookType } from "../enums";
|
|
14
16
|
|
|
15
17
|
export async function processRequest(
|
|
16
18
|
binding: Binding,
|
|
@@ -58,12 +60,13 @@ export async function validateProcessor(
|
|
|
58
60
|
req: AdmissionRequest,
|
|
59
61
|
reqMetadata: Record<string, string>,
|
|
60
62
|
): Promise<ValidateResponse[]> {
|
|
63
|
+
const webhookTimer = new MeasureWebhookTimeout(WebhookType.VALIDATE);
|
|
64
|
+
webhookTimer.start(config.webhookTimeout);
|
|
61
65
|
const wrapped = new PeprValidateRequest(req);
|
|
62
66
|
const response: ValidateResponse[] = [];
|
|
63
67
|
|
|
64
68
|
// If the resource is a secret, decode the data
|
|
65
|
-
|
|
66
|
-
if (isSecret) {
|
|
69
|
+
if (req.kind.version === "v1" && req.kind.kind === "Secret") {
|
|
67
70
|
convertFromBase64Map(wrapped.Raw as unknown as kind.Secret);
|
|
68
71
|
}
|
|
69
72
|
|
|
@@ -94,6 +97,6 @@ export async function validateProcessor(
|
|
|
94
97
|
response.push(resp);
|
|
95
98
|
}
|
|
96
99
|
}
|
|
97
|
-
|
|
100
|
+
webhookTimer.stop();
|
|
98
101
|
return response;
|
|
99
102
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const getNow = (): number => performance.now();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { metricsCollector } from "./metrics";
|
|
2
|
+
import { getNow } from "./timeUtils";
|
|
3
|
+
import Log from "./logger";
|
|
4
|
+
import { WebhookType } from "../enums";
|
|
5
|
+
export class MeasureWebhookTimeout {
|
|
6
|
+
#startTime: number | null = null;
|
|
7
|
+
#webhookType: string;
|
|
8
|
+
timeout: number = 0;
|
|
9
|
+
|
|
10
|
+
constructor(webhookType: WebhookType) {
|
|
11
|
+
this.#webhookType = webhookType;
|
|
12
|
+
metricsCollector.addCounter(`${webhookType}_timeouts`, `Number of ${webhookType} webhook timeouts`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
start(timeout: number = 10): void {
|
|
16
|
+
this.#startTime = getNow();
|
|
17
|
+
this.timeout = timeout;
|
|
18
|
+
Log.info(`Starting timer at ${this.#startTime}`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
stop(): void {
|
|
22
|
+
if (this.#startTime === null) {
|
|
23
|
+
throw new Error("Timer was not started before calling stop.");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const elapsedTime = getNow() - this.#startTime;
|
|
27
|
+
Log.info(`Webhook ${this.#startTime} took ${elapsedTime}ms`);
|
|
28
|
+
this.#startTime = null;
|
|
29
|
+
|
|
30
|
+
if (elapsedTime > this.timeout) {
|
|
31
|
+
metricsCollector.incCounter(`${this.#webhookType}_timeouts`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|