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/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "!src/**/*.test.ts",
16
16
  "!dist/**/*.test.d.ts*"
17
17
  ],
18
- "version": "0.43.0",
18
+ "version": "0.44.0",
19
19
  "main": "dist/lib.js",
20
20
  "types": "dist/lib.d.ts",
21
21
  "scripts": {
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
- const isSecret = req.kind.version === "v1" && req.kind.kind === "Secret";
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
+ }