pepr 0.8.0 → 0.10.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.
@@ -116,7 +116,7 @@ if (process.env.LOG_LEVEL) {
116
116
  var logger_default = Log;
117
117
 
118
118
  // src/cli/init/templates/data.json
119
- var packageJSON = { name: "pepr", description: "Kubernetes application engine", author: "Defense Unicorns", homepage: "https://github.com/defenseunicorns/pepr", license: "Apache-2.0", bin: "dist/cli.js", repository: "defenseunicorns/pepr", engines: { node: ">=18.0.0" }, version: "0.8.0", main: "dist/lib.js", types: "dist/lib.d.ts", scripts: { prebuild: "rm -fr dist/* && node hack/build-template-data.js", build: "tsc && node build.mjs", test: "npm run test:unit && npm run test:e2e", "test:unit": "npm run build && tsc -p tsconfig.tests.json && ava dist/**/*.test.js", "test:e2e": "npm run test:e2e:k3d && npm run test:e2e:build && npm run test:e2e:image && npm run test:e2e:run", "test:e2e:k3d": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'", "test:e2e:build": "npm run build && npm pack && npm uninstall pepr -g && npm install -g pepr-0.0.0-development.tgz && pepr", "test:e2e:image": "docker buildx build --tag pepr:dev . && k3d image import pepr:dev -c pepr-dev", "test:e2e:run": "ava hack/e2e.test.mjs --sequential --timeout=2m", "format:check": "eslint src && prettier src --check", "format:fix": "eslint src --fix && prettier src --write" }, dependencies: { "@kubernetes/client-node": "0.18.1", express: "4.18.2", "fast-json-patch": "3.1.1", "http-status-codes": "2.2.0", "node-fetch": "2.6.11", ramda: "0.29.0" }, devDependencies: { "@types/eslint": "8.40.2", "@types/express": "4.17.17", "@types/node-fetch": "2.6.4", "@types/node-forge": "1.3.2", "@types/prettier": "2.7.3", "@types/prompts": "2.4.4", "@types/ramda": "0.29.2", "@types/uuid": "9.0.2", ava: "5.3.0", nock: "13.3.1" }, peerDependencies: { "@typescript-eslint/eslint-plugin": "5.59.7", "@typescript-eslint/parser": "5.59.7", commander: "10.0.1", esbuild: "0.17.19", eslint: "8.41.0", "node-forge": "1.3.1", prettier: "2.8.8", prompts: "2.4.2", typescript: "5.0.4", uuid: "9.0.0" }, ava: { failFast: true, verbose: true } };
119
+ var packageJSON = { name: "pepr", description: "Kubernetes application engine", author: "Defense Unicorns", homepage: "https://github.com/defenseunicorns/pepr", license: "Apache-2.0", bin: "dist/cli.js", repository: "defenseunicorns/pepr", engines: { node: ">=18.0.0" }, version: "0.10.0", main: "dist/lib.js", types: "dist/lib.d.ts", scripts: { prebuild: "rm -fr dist/* && node hack/build-template-data.js", build: "tsc && node build.mjs", test: "npm run test:unit && npm run test:e2e", "test:unit": "npm run build && tsc -p tsconfig.tests.json && ava dist/**/*.test.js", "test:e2e": "npm run test:e2e:k3d && npm run test:e2e:build && npm run test:e2e:image && npm run test:e2e:run", "test:e2e:k3d": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'", "test:e2e:build": "npm run build && npm pack", "test:e2e:image": "docker buildx build --tag pepr:dev . && k3d image import pepr:dev -c pepr-dev", "test:e2e:run": "ava hack/e2e.test.mjs --sequential --timeout=2m", "format:check": "eslint src && prettier src --check", "format:fix": "eslint src --fix && prettier src --write" }, dependencies: { "@kubernetes/client-node": "0.18.1", express: "4.18.2", "fast-json-patch": "3.1.1", "http-status-codes": "2.2.0", "node-fetch": "2.6.12", "prom-client": "^14.2.0", ramda: "0.29.0" }, devDependencies: { "@types/eslint": "8.40.2", "@types/express": "4.17.17", "@types/node-fetch": "2.6.4", "@types/node-forge": "1.3.2", "@types/prettier": "2.7.3", "@types/prompts": "2.4.4", "@types/ramda": "0.29.3", "@types/uuid": "9.0.2", ava: "5.3.1", nock: "13.3.1" }, peerDependencies: { "@typescript-eslint/eslint-plugin": "5.59.7", "@typescript-eslint/parser": "5.59.7", commander: "10.0.1", esbuild: "0.17.19", eslint: "8.41.0", "node-forge": "1.3.1", prettier: "2.8.8", prompts: "2.4.2", typescript: "5.0.4", uuid: "9.0.0" }, ava: { failFast: true, verbose: true } };
120
120
 
121
121
  // src/runtime/controller.ts
122
122
  var { version } = packageJSON;
@@ -8,12 +8,14 @@ export declare class Controller {
8
8
  private readonly afterHook?;
9
9
  private readonly app;
10
10
  private running;
11
+ private metricsCollector;
11
12
  private token;
12
13
  constructor(config: ModuleConfig, capabilities: Capability[], beforeHook?: ((req: Request) => void) | undefined, afterHook?: ((res: Response) => void) | undefined);
13
14
  /** Start the webhook server */
14
15
  startServer: (port: number) => void;
15
16
  private logger;
16
17
  private healthz;
18
+ private metrics;
17
19
  private mutate;
18
20
  }
19
21
  //# sourceMappingURL=controller.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/lib/controller.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,qBAAa,UAAU;IAQnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAV7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,OAAO,CAAS;IAGxB,OAAO,CAAC,KAAK,CAAM;gBAGA,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,UAAU,EAAE,EAC1B,UAAU,CAAC,SAAQ,OAAO,KAAK,IAAI,aAAA,EACnC,SAAS,CAAC,SAAQ,QAAQ,KAAK,IAAI,aAAA;IAuBtD,+BAA+B;IACxB,WAAW,SAAU,MAAM,UAkDhC;IAEF,OAAO,CAAC,MAAM,CAYZ;IAEF,OAAO,CAAC,OAAO,CAOb;IAEF,OAAO,CAAC,MAAM,CA0CZ;CACH"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/lib/controller.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,qBAAa,UAAU;IASnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAX7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,gBAAgB,CAAgC;IAGxD,OAAO,CAAC,KAAK,CAAM;gBAGA,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,UAAU,EAAE,EAC1B,UAAU,CAAC,SAAQ,OAAO,KAAK,IAAI,aAAA,EACnC,SAAS,CAAC,SAAQ,QAAQ,KAAK,IAAI,aAAA;IA0BtD,+BAA+B;IACxB,WAAW,SAAU,MAAM,UAkDhC;IAEF,OAAO,CAAC,MAAM,CAYZ;IAEF,OAAO,CAAC,OAAO,CAOb;IAEF,OAAO,CAAC,OAAO,CAOb;IAEF,OAAO,CAAC,MAAM,CA+CZ;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../../src/lib/k8s/webhook.ts"],"names":[],"mappings":";AAGA,OAAO,EAQL,aAAa,EACb,oBAAoB,EACpB,YAAY,EAEZ,8BAA8B,EAC9B,WAAW,EACX,oBAAoB,EACpB,QAAQ,EACR,SAAS,EACT,gBAAgB,EAEjB,MAAM,yBAAyB,CAAC;AAQjC,OAAO,EAA6B,YAAY,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,MAAM,EAAU,MAAM,OAAO,CAAC;AAQvC,qBAAa,OAAO;IAeN,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAgB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IAdzE,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,SAAS,CAAS;IAEnB,KAAK,EAAE,MAAM,CAAC;IAErB,IAAW,GAAG,IAAI,MAAM,CAEvB;IAED,IAAW,QAAQ,IAAI,MAAM,CAE5B;gBAE4B,MAAM,EAAE,YAAY,EAAmB,IAAI,CAAC,oBAAQ;IAYjF,yCAAyC;IACzC,SAAS,IAAI,WAAW;IAQxB;;;;;OAKG;IACH,WAAW,IAAI,aAAa;IAgB5B,kBAAkB,IAAI,oBAAoB;IAqB1C,cAAc,IAAI,gBAAgB;IAWlC,cAAc,IAAI,QAAQ;IAe1B,SAAS,IAAI,QAAQ;IAgBrB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAwF7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,SAAK,GAAG,OAAO,CAAC,8BAA8B,CAAC;IA4DjG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAoGtC,OAAO,IAAI,SAAS;IAsBpB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ;IAkBlD,QAAQ,CAAC,IAAI,EAAE,MAAM;IA2Bf,OAAO,CAAC,IAAI,EAAE,MAAM;IAyBpB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM;CA6InD"}
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../../src/lib/k8s/webhook.ts"],"names":[],"mappings":";AAGA,OAAO,EAQL,aAAa,EACb,oBAAoB,EACpB,YAAY,EAEZ,8BAA8B,EAC9B,WAAW,EACX,oBAAoB,EACpB,QAAQ,EACR,SAAS,EACT,gBAAgB,EAEjB,MAAM,yBAAyB,CAAC;AAQjC,OAAO,EAA6B,YAAY,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,MAAM,EAAU,MAAM,OAAO,CAAC;AAQvC,qBAAa,OAAO;IAeN,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAgB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IAdzE,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,SAAS,CAAS;IAEnB,KAAK,EAAE,MAAM,CAAC;IAErB,IAAW,GAAG,IAAI,MAAM,CAEvB;IAED,IAAW,QAAQ,IAAI,MAAM,CAE5B;gBAE4B,MAAM,EAAE,YAAY,EAAmB,IAAI,CAAC,oBAAQ;IAYjF,yCAAyC;IACzC,SAAS,IAAI,WAAW;IAQxB;;;;;OAKG;IACH,WAAW,IAAI,aAAa;IAgB5B,kBAAkB,IAAI,oBAAoB;IAqB1C,cAAc,IAAI,gBAAgB;IAWlC,cAAc,IAAI,QAAQ;IAe1B,SAAS,IAAI,QAAQ;IAgBrB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAwF7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,SAAK,GAAG,OAAO,CAAC,8BAA8B,CAAC;IA4DjG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAoGtC,OAAO,IAAI,SAAS;IAsBpB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ;IAkBlD,QAAQ,CAAC,IAAI,EAAE,MAAM;IA4Bf,OAAO,CAAC,IAAI,EAAE,MAAM;IAyBpB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM;CA6InD"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * MetricsCollector class handles metrics collection using prom-client and performance hooks.
3
+ */
4
+ export declare class MetricsCollector {
5
+ private _registry;
6
+ private _errors;
7
+ private _alerts;
8
+ private _summary;
9
+ /**
10
+ * Creates a MetricsCollector instance with prefixed metrics.
11
+ * @param {string} [prefix='pepr'] - The prefix for the metric names.
12
+ */
13
+ constructor(prefix?: string);
14
+ /**
15
+ * Increments the error counter.
16
+ */
17
+ error(): void;
18
+ /**
19
+ * Increments the alerts counter.
20
+ */
21
+ alert(): void;
22
+ /**
23
+ * Returns the current timestamp from performance.now() method. Useful for start timing an operation.
24
+ * @returns {number} The timestamp.
25
+ */
26
+ observeStart(): number;
27
+ /**
28
+ * Observes the duration since the provided start time and updates the summary.
29
+ * @param {number} startTime - The start time.
30
+ */
31
+ observeEnd(startTime: number): void;
32
+ /**
33
+ * Fetches the current metrics from the registry.
34
+ * @returns {Promise<string>} The metrics.
35
+ */
36
+ getMetrics(): Promise<string>;
37
+ }
38
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/lib/metrics.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,QAAQ,CAA6B;IAE7C;;;OAGG;gBACS,MAAM,SAAS;IAsB3B;;OAEG;IACH,KAAK;IAIL;;OAEG;IACH,KAAK;IAIL;;;OAGG;IACH,YAAY;IAIZ;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM;IAI5B;;;OAGG;IACG,UAAU;CAGjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../src/lib/processor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIhD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,wBAAsB,SAAS,CAC7B,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,UAAU,EAAE,EAC1B,GAAG,EAAE,OAAO,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,QAAQ,CAAC,CAiHnB"}
1
+ {"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../src/lib/processor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIhD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,wBAAsB,SAAS,CAC7B,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,UAAU,EAAE,EAC1B,GAAG,EAAE,OAAO,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,QAAQ,CAAC,CAsHnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/lib/request.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC;;;GAGG;AACH,qBAAa,WAAW,CAAC,CAAC,SAAS,gBAAgB;IAmCrC,OAAO,CAAC,MAAM;IAlCnB,GAAG,EAAE,CAAC,CAAC;IAEd,IAAI,iBAAiB,YAEpB;IAED;;;OAGG;IACH,IAAI,QAAQ,wBAEX;IAED;;;OAGG;IACH,IAAI,WAAW,kBAEd;IAED;;;OAGG;IACH,IAAI,OAAO,eAEV;IAED;;;OAGG;gBACiB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAKtC;;;;OAIG;IACH,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IAIzB;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAUnC;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAUxC;;;;OAIG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM;IAOvB;;;;OAIG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM;IAO5B;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM;IAIpB;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM;CAG1B"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/lib/request.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAa,OAAO,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC;;;GAGG;AACH,qBAAa,WAAW,CAAC,CAAC,SAAS,gBAAgB;IAmCrC,OAAO,CAAC,MAAM;IAlCnB,GAAG,EAAE,CAAC,CAAC;IAEd,IAAI,iBAAiB,YAEpB;IAED;;;OAGG;IACH,IAAI,QAAQ,wBAEX;IAED;;;OAGG;IACH,IAAI,WAAW,kBAEd;IAED;;;OAGG;IACH,IAAI,OAAO,eAEV;IAED;;;OAGG;gBACiB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IActC;;;;OAIG;IACH,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IAIzB;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAUnC;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAUxC;;;;OAIG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM;IAQvB;;;;OAIG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM;IAQ5B;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM;IAIpB;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM;CAG1B"}
package/dist/lib.js CHANGED
@@ -848,7 +848,14 @@ var PeprRequest = class {
848
848
  */
849
849
  constructor(_input) {
850
850
  this._input = _input;
851
- this.Raw = (0, import_ramda.clone)(_input.object);
851
+ if (_input.operation === "DELETE" /* DELETE */) {
852
+ this.Raw = (0, import_ramda.clone)(_input.oldObject);
853
+ } else {
854
+ this.Raw = (0, import_ramda.clone)(_input.object);
855
+ }
856
+ if (!this.Raw) {
857
+ throw new Error("unable to load the request object into PeprRequest.RawP");
858
+ }
852
859
  }
853
860
  Raw;
854
861
  get PermitSideEffects() {
@@ -938,7 +945,7 @@ var PeprRequest = class {
938
945
  * @returns
939
946
  */
940
947
  HasLabel(key) {
941
- return this.Raw?.metadata?.labels?.[key] !== void 0;
948
+ return this.Raw.metadata?.labels?.[key] !== void 0;
942
949
  }
943
950
  /**
944
951
  * Check if an annotation exists on the Kubernetes resource.
@@ -947,7 +954,7 @@ var PeprRequest = class {
947
954
  * @returns
948
955
  */
949
956
  HasAnnotation(key) {
950
- return this.Raw?.metadata?.annotations?.[key] !== void 0;
957
+ return this.Raw.metadata?.annotations?.[key] !== void 0;
951
958
  }
952
959
  };
953
960
 
@@ -1046,6 +1053,9 @@ async function processor(config, capabilities, req, parentPrefix) {
1046
1053
  logger_default.info(`No matching capability action found`, parentPrefix);
1047
1054
  return response;
1048
1055
  }
1056
+ if (req.operation == "DELETE") {
1057
+ return response;
1058
+ }
1049
1059
  const transformed = wrapped.Raw;
1050
1060
  if (isSecret) {
1051
1061
  convertToBase64Map(transformed, skipDecode);
@@ -1062,6 +1072,71 @@ async function processor(config, capabilities, req, parentPrefix) {
1062
1072
  return response;
1063
1073
  }
1064
1074
 
1075
+ // src/lib/metrics.ts
1076
+ var import_prom_client = __toESM(require("prom-client"));
1077
+ var import_perf_hooks = require("perf_hooks");
1078
+ var MetricsCollector = class {
1079
+ _registry;
1080
+ _errors;
1081
+ _alerts;
1082
+ _summary;
1083
+ /**
1084
+ * Creates a MetricsCollector instance with prefixed metrics.
1085
+ * @param {string} [prefix='pepr'] - The prefix for the metric names.
1086
+ */
1087
+ constructor(prefix = "pepr") {
1088
+ this._registry = new import_prom_client.default.Registry();
1089
+ this._errors = new import_prom_client.default.Counter({
1090
+ name: `${prefix}_errors`,
1091
+ help: "error counter",
1092
+ registers: [this._registry]
1093
+ });
1094
+ this._alerts = new import_prom_client.default.Counter({
1095
+ name: `${prefix}_alerts`,
1096
+ help: "alerts counter",
1097
+ registers: [this._registry]
1098
+ });
1099
+ this._summary = new import_prom_client.default.Summary({
1100
+ name: `${prefix}_summary`,
1101
+ help: "summary",
1102
+ registers: [this._registry]
1103
+ });
1104
+ }
1105
+ /**
1106
+ * Increments the error counter.
1107
+ */
1108
+ error() {
1109
+ this._errors.inc();
1110
+ }
1111
+ /**
1112
+ * Increments the alerts counter.
1113
+ */
1114
+ alert() {
1115
+ this._alerts.inc();
1116
+ }
1117
+ /**
1118
+ * Returns the current timestamp from performance.now() method. Useful for start timing an operation.
1119
+ * @returns {number} The timestamp.
1120
+ */
1121
+ observeStart() {
1122
+ return import_perf_hooks.performance.now();
1123
+ }
1124
+ /**
1125
+ * Observes the duration since the provided start time and updates the summary.
1126
+ * @param {number} startTime - The start time.
1127
+ */
1128
+ observeEnd(startTime) {
1129
+ this._summary.observe(import_perf_hooks.performance.now() - startTime);
1130
+ }
1131
+ /**
1132
+ * Fetches the current metrics from the registry.
1133
+ * @returns {Promise<string>} The metrics.
1134
+ */
1135
+ async getMetrics() {
1136
+ return this._registry.metrics();
1137
+ }
1138
+ };
1139
+
1065
1140
  // src/lib/controller.ts
1066
1141
  var Controller = class {
1067
1142
  constructor(config, capabilities, beforeHook, afterHook) {
@@ -1072,6 +1147,7 @@ var Controller = class {
1072
1147
  this.app.use(this.logger);
1073
1148
  this.app.use(import_express.default.json({ limit: "2mb" }));
1074
1149
  this.app.get("/healthz", this.healthz);
1150
+ this.app.get("/metrics", this.metrics);
1075
1151
  this.app.post("/mutate/:token", this.mutate);
1076
1152
  if (beforeHook) {
1077
1153
  console.info(`Using beforeHook: ${beforeHook}`);
@@ -1082,6 +1158,7 @@ var Controller = class {
1082
1158
  }
1083
1159
  app = (0, import_express.default)();
1084
1160
  running = false;
1161
+ metricsCollector = new MetricsCollector("pepr");
1085
1162
  // The token used to authenticate requests
1086
1163
  token = "";
1087
1164
  /** Start the webhook server */
@@ -1141,13 +1218,23 @@ var Controller = class {
1141
1218
  res.status(500).send("Internal Server Error");
1142
1219
  }
1143
1220
  };
1221
+ metrics = async (req, res) => {
1222
+ try {
1223
+ res.send(await this.metricsCollector.getMetrics());
1224
+ } catch (err) {
1225
+ console.error(err);
1226
+ res.status(500).send("Internal Server Error");
1227
+ }
1228
+ };
1144
1229
  mutate = async (req, res) => {
1230
+ const startTime = this.metricsCollector.observeStart();
1145
1231
  try {
1146
1232
  const { token } = req.params;
1147
1233
  if (token !== this.token) {
1148
1234
  const err = `Unauthorized: invalid token '${token.replace(/[^\w]/g, "_")}'`;
1149
1235
  console.warn(err);
1150
1236
  res.status(401).send(err);
1237
+ this.metricsCollector.alert();
1151
1238
  return;
1152
1239
  }
1153
1240
  const request = req.body?.request || {};
@@ -1165,9 +1252,11 @@ var Controller = class {
1165
1252
  kind: "AdmissionReview",
1166
1253
  response
1167
1254
  });
1255
+ this.metricsCollector.observeEnd(startTime);
1168
1256
  } catch (err) {
1169
1257
  console.error(err);
1170
1258
  res.status(500).send("Internal Server Error");
1259
+ this.metricsCollector.error();
1171
1260
  }
1172
1261
  };
1173
1262
  };