pepr 0.40.1 → 0.42.1
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 +11 -5
- package/dist/cli/build.d.ts +1 -0
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.helpers.d.ts +66 -0
- package/dist/cli/build.helpers.d.ts.map +1 -1
- package/dist/cli/deploy.d.ts.map +1 -1
- package/dist/cli/init/templates.d.ts +2 -2
- package/dist/cli/monitor.d.ts +23 -0
- package/dist/cli/monitor.d.ts.map +1 -1
- package/dist/cli.js +536 -429
- package/dist/controller.js +52 -27
- package/dist/lib/assets/destroy.d.ts.map +1 -1
- package/dist/lib/assets/helm.d.ts +1 -1
- package/dist/lib/assets/helm.d.ts.map +1 -1
- package/dist/lib/assets/index.d.ts.map +1 -1
- package/dist/lib/assets/pods.d.ts +5 -19
- package/dist/lib/assets/pods.d.ts.map +1 -1
- package/dist/lib/assets/webhooks.d.ts.map +1 -1
- package/dist/lib/assets/yaml.d.ts.map +1 -1
- package/dist/lib/capability.d.ts.map +1 -1
- package/dist/lib/controller/index.d.ts.map +1 -1
- package/dist/lib/controller/index.util.d.ts +10 -0
- package/dist/lib/controller/index.util.d.ts.map +1 -0
- package/dist/lib/controller/store.d.ts +0 -1
- package/dist/lib/controller/store.d.ts.map +1 -1
- package/dist/lib/controller/storeCache.d.ts +1 -0
- package/dist/lib/controller/storeCache.d.ts.map +1 -1
- package/dist/lib/deploymentChecks.d.ts +3 -0
- package/dist/lib/deploymentChecks.d.ts.map +1 -0
- package/dist/lib/enums.d.ts +5 -5
- package/dist/lib/enums.d.ts.map +1 -1
- package/dist/lib/filesystemService.d.ts +2 -0
- package/dist/lib/filesystemService.d.ts.map +1 -0
- package/dist/lib/filter/adjudicators/adjudicators.d.ts +73 -0
- package/dist/lib/filter/adjudicators/adjudicators.d.ts.map +1 -0
- package/dist/lib/filter/adjudicators/defaultTestObjects.d.ts +7 -0
- package/dist/lib/filter/adjudicators/defaultTestObjects.d.ts.map +1 -0
- package/dist/lib/helpers.d.ts +1 -4
- package/dist/lib/helpers.d.ts.map +1 -1
- package/dist/lib/mutate-request.d.ts +2 -2
- package/dist/lib/mutate-request.d.ts.map +1 -1
- package/dist/lib/queue.d.ts.map +1 -1
- package/dist/lib/schedule.d.ts.map +1 -1
- package/dist/lib/storage.d.ts +5 -5
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/{logger.d.ts → telemetry/logger.d.ts} +1 -1
- package/dist/lib/telemetry/logger.d.ts.map +1 -0
- package/dist/lib/{metrics.d.ts → telemetry/metrics.d.ts} +3 -1
- package/dist/lib/telemetry/metrics.d.ts.map +1 -0
- package/dist/lib/types.d.ts +10 -9
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/validate-processor.d.ts +4 -1
- package/dist/lib/validate-processor.d.ts.map +1 -1
- package/dist/lib/watch-processor.d.ts.map +1 -1
- package/dist/lib.d.ts +1 -1
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +283 -231
- package/dist/lib.js.map +4 -4
- package/dist/sdk/sdk.d.ts +3 -4
- package/dist/sdk/sdk.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/cli/build.helpers.ts +180 -0
- package/src/cli/build.ts +85 -132
- package/src/cli/deploy.ts +2 -1
- package/src/cli/init/templates.ts +1 -1
- package/src/cli/monitor.ts +108 -65
- package/src/lib/assets/deploy.ts +7 -7
- package/src/lib/assets/destroy.ts +2 -2
- package/src/lib/assets/helm.ts +6 -6
- package/src/lib/assets/index.ts +110 -89
- package/src/lib/assets/pods.ts +10 -5
- package/src/lib/assets/webhooks.ts +3 -3
- package/src/lib/assets/yaml.ts +12 -9
- package/src/lib/capability.ts +29 -19
- package/src/lib/controller/index.ts +41 -69
- package/src/lib/controller/index.util.ts +47 -0
- package/src/lib/controller/store.ts +24 -11
- package/src/lib/controller/storeCache.ts +11 -2
- package/src/lib/deploymentChecks.ts +43 -0
- package/src/lib/enums.ts +5 -5
- package/src/lib/filesystemService.ts +16 -0
- package/src/lib/filter/{adjudicators.ts → adjudicators/adjudicators.ts} +67 -35
- package/src/lib/filter/adjudicators/defaultTestObjects.ts +46 -0
- package/src/lib/filter/filter.ts +1 -1
- package/src/lib/finalizer.ts +1 -1
- package/src/lib/helpers.ts +31 -88
- package/src/lib/mutate-processor.ts +1 -1
- package/src/lib/mutate-request.ts +11 -11
- package/src/lib/queue.ts +13 -5
- package/src/lib/schedule.ts +8 -8
- package/src/lib/storage.ts +48 -39
- package/src/lib/{logger.ts → telemetry/logger.ts} +1 -1
- package/src/lib/{metrics.ts → telemetry/metrics.ts} +18 -17
- package/src/lib/types.ts +12 -9
- package/src/lib/utils.ts +6 -6
- package/src/lib/validate-processor.ts +48 -40
- package/src/lib/watch-processor.ts +19 -15
- package/src/lib.ts +1 -1
- package/src/runtime/controller.ts +1 -1
- package/src/sdk/cosign.ts +4 -4
- package/src/sdk/sdk.ts +6 -9
- package/src/templates/capabilities/hello-pepr.ts +19 -9
- package/dist/lib/filter/adjudicators.d.ts +0 -69
- package/dist/lib/filter/adjudicators.d.ts.map +0 -1
- package/dist/lib/logger.d.ts.map +0 -1
- package/dist/lib/metrics.d.ts.map +0 -1
package/dist/lib.js
CHANGED
|
@@ -6,8 +6,8 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
8
|
var __export = (target, all) => {
|
|
9
|
-
for (var
|
|
10
|
-
__defProp(target,
|
|
9
|
+
for (var name2 in all)
|
|
10
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
11
11
|
};
|
|
12
12
|
var __copyProps = (to, from, except, desc) => {
|
|
13
13
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -31,29 +31,29 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var lib_exports = {};
|
|
32
32
|
__export(lib_exports, {
|
|
33
33
|
Capability: () => Capability,
|
|
34
|
-
K8s: () =>
|
|
34
|
+
K8s: () => import_kubernetes_fluent_client8.K8s,
|
|
35
35
|
Log: () => logger_default,
|
|
36
36
|
PeprModule: () => PeprModule,
|
|
37
37
|
PeprMutateRequest: () => PeprMutateRequest,
|
|
38
38
|
PeprUtils: () => utils_exports,
|
|
39
39
|
PeprValidateRequest: () => PeprValidateRequest,
|
|
40
40
|
R: () => R,
|
|
41
|
-
RegisterKind: () =>
|
|
42
|
-
a: () =>
|
|
43
|
-
fetch: () =>
|
|
44
|
-
fetchStatus: () =>
|
|
45
|
-
kind: () =>
|
|
41
|
+
RegisterKind: () => import_kubernetes_fluent_client8.RegisterKind,
|
|
42
|
+
a: () => import_kubernetes_fluent_client8.kind,
|
|
43
|
+
fetch: () => import_kubernetes_fluent_client8.fetch,
|
|
44
|
+
fetchStatus: () => import_kubernetes_fluent_client8.fetchStatus,
|
|
45
|
+
kind: () => import_kubernetes_fluent_client8.kind,
|
|
46
46
|
sdk: () => sdk_exports
|
|
47
47
|
});
|
|
48
48
|
module.exports = __toCommonJS(lib_exports);
|
|
49
|
-
var
|
|
49
|
+
var import_kubernetes_fluent_client8 = require("kubernetes-fluent-client");
|
|
50
50
|
var R = __toESM(require("ramda"));
|
|
51
51
|
|
|
52
52
|
// src/lib/capability.ts
|
|
53
|
-
var
|
|
53
|
+
var import_kubernetes_fluent_client7 = require("kubernetes-fluent-client");
|
|
54
54
|
var import_ramda7 = require("ramda");
|
|
55
55
|
|
|
56
|
-
// src/lib/logger.ts
|
|
56
|
+
// src/lib/telemetry/logger.ts
|
|
57
57
|
var import_pino = require("pino");
|
|
58
58
|
var isPrettyLog = process.env.PEPR_PRETTY_LOGS === "true";
|
|
59
59
|
var redactedValue = "**redacted**";
|
|
@@ -109,7 +109,7 @@ var import_express = __toESM(require("express"));
|
|
|
109
109
|
var import_fs = __toESM(require("fs"));
|
|
110
110
|
var import_https = __toESM(require("https"));
|
|
111
111
|
|
|
112
|
-
// src/lib/metrics.ts
|
|
112
|
+
// src/lib/telemetry/metrics.ts
|
|
113
113
|
var import_perf_hooks = require("perf_hooks");
|
|
114
114
|
var import_prom_client = __toESM(require("prom-client"));
|
|
115
115
|
var loggingPrefix = "MetricsCollector";
|
|
@@ -142,34 +142,34 @@ var MetricsCollector = class {
|
|
|
142
142
|
this.addGauge(this.#metricNames.cacheMiss, "Number of cache misses per window", ["window"]);
|
|
143
143
|
this.addGauge(this.#metricNames.resyncFailureCount, "Number of failures per resync operation", ["count"]);
|
|
144
144
|
}
|
|
145
|
-
#getMetricName = (
|
|
146
|
-
#addMetric = (collection, MetricType,
|
|
147
|
-
if (collection.has(this.#getMetricName(
|
|
148
|
-
logger_default.debug(`Metric for ${
|
|
145
|
+
#getMetricName = (name2) => `${this.#prefix}_${name2}`;
|
|
146
|
+
#addMetric = (collection, MetricType, name2, help, labelNames) => {
|
|
147
|
+
if (collection.has(this.#getMetricName(name2))) {
|
|
148
|
+
logger_default.debug(`Metric for ${name2} already exists`, loggingPrefix);
|
|
149
149
|
return;
|
|
150
150
|
}
|
|
151
151
|
const metric = new MetricType({
|
|
152
|
-
name: this.#getMetricName(
|
|
152
|
+
name: this.#getMetricName(name2),
|
|
153
153
|
help,
|
|
154
154
|
registers: [this.#registry],
|
|
155
155
|
labelNames
|
|
156
156
|
});
|
|
157
|
-
collection.set(this.#getMetricName(
|
|
157
|
+
collection.set(this.#getMetricName(name2), metric);
|
|
158
158
|
};
|
|
159
|
-
addCounter = (
|
|
160
|
-
this.#addMetric(this.#counters, import_prom_client.default.Counter,
|
|
159
|
+
addCounter = (name2, help) => {
|
|
160
|
+
this.#addMetric(this.#counters, import_prom_client.default.Counter, name2, help, []);
|
|
161
161
|
};
|
|
162
|
-
addSummary = (
|
|
163
|
-
this.#addMetric(this.#summaries, import_prom_client.default.Summary,
|
|
162
|
+
addSummary = (name2, help) => {
|
|
163
|
+
this.#addMetric(this.#summaries, import_prom_client.default.Summary, name2, help, []);
|
|
164
164
|
};
|
|
165
|
-
addGauge = (
|
|
166
|
-
this.#addMetric(this.#gauges, import_prom_client.default.Gauge,
|
|
165
|
+
addGauge = (name2, help, labelNames) => {
|
|
166
|
+
this.#addMetric(this.#gauges, import_prom_client.default.Gauge, name2, help, labelNames);
|
|
167
167
|
};
|
|
168
|
-
incCounter = (
|
|
169
|
-
this.#counters.get(this.#getMetricName(
|
|
168
|
+
incCounter = (name2) => {
|
|
169
|
+
this.#counters.get(this.#getMetricName(name2))?.inc();
|
|
170
170
|
};
|
|
171
|
-
incGauge = (
|
|
172
|
-
this.#gauges.get(this.#getMetricName(
|
|
171
|
+
incGauge = (name2, labels, value = 1) => {
|
|
172
|
+
this.#gauges.get(this.#getMetricName(name2))?.inc(labels || {}, value);
|
|
173
173
|
};
|
|
174
174
|
/**
|
|
175
175
|
* Increments the error counter.
|
|
@@ -184,8 +184,8 @@ var MetricsCollector = class {
|
|
|
184
184
|
* @param startTime - The start time.
|
|
185
185
|
* @param name - The metrics summary to increment.
|
|
186
186
|
*/
|
|
187
|
-
observeEnd = (startTime,
|
|
188
|
-
this.#summaries.get(this.#getMetricName(
|
|
187
|
+
observeEnd = (startTime, name2 = this.#metricNames.mutate) => {
|
|
188
|
+
this.#summaries.get(this.#getMetricName(name2))?.observe(import_perf_hooks.performance.now() - startTime);
|
|
189
189
|
};
|
|
190
190
|
/**
|
|
191
191
|
* Fetches the current metrics from the registry.
|
|
@@ -254,7 +254,7 @@ function ValidateError(error = "") {
|
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
// src/lib/filter/adjudicators.ts
|
|
257
|
+
// src/lib/filter/adjudicators/adjudicators.ts
|
|
258
258
|
var import_ramda = require("ramda");
|
|
259
259
|
var declaredOperation = (0, import_ramda.pipe)(
|
|
260
260
|
(request) => request?.operation,
|
|
@@ -278,23 +278,49 @@ var carriesDeletionTimestamp = (0, import_ramda.pipe)(
|
|
|
278
278
|
(0, import_ramda.defaultTo)(false)
|
|
279
279
|
);
|
|
280
280
|
var missingDeletionTimestamp = (0, import_ramda.complement)(carriesDeletionTimestamp);
|
|
281
|
-
var carriedKind = (0, import_ramda.pipe)(
|
|
282
|
-
|
|
283
|
-
|
|
281
|
+
var carriedKind = (0, import_ramda.pipe)(
|
|
282
|
+
(kubernetesObject) => kubernetesObject?.kind,
|
|
283
|
+
(0, import_ramda.defaultTo)("not set")
|
|
284
|
+
);
|
|
285
|
+
var carriedVersion = (0, import_ramda.pipe)(
|
|
286
|
+
(kubernetesObject) => kubernetesObject?.metadata?.resourceVersion,
|
|
287
|
+
(0, import_ramda.defaultTo)("not set")
|
|
288
|
+
);
|
|
289
|
+
var carriedName = (0, import_ramda.pipe)(
|
|
290
|
+
(kubernetesObject) => kubernetesObject?.metadata?.name,
|
|
291
|
+
(0, import_ramda.defaultTo)("")
|
|
292
|
+
);
|
|
284
293
|
var carriesName = (0, import_ramda.pipe)(carriedName, (0, import_ramda.equals)(""), import_ramda.not);
|
|
285
294
|
var missingName = (0, import_ramda.complement)(carriesName);
|
|
286
|
-
var carriedNamespace = (0, import_ramda.pipe)(
|
|
295
|
+
var carriedNamespace = (0, import_ramda.pipe)(
|
|
296
|
+
(kubernetesObject) => kubernetesObject?.metadata?.namespace,
|
|
297
|
+
(0, import_ramda.defaultTo)("")
|
|
298
|
+
);
|
|
287
299
|
var carriesNamespace = (0, import_ramda.pipe)(carriedNamespace, (0, import_ramda.equals)(""), import_ramda.not);
|
|
288
|
-
var carriedAnnotations = (0, import_ramda.pipe)(
|
|
300
|
+
var carriedAnnotations = (0, import_ramda.pipe)(
|
|
301
|
+
(kubernetesObject) => kubernetesObject?.metadata?.annotations,
|
|
302
|
+
(0, import_ramda.defaultTo)({})
|
|
303
|
+
);
|
|
289
304
|
var carriesAnnotations = (0, import_ramda.pipe)(carriedAnnotations, (0, import_ramda.equals)({}), import_ramda.not);
|
|
290
|
-
var carriedLabels = (0, import_ramda.pipe)(
|
|
305
|
+
var carriedLabels = (0, import_ramda.pipe)(
|
|
306
|
+
(kubernetesObject) => kubernetesObject?.metadata?.labels,
|
|
307
|
+
(0, import_ramda.defaultTo)({})
|
|
308
|
+
);
|
|
291
309
|
var carriesLabels = (0, import_ramda.pipe)(carriedLabels, (0, import_ramda.equals)({}), import_ramda.not);
|
|
292
|
-
var definesDeletionTimestamp = (0, import_ramda.pipe)(
|
|
310
|
+
var definesDeletionTimestamp = (0, import_ramda.pipe)(
|
|
311
|
+
(binding) => binding?.filters?.deletionTimestamp ?? false,
|
|
312
|
+
(0, import_ramda.defaultTo)(false)
|
|
313
|
+
);
|
|
293
314
|
var ignoresDeletionTimestamp = (0, import_ramda.complement)(definesDeletionTimestamp);
|
|
294
|
-
var definedName = (0, import_ramda.pipe)((binding) =>
|
|
315
|
+
var definedName = (0, import_ramda.pipe)((binding) => {
|
|
316
|
+
return binding.filters.name;
|
|
317
|
+
}, (0, import_ramda.defaultTo)(""));
|
|
295
318
|
var definesName = (0, import_ramda.pipe)(definedName, (0, import_ramda.equals)(""), import_ramda.not);
|
|
296
319
|
var ignoresName = (0, import_ramda.complement)(definesName);
|
|
297
|
-
var definedNameRegex = (0, import_ramda.pipe)(
|
|
320
|
+
var definedNameRegex = (0, import_ramda.pipe)(
|
|
321
|
+
(binding) => binding.filters?.regexName,
|
|
322
|
+
(0, import_ramda.defaultTo)("")
|
|
323
|
+
);
|
|
298
324
|
var definesNameRegex = (0, import_ramda.pipe)(definedNameRegex, (0, import_ramda.equals)(""), import_ramda.not);
|
|
299
325
|
var definedNamespaces = (0, import_ramda.pipe)((binding) => binding?.filters?.namespaces, (0, import_ramda.defaultTo)([]));
|
|
300
326
|
var definesNamespaces = (0, import_ramda.pipe)(definedNamespaces, (0, import_ramda.equals)([]), import_ramda.not);
|
|
@@ -304,20 +330,22 @@ var definedAnnotations = (0, import_ramda.pipe)((binding) => binding?.filters?.a
|
|
|
304
330
|
var definesAnnotations = (0, import_ramda.pipe)(definedAnnotations, (0, import_ramda.equals)({}), import_ramda.not);
|
|
305
331
|
var definedLabels = (0, import_ramda.pipe)((binding) => binding?.filters?.labels, (0, import_ramda.defaultTo)({}));
|
|
306
332
|
var definesLabels = (0, import_ramda.pipe)(definedLabels, (0, import_ramda.equals)({}), import_ramda.not);
|
|
307
|
-
var definedEvent = (
|
|
333
|
+
var definedEvent = (binding) => {
|
|
334
|
+
return binding.event;
|
|
335
|
+
};
|
|
308
336
|
var definesDelete = (0, import_ramda.pipe)(definedEvent, (0, import_ramda.equals)("DELETE" /* DELETE */));
|
|
309
337
|
var definedGroup = (0, import_ramda.pipe)((binding) => binding?.kind?.group, (0, import_ramda.defaultTo)(""));
|
|
310
338
|
var definesGroup = (0, import_ramda.pipe)(definedGroup, (0, import_ramda.equals)(""), import_ramda.not);
|
|
311
|
-
var definedVersion = (0, import_ramda.pipe)(
|
|
339
|
+
var definedVersion = (0, import_ramda.pipe)(
|
|
340
|
+
(binding) => binding?.kind?.version,
|
|
341
|
+
(0, import_ramda.defaultTo)("")
|
|
342
|
+
);
|
|
312
343
|
var definesVersion = (0, import_ramda.pipe)(definedVersion, (0, import_ramda.equals)(""), import_ramda.not);
|
|
313
344
|
var definedKind = (0, import_ramda.pipe)((binding) => binding?.kind?.kind, (0, import_ramda.defaultTo)(""));
|
|
314
345
|
var definesKind = (0, import_ramda.pipe)(definedKind, (0, import_ramda.equals)(""), import_ramda.not);
|
|
315
|
-
var
|
|
316
|
-
return binding.isFinalize ? "Finalize" : binding.isWatch ? "Watch" : binding.isMutate ? "Mutate" : binding.isValidate ? "Validate" : "";
|
|
317
|
-
});
|
|
318
|
-
var definedCallback = (0, import_ramda.pipe)((binding) => {
|
|
346
|
+
var definedCallback = (binding) => {
|
|
319
347
|
return binding.isFinalize ? binding.finalizeCallback : binding.isWatch ? binding.watchCallback : binding.isMutate ? binding.mutateCallback : binding.isValidate ? binding.validateCallback : null;
|
|
320
|
-
}
|
|
348
|
+
};
|
|
321
349
|
var definedCallbackName = (0, import_ramda.pipe)(definedCallback, (0, import_ramda.defaultTo)({ name: "" }), (callback) => callback.name);
|
|
322
350
|
var mismatchedDeletionTimestamp = (0, import_ramda.allPass)([
|
|
323
351
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesDeletionTimestamp),
|
|
@@ -332,7 +360,7 @@ var mismatchedNameRegex = (0, import_ramda.allPass)([
|
|
|
332
360
|
(0, import_ramda.pipe)((binding, kubernetesObject) => new RegExp(definedNameRegex(binding)).test(carriedName(kubernetesObject)), import_ramda.not)
|
|
333
361
|
]);
|
|
334
362
|
var bindsToKind = (0, import_ramda.curry)(
|
|
335
|
-
(0, import_ramda.allPass)([(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definedKind, (0, import_ramda.equals)(""), import_ramda.not), (0, import_ramda.pipe)((binding,
|
|
363
|
+
(0, import_ramda.allPass)([(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definedKind, (0, import_ramda.equals)(""), import_ramda.not), (0, import_ramda.pipe)((binding, kind3) => definedKind(binding) === kind3)])
|
|
336
364
|
);
|
|
337
365
|
var bindsToNamespace = (0, import_ramda.curry)((0, import_ramda.pipe)(bindsToKind(import_ramda.__, "Namespace")));
|
|
338
366
|
var misboundNamespace = (0, import_ramda.allPass)([bindsToNamespace, definesNamespaces]);
|
|
@@ -399,8 +427,8 @@ var unbindableNamespaces = (0, import_ramda.allPass)([
|
|
|
399
427
|
]);
|
|
400
428
|
var misboundDeleteWithDeletionTimestamp = (0, import_ramda.allPass)([definesDelete, definesDeletionTimestamp]);
|
|
401
429
|
var operationMatchesEvent = (0, import_ramda.anyPass)([
|
|
402
|
-
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), (0, import_ramda.equals)("*" /*
|
|
403
|
-
(0, import_ramda.pipe)((operation, event) => operation === event),
|
|
430
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), (0, import_ramda.equals)("*" /* ANY */)),
|
|
431
|
+
(0, import_ramda.pipe)((operation, event) => operation.valueOf() === event.valueOf()),
|
|
404
432
|
(0, import_ramda.pipe)((operation, event) => operation ? event.includes(operation) : false)
|
|
405
433
|
]);
|
|
406
434
|
var mismatchedEvent = (0, import_ramda.pipe)(
|
|
@@ -549,8 +577,8 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
549
577
|
skipDecode = convertFromBase64Map(wrapped.Raw);
|
|
550
578
|
}
|
|
551
579
|
logger_default.info(reqMetadata, `Processing request`);
|
|
552
|
-
for (const { name, bindings, namespaces } of capabilities) {
|
|
553
|
-
const actionMetadata = { ...reqMetadata, name };
|
|
580
|
+
for (const { name: name2, bindings, namespaces } of capabilities) {
|
|
581
|
+
const actionMetadata = { ...reqMetadata, name: name2 };
|
|
554
582
|
for (const action of bindings) {
|
|
555
583
|
if (!action.mutateCallback) {
|
|
556
584
|
continue;
|
|
@@ -567,7 +595,7 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
567
595
|
if (req.operation === "DELETE") {
|
|
568
596
|
return;
|
|
569
597
|
}
|
|
570
|
-
const identifier = `${config.uuid}.pepr.dev/${
|
|
598
|
+
const identifier = `${config.uuid}.pepr.dev/${name2}`;
|
|
571
599
|
wrapped.Raw.metadata = wrapped.Raw.metadata || {};
|
|
572
600
|
wrapped.Raw.metadata.annotations = wrapped.Raw.metadata.annotations || {};
|
|
573
601
|
wrapped.Raw.metadata.annotations[identifier] = status;
|
|
@@ -710,6 +738,35 @@ var PeprValidateRequest = class {
|
|
|
710
738
|
};
|
|
711
739
|
|
|
712
740
|
// src/lib/validate-processor.ts
|
|
741
|
+
async function processRequest(binding, actionMetadata, peprValidateRequest) {
|
|
742
|
+
const label = binding.validateCallback.name;
|
|
743
|
+
logger_default.info(actionMetadata, `Processing validation action (${label})`);
|
|
744
|
+
const valResp = {
|
|
745
|
+
uid: peprValidateRequest.Request.uid,
|
|
746
|
+
allowed: true
|
|
747
|
+
// Assume it's allowed until a validation check fails
|
|
748
|
+
};
|
|
749
|
+
try {
|
|
750
|
+
const callbackResp = await binding.validateCallback(peprValidateRequest);
|
|
751
|
+
valResp.allowed = callbackResp.allowed;
|
|
752
|
+
if (callbackResp.statusCode || callbackResp.statusMessage) {
|
|
753
|
+
valResp.status = {
|
|
754
|
+
code: callbackResp.statusCode || 400,
|
|
755
|
+
message: callbackResp.statusMessage || `Validation failed for ${name}`
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
logger_default.info(actionMetadata, `Validation action complete (${label}): ${callbackResp.allowed ? "allowed" : "denied"}`);
|
|
759
|
+
return valResp;
|
|
760
|
+
} catch (e) {
|
|
761
|
+
logger_default.error(actionMetadata, `Action failed: ${JSON.stringify(e)}`);
|
|
762
|
+
valResp.allowed = false;
|
|
763
|
+
valResp.status = {
|
|
764
|
+
code: 500,
|
|
765
|
+
message: `Action failed with error: ${JSON.stringify(e)}`
|
|
766
|
+
};
|
|
767
|
+
return valResp;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
713
770
|
async function validateProcessor(config, capabilities, req, reqMetadata) {
|
|
714
771
|
const wrapped = new PeprValidateRequest(req);
|
|
715
772
|
const response = [];
|
|
@@ -718,44 +775,19 @@ async function validateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
718
775
|
convertFromBase64Map(wrapped.Raw);
|
|
719
776
|
}
|
|
720
777
|
logger_default.info(reqMetadata, `Processing validation request`);
|
|
721
|
-
for (const { name, bindings, namespaces } of capabilities) {
|
|
722
|
-
const actionMetadata = { ...reqMetadata, name };
|
|
723
|
-
for (const
|
|
724
|
-
if (!
|
|
778
|
+
for (const { name: name2, bindings, namespaces } of capabilities) {
|
|
779
|
+
const actionMetadata = { ...reqMetadata, name: name2 };
|
|
780
|
+
for (const binding of bindings) {
|
|
781
|
+
if (!binding.validateCallback) {
|
|
725
782
|
continue;
|
|
726
783
|
}
|
|
727
|
-
const
|
|
728
|
-
uid: req.uid,
|
|
729
|
-
allowed: true
|
|
730
|
-
// Assume it's allowed until a validation check fails
|
|
731
|
-
};
|
|
732
|
-
const shouldSkip = shouldSkipRequest(action, req, namespaces, config?.alwaysIgnore?.namespaces);
|
|
784
|
+
const shouldSkip = shouldSkipRequest(binding, req, namespaces, config?.alwaysIgnore?.namespaces);
|
|
733
785
|
if (shouldSkip !== "") {
|
|
734
786
|
logger_default.debug(shouldSkip);
|
|
735
787
|
continue;
|
|
736
788
|
}
|
|
737
|
-
const
|
|
738
|
-
|
|
739
|
-
try {
|
|
740
|
-
const resp = await action.validateCallback(wrapped);
|
|
741
|
-
localResponse.allowed = resp.allowed;
|
|
742
|
-
if (resp.statusCode || resp.statusMessage) {
|
|
743
|
-
localResponse.status = {
|
|
744
|
-
code: resp.statusCode || 400,
|
|
745
|
-
message: resp.statusMessage || `Validation failed for ${name}`
|
|
746
|
-
};
|
|
747
|
-
}
|
|
748
|
-
logger_default.info(actionMetadata, `Validation action complete (${label}): ${resp.allowed ? "allowed" : "denied"}`);
|
|
749
|
-
} catch (e) {
|
|
750
|
-
logger_default.error(actionMetadata, `Action failed: ${JSON.stringify(e)}`);
|
|
751
|
-
localResponse.allowed = false;
|
|
752
|
-
localResponse.status = {
|
|
753
|
-
code: 500,
|
|
754
|
-
message: `Action failed with error: ${JSON.stringify(e)}`
|
|
755
|
-
};
|
|
756
|
-
return [localResponse];
|
|
757
|
-
}
|
|
758
|
-
response.push(localResponse);
|
|
789
|
+
const resp = await processRequest(binding, actionMetadata, wrapped);
|
|
790
|
+
response.push(resp);
|
|
759
791
|
}
|
|
760
792
|
}
|
|
761
793
|
return response;
|
|
@@ -779,12 +811,12 @@ var peprStoreGVK = {
|
|
|
779
811
|
// src/lib/controller/storeCache.ts
|
|
780
812
|
var import_kubernetes_fluent_client2 = require("kubernetes-fluent-client");
|
|
781
813
|
var import_http_status_codes = require("http-status-codes");
|
|
782
|
-
var sendUpdatesAndFlushCache = async (cache, namespace2,
|
|
814
|
+
var sendUpdatesAndFlushCache = async (cache, namespace2, name2) => {
|
|
783
815
|
const indexes = Object.keys(cache);
|
|
784
816
|
const payload = Object.values(cache);
|
|
785
817
|
try {
|
|
786
818
|
if (payload.length > 0) {
|
|
787
|
-
await (0, import_kubernetes_fluent_client2.K8s)(Store, { namespace: namespace2, name }).Patch(payload);
|
|
819
|
+
await (0, import_kubernetes_fluent_client2.K8s)(Store, { namespace: namespace2, name: name2 }).Patch(updateCacheID(payload));
|
|
788
820
|
Object.keys(cache).forEach((key) => delete cache[key]);
|
|
789
821
|
}
|
|
790
822
|
} catch (err) {
|
|
@@ -816,32 +848,41 @@ var fillStoreCache = (cache, capabilityName, op, cacheItem) => {
|
|
|
816
848
|
}
|
|
817
849
|
return cache;
|
|
818
850
|
};
|
|
851
|
+
function updateCacheID(payload) {
|
|
852
|
+
payload.push({
|
|
853
|
+
op: "replace",
|
|
854
|
+
path: "/metadata/labels/pepr.dev-cacheID",
|
|
855
|
+
value: `${Date.now()}`
|
|
856
|
+
});
|
|
857
|
+
return payload;
|
|
858
|
+
}
|
|
819
859
|
|
|
820
860
|
// src/lib/controller/store.ts
|
|
821
861
|
var namespace = "pepr-system";
|
|
822
|
-
var
|
|
862
|
+
var debounceBackoffReceive = 1e3;
|
|
863
|
+
var debounceBackoffSend = 4e3;
|
|
823
864
|
var StoreController = class {
|
|
824
865
|
#name;
|
|
825
866
|
#stores = {};
|
|
826
867
|
#sendDebounce;
|
|
827
868
|
#onReady;
|
|
828
|
-
constructor(capabilities,
|
|
869
|
+
constructor(capabilities, name2, onReady) {
|
|
829
870
|
this.#onReady = onReady;
|
|
830
|
-
this.#name =
|
|
831
|
-
const setStorageInstance = (registrationFunction,
|
|
871
|
+
this.#name = name2;
|
|
872
|
+
const setStorageInstance = (registrationFunction, name3) => {
|
|
832
873
|
const scheduleStore = registrationFunction();
|
|
833
|
-
scheduleStore.registerSender(this.#send(
|
|
834
|
-
this.#stores[
|
|
874
|
+
scheduleStore.registerSender(this.#send(name3));
|
|
875
|
+
this.#stores[name3] = scheduleStore;
|
|
835
876
|
};
|
|
836
|
-
if (
|
|
837
|
-
for (const { name:
|
|
877
|
+
if (name2.includes("schedule")) {
|
|
878
|
+
for (const { name: name3, registerScheduleStore, hasSchedule } of capabilities) {
|
|
838
879
|
if (hasSchedule === true) {
|
|
839
|
-
setStorageInstance(registerScheduleStore,
|
|
880
|
+
setStorageInstance(registerScheduleStore, name3);
|
|
840
881
|
}
|
|
841
882
|
}
|
|
842
883
|
} else {
|
|
843
|
-
for (const { name:
|
|
844
|
-
setStorageInstance(registerStore,
|
|
884
|
+
for (const { name: name3, registerStore } of capabilities) {
|
|
885
|
+
setStorageInstance(registerStore, name3);
|
|
845
886
|
}
|
|
846
887
|
}
|
|
847
888
|
setTimeout(
|
|
@@ -856,17 +897,24 @@ var StoreController = class {
|
|
|
856
897
|
};
|
|
857
898
|
#migrateAndSetupWatch = async (store) => {
|
|
858
899
|
logger_default.debug(redactedStore(store), "Pepr Store migration");
|
|
900
|
+
await (0, import_kubernetes_fluent_client3.K8s)(Store, { namespace, name: this.#name }).Patch([
|
|
901
|
+
{
|
|
902
|
+
op: "add",
|
|
903
|
+
path: "/metadata/labels/pepr.dev-cacheID",
|
|
904
|
+
value: `${Date.now()}`
|
|
905
|
+
}
|
|
906
|
+
]);
|
|
859
907
|
const data = store.data || {};
|
|
860
908
|
let storeCache = {};
|
|
861
|
-
for (const
|
|
862
|
-
const offset = `${
|
|
909
|
+
for (const name2 of Object.keys(this.#stores)) {
|
|
910
|
+
const offset = `${name2}-`.length;
|
|
863
911
|
for (const key of Object.keys(data)) {
|
|
864
|
-
if ((0, import_ramda4.startsWith)(
|
|
865
|
-
storeCache = fillStoreCache(storeCache,
|
|
912
|
+
if ((0, import_ramda4.startsWith)(name2, key) && !(0, import_ramda4.startsWith)(`${name2}-v2`, key)) {
|
|
913
|
+
storeCache = fillStoreCache(storeCache, name2, "remove", {
|
|
866
914
|
key: [key.slice(offset)],
|
|
867
915
|
value: data[key]
|
|
868
916
|
});
|
|
869
|
-
storeCache = fillStoreCache(storeCache,
|
|
917
|
+
storeCache = fillStoreCache(storeCache, name2, "add", {
|
|
870
918
|
key: [key.slice(offset)],
|
|
871
919
|
value: data[key],
|
|
872
920
|
version: "v2"
|
|
@@ -881,15 +929,15 @@ var StoreController = class {
|
|
|
881
929
|
logger_default.debug(redactedStore(store), "Pepr Store update");
|
|
882
930
|
const debounced = () => {
|
|
883
931
|
const data = store.data || {};
|
|
884
|
-
for (const
|
|
885
|
-
const offset = `${
|
|
932
|
+
for (const name2 of Object.keys(this.#stores)) {
|
|
933
|
+
const offset = `${name2}-`.length;
|
|
886
934
|
const filtered = {};
|
|
887
935
|
for (const key of Object.keys(data)) {
|
|
888
|
-
if ((0, import_ramda4.startsWith)(
|
|
936
|
+
if ((0, import_ramda4.startsWith)(name2, key)) {
|
|
889
937
|
filtered[key.slice(offset)] = data[key];
|
|
890
938
|
}
|
|
891
939
|
}
|
|
892
|
-
this.#stores[
|
|
940
|
+
this.#stores[name2].receive(filtered);
|
|
893
941
|
}
|
|
894
942
|
if (this.#onReady) {
|
|
895
943
|
this.#onReady();
|
|
@@ -897,7 +945,7 @@ var StoreController = class {
|
|
|
897
945
|
}
|
|
898
946
|
};
|
|
899
947
|
clearTimeout(this.#sendDebounce);
|
|
900
|
-
this.#sendDebounce = setTimeout(debounced, this.#onReady ? 0 :
|
|
948
|
+
this.#sendDebounce = setTimeout(debounced, this.#onReady ? 0 : debounceBackoffReceive);
|
|
901
949
|
};
|
|
902
950
|
#send = (capabilityName) => {
|
|
903
951
|
let storeCache = {};
|
|
@@ -909,7 +957,7 @@ var StoreController = class {
|
|
|
909
957
|
logger_default.debug(redactedPatch(storeCache), "Sending updates to Pepr store");
|
|
910
958
|
void sendUpdatesAndFlushCache(storeCache, namespace, this.#name);
|
|
911
959
|
}
|
|
912
|
-
},
|
|
960
|
+
}, debounceBackoffSend);
|
|
913
961
|
return sender;
|
|
914
962
|
};
|
|
915
963
|
#createStoreResource = async (e) => {
|
|
@@ -919,7 +967,10 @@ var StoreController = class {
|
|
|
919
967
|
await (0, import_kubernetes_fluent_client3.K8s)(Store).Apply({
|
|
920
968
|
metadata: {
|
|
921
969
|
name: this.#name,
|
|
922
|
-
namespace
|
|
970
|
+
namespace,
|
|
971
|
+
labels: {
|
|
972
|
+
"pepr.dev-cacheID": `${Date.now()}`
|
|
973
|
+
}
|
|
923
974
|
},
|
|
924
975
|
data: {
|
|
925
976
|
// JSON Patch will die if the data is empty, so we need to add a placeholder
|
|
@@ -933,6 +984,35 @@ var StoreController = class {
|
|
|
933
984
|
};
|
|
934
985
|
};
|
|
935
986
|
|
|
987
|
+
// src/lib/controller/index.util.ts
|
|
988
|
+
function karForMutate(mr) {
|
|
989
|
+
return {
|
|
990
|
+
apiVersion: "admission.k8s.io/v1",
|
|
991
|
+
kind: "AdmissionReview",
|
|
992
|
+
response: mr
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
function karForValidate(ar, vr) {
|
|
996
|
+
const isAllowed = vr.filter((r) => !r.allowed).length === 0;
|
|
997
|
+
const resp = vr.length === 0 ? {
|
|
998
|
+
uid: ar.uid,
|
|
999
|
+
allowed: true,
|
|
1000
|
+
status: { code: 200, message: "no in-scope validations -- allowed!" }
|
|
1001
|
+
} : {
|
|
1002
|
+
uid: vr[0].uid,
|
|
1003
|
+
allowed: isAllowed,
|
|
1004
|
+
status: {
|
|
1005
|
+
code: isAllowed ? 200 : 422,
|
|
1006
|
+
message: vr.filter((rl) => !rl.allowed).map((curr) => curr.status?.message).join("; ")
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
return {
|
|
1010
|
+
apiVersion: "admission.k8s.io/v1",
|
|
1011
|
+
kind: "AdmissionReview",
|
|
1012
|
+
response: resp
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
|
|
936
1016
|
// src/lib/controller/index.ts
|
|
937
1017
|
if (!process.env.PEPR_NODE_WARNINGS) {
|
|
938
1018
|
process.removeAllListeners("warning");
|
|
@@ -1050,6 +1130,7 @@ var Controller = class _Controller {
|
|
|
1050
1130
|
*/
|
|
1051
1131
|
#metrics = async (req, res) => {
|
|
1052
1132
|
try {
|
|
1133
|
+
res.set("Content-Type", "text/plain; version=0.0.4");
|
|
1053
1134
|
res.send(await this.#metricsCollector.getMetrics());
|
|
1054
1135
|
} catch (err) {
|
|
1055
1136
|
logger_default.error(err, `Error getting metrics`);
|
|
@@ -1067,56 +1148,23 @@ var Controller = class _Controller {
|
|
|
1067
1148
|
const startTime = MetricsCollector.observeStart();
|
|
1068
1149
|
try {
|
|
1069
1150
|
const request = req.body?.request || {};
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
const reqMetadata = {
|
|
1075
|
-
uid: request.uid,
|
|
1076
|
-
namespace: namespace2,
|
|
1077
|
-
name
|
|
1151
|
+
const { name: name2, namespace: namespace2, gvk } = {
|
|
1152
|
+
name: request?.name ? `/${request.name}` : "",
|
|
1153
|
+
namespace: request?.namespace || "",
|
|
1154
|
+
gvk: request?.kind || { group: "", version: "", kind: "" }
|
|
1078
1155
|
};
|
|
1156
|
+
const reqMetadata = { uid: request.uid, namespace: namespace2, name: name2 };
|
|
1079
1157
|
logger_default.info({ ...reqMetadata, gvk, operation: request.operation, admissionKind }, "Incoming request");
|
|
1080
1158
|
logger_default.debug({ ...reqMetadata, request }, "Incoming request body");
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
} else {
|
|
1085
|
-
response = await validateProcessor(this.#config, this.#capabilities, request, reqMetadata);
|
|
1086
|
-
}
|
|
1087
|
-
const responseList = Array.isArray(response) ? response : [response];
|
|
1088
|
-
responseList.map((res2) => {
|
|
1159
|
+
this.#beforeHook && this.#beforeHook(request || {});
|
|
1160
|
+
const response = admissionKind === "Mutate" ? await mutateProcessor(this.#config, this.#capabilities, request, reqMetadata) : await validateProcessor(this.#config, this.#capabilities, request, reqMetadata);
|
|
1161
|
+
[response].flat().map((res2) => {
|
|
1089
1162
|
this.#afterHook && this.#afterHook(res2);
|
|
1090
1163
|
logger_default.info({ ...reqMetadata, res: res2 }, "Check response");
|
|
1091
1164
|
});
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
logger_default.debug({ ...reqMetadata, response }, "Outgoing response");
|
|
1096
|
-
res.send({
|
|
1097
|
-
apiVersion: "admission.k8s.io/v1",
|
|
1098
|
-
kind: "AdmissionReview",
|
|
1099
|
-
response: kubeAdmissionResponse
|
|
1100
|
-
});
|
|
1101
|
-
} else {
|
|
1102
|
-
kubeAdmissionResponse = responseList.length === 0 ? {
|
|
1103
|
-
uid: request.uid,
|
|
1104
|
-
allowed: true,
|
|
1105
|
-
status: { message: "no in-scope validations -- allowed!" }
|
|
1106
|
-
} : {
|
|
1107
|
-
uid: responseList[0].uid,
|
|
1108
|
-
allowed: responseList.filter((r) => !r.allowed).length === 0,
|
|
1109
|
-
status: {
|
|
1110
|
-
message: responseList.filter((rl) => !rl.allowed).map((curr) => curr.status?.message).join("; ")
|
|
1111
|
-
}
|
|
1112
|
-
};
|
|
1113
|
-
res.send({
|
|
1114
|
-
apiVersion: "admission.k8s.io/v1",
|
|
1115
|
-
kind: "AdmissionReview",
|
|
1116
|
-
response: kubeAdmissionResponse
|
|
1117
|
-
});
|
|
1118
|
-
}
|
|
1119
|
-
logger_default.debug({ ...reqMetadata, kubeAdmissionResponse }, "Outgoing response");
|
|
1165
|
+
const kar = admissionKind === "Mutate" ? karForMutate(response) : karForValidate(request, response);
|
|
1166
|
+
logger_default.debug({ ...reqMetadata, kubeAdmissionResponse: kar.response }, "Outgoing response");
|
|
1167
|
+
res.send(kar);
|
|
1120
1168
|
this.#metricsCollector.observeEnd(startTime, admissionKind);
|
|
1121
1169
|
} catch (err) {
|
|
1122
1170
|
logger_default.error(err, `Error processing ${admissionKind} request`);
|
|
@@ -1135,6 +1183,10 @@ var Controller = class _Controller {
|
|
|
1135
1183
|
static #logger(req, res, next) {
|
|
1136
1184
|
const startTime = Date.now();
|
|
1137
1185
|
res.on("finish", () => {
|
|
1186
|
+
const excludedRoutes = ["/healthz", "/metrics"];
|
|
1187
|
+
if (excludedRoutes.includes(req.originalUrl)) {
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1138
1190
|
const elapsedTime = Date.now() - startTime;
|
|
1139
1191
|
const message = {
|
|
1140
1192
|
uid: req.body?.request?.uid,
|
|
@@ -1164,12 +1216,9 @@ var Controller = class _Controller {
|
|
|
1164
1216
|
};
|
|
1165
1217
|
|
|
1166
1218
|
// src/lib/watch-processor.ts
|
|
1167
|
-
var
|
|
1219
|
+
var import_kubernetes_fluent_client6 = require("kubernetes-fluent-client");
|
|
1168
1220
|
var import_types = require("kubernetes-fluent-client/dist/fluent/types");
|
|
1169
1221
|
|
|
1170
|
-
// src/lib/helpers.ts
|
|
1171
|
-
var import_kubernetes_fluent_client5 = require("kubernetes-fluent-client");
|
|
1172
|
-
|
|
1173
1222
|
// src/sdk/sdk.ts
|
|
1174
1223
|
var sdk_exports = {};
|
|
1175
1224
|
__export(sdk_exports, {
|
|
@@ -1195,7 +1244,6 @@ function containers(request, containerType) {
|
|
|
1195
1244
|
return [...containers2, ...initContainers, ...ephemeralContainers];
|
|
1196
1245
|
}
|
|
1197
1246
|
async function writeEvent(cr, event, eventType, eventReason, reportingComponent, reportingInstance) {
|
|
1198
|
-
logger_default.debug(cr.metadata, `Writing event: ${event.message}`);
|
|
1199
1247
|
await (0, import_kubernetes_fluent_client4.K8s)(import_kubernetes_fluent_client4.kind.CoreEvent).Create({
|
|
1200
1248
|
type: eventType,
|
|
1201
1249
|
reason: eventReason,
|
|
@@ -1218,31 +1266,31 @@ async function writeEvent(cr, event, eventType, eventReason, reportingComponent,
|
|
|
1218
1266
|
});
|
|
1219
1267
|
}
|
|
1220
1268
|
function getOwnerRefFrom(customResource, blockOwnerDeletion, controller) {
|
|
1221
|
-
const { apiVersion, kind:
|
|
1222
|
-
const { name, uid } = metadata;
|
|
1269
|
+
const { apiVersion, kind: kind3, metadata } = customResource;
|
|
1270
|
+
const { name: name2, uid } = metadata;
|
|
1223
1271
|
return [
|
|
1224
1272
|
{
|
|
1225
1273
|
apiVersion,
|
|
1226
|
-
kind:
|
|
1274
|
+
kind: kind3,
|
|
1227
1275
|
uid,
|
|
1228
|
-
name,
|
|
1276
|
+
name: name2,
|
|
1229
1277
|
...blockOwnerDeletion !== void 0 && { blockOwnerDeletion },
|
|
1230
1278
|
...controller !== void 0 && { controller }
|
|
1231
1279
|
}
|
|
1232
1280
|
];
|
|
1233
1281
|
}
|
|
1234
|
-
function sanitizeResourceName(
|
|
1235
|
-
return
|
|
1282
|
+
function sanitizeResourceName(name2) {
|
|
1283
|
+
return name2.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 250).replace(/^[^a-z]+|[^a-z]+$/g, "");
|
|
1236
1284
|
}
|
|
1237
1285
|
|
|
1238
1286
|
// src/lib/helpers.ts
|
|
1239
|
-
function filterNoMatchReason(binding,
|
|
1287
|
+
function filterNoMatchReason(binding, kubernetesObject, capabilityNamespaces, ignoredNamespaces) {
|
|
1240
1288
|
const prefix = "Ignoring Watch Callback:";
|
|
1241
|
-
return mismatchedDeletionTimestamp(binding,
|
|
1289
|
+
return mismatchedDeletionTimestamp(binding, kubernetesObject) ? `${prefix} Binding defines deletionTimestamp but Object does not carry it.` : mismatchedName(binding, kubernetesObject) ? `${prefix} Binding defines name '${definedName(binding)}' but Object carries '${carriedName(kubernetesObject)}'.` : misboundNamespace(binding) ? `${prefix} Cannot use namespace filter on a namespace object.` : mismatchedLabels(binding, kubernetesObject) ? `${prefix} Binding defines labels '${JSON.stringify(definedLabels(binding))}' but Object carries '${JSON.stringify(carriedLabels(kubernetesObject))}'.` : mismatchedAnnotations(binding, kubernetesObject) ? `${prefix} Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' but Object carries '${JSON.stringify(carriedAnnotations(kubernetesObject))}'.` : uncarryableNamespace(capabilityNamespaces, kubernetesObject) ? `${prefix} Object carries namespace '${carriedNamespace(kubernetesObject)}' but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : unbindableNamespaces(capabilityNamespaces, binding) ? `${prefix} Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : mismatchedNamespace(binding, kubernetesObject) ? `${prefix} Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' but Object carries '${carriedNamespace(kubernetesObject)}'.` : mismatchedNamespaceRegex(binding, kubernetesObject) ? `${prefix} Binding defines namespace regexes '${JSON.stringify(definedNamespaceRegexes(binding))}' but Object carries '${carriedNamespace(kubernetesObject)}'.` : mismatchedNameRegex(binding, kubernetesObject) ? `${prefix} Binding defines name regex '${definedNameRegex(binding)}' but Object carries '${carriedName(kubernetesObject)}'.` : carriesIgnoredNamespace(ignoredNamespaces, kubernetesObject) ? `${prefix} Object carries namespace '${carriedNamespace(kubernetesObject)}' but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.` : missingCarriableNamespace(capabilityNamespaces, kubernetesObject) ? `${prefix} Object does not carry a namespace but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : "";
|
|
1242
1290
|
}
|
|
1243
1291
|
|
|
1244
1292
|
// src/lib/finalizer.ts
|
|
1245
|
-
var
|
|
1293
|
+
var import_kubernetes_fluent_client5 = require("kubernetes-fluent-client");
|
|
1246
1294
|
function addFinalizer(request) {
|
|
1247
1295
|
if (request.Request.operation === "DELETE" /* DELETE */) {
|
|
1248
1296
|
return;
|
|
@@ -1262,18 +1310,18 @@ async function removeFinalizer(binding, obj) {
|
|
|
1262
1310
|
const meta = obj.metadata;
|
|
1263
1311
|
const resource = `${meta.namespace || "ClusterScoped"}/${meta.name}`;
|
|
1264
1312
|
logger_default.debug({ obj }, `Removing finalizer '${peprFinal}' from '${resource}'`);
|
|
1265
|
-
const { model, kind:
|
|
1313
|
+
const { model, kind: kind3 } = binding;
|
|
1266
1314
|
try {
|
|
1267
|
-
(0,
|
|
1315
|
+
(0, import_kubernetes_fluent_client5.RegisterKind)(model, kind3);
|
|
1268
1316
|
} catch (e) {
|
|
1269
1317
|
const expected = e.message === `GVK ${model.name} already registered`;
|
|
1270
1318
|
if (!expected) {
|
|
1271
|
-
logger_default.error({ model, kind:
|
|
1319
|
+
logger_default.error({ model, kind: kind3, error: e }, `Error registering "${kind3}" during finalization.`);
|
|
1272
1320
|
return;
|
|
1273
1321
|
}
|
|
1274
1322
|
}
|
|
1275
1323
|
const finalizers = meta.finalizers?.filter((f) => f !== peprFinal) || [];
|
|
1276
|
-
obj = await (0,
|
|
1324
|
+
obj = await (0, import_kubernetes_fluent_client5.K8s)(model, meta).Patch([
|
|
1277
1325
|
{
|
|
1278
1326
|
op: "replace",
|
|
1279
1327
|
path: `/metadata/finalizers`,
|
|
@@ -1290,8 +1338,8 @@ var Queue = class {
|
|
|
1290
1338
|
#uid;
|
|
1291
1339
|
#queue = [];
|
|
1292
1340
|
#pendingPromise = false;
|
|
1293
|
-
constructor(
|
|
1294
|
-
this.#name =
|
|
1341
|
+
constructor(name2) {
|
|
1342
|
+
this.#name = name2;
|
|
1295
1343
|
this.#uid = `${Date.now()}-${(0, import_node_crypto.randomBytes)(2).toString("hex")}`;
|
|
1296
1344
|
}
|
|
1297
1345
|
label() {
|
|
@@ -1379,12 +1427,12 @@ function queueKey(obj) {
|
|
|
1379
1427
|
let strat = process.env.PEPR_RECONCILE_STRATEGY || d3fault;
|
|
1380
1428
|
strat = options.includes(strat) ? strat : d3fault;
|
|
1381
1429
|
const ns = obj.metadata?.namespace ?? "cluster-scoped";
|
|
1382
|
-
const
|
|
1383
|
-
const
|
|
1430
|
+
const kind3 = obj.kind ?? "UnknownKind";
|
|
1431
|
+
const name2 = obj.metadata?.name ?? "Unnamed";
|
|
1384
1432
|
const lookup = {
|
|
1385
|
-
kind: `${
|
|
1386
|
-
kindNs: `${
|
|
1387
|
-
kindNsName: `${
|
|
1433
|
+
kind: `${kind3}`,
|
|
1434
|
+
kindNs: `${kind3}/${ns}`,
|
|
1435
|
+
kindNsName: `${kind3}/${ns}/${name2}`,
|
|
1388
1436
|
global: "global"
|
|
1389
1437
|
};
|
|
1390
1438
|
return lookup[strat];
|
|
@@ -1403,11 +1451,11 @@ var watchCfg = {
|
|
|
1403
1451
|
relistIntervalSec: process.env.PEPR_RELIST_INTERVAL_SECONDS ? parseInt(process.env.PEPR_RELIST_INTERVAL_SECONDS, 10) : 600
|
|
1404
1452
|
};
|
|
1405
1453
|
var eventToPhaseMap = {
|
|
1406
|
-
["CREATE" /*
|
|
1407
|
-
["UPDATE" /*
|
|
1408
|
-
["CREATEORUPDATE" /*
|
|
1409
|
-
["DELETE" /*
|
|
1410
|
-
["*" /*
|
|
1454
|
+
["CREATE" /* CREATE */]: [import_types.WatchPhase.Added],
|
|
1455
|
+
["UPDATE" /* UPDATE */]: [import_types.WatchPhase.Modified],
|
|
1456
|
+
["CREATEORUPDATE" /* CREATE_OR_UPDATE */]: [import_types.WatchPhase.Added, import_types.WatchPhase.Modified],
|
|
1457
|
+
["DELETE" /* DELETE */]: [import_types.WatchPhase.Deleted],
|
|
1458
|
+
["*" /* ANY */]: [import_types.WatchPhase.Added, import_types.WatchPhase.Modified, import_types.WatchPhase.Deleted]
|
|
1411
1459
|
};
|
|
1412
1460
|
function setupWatch(capabilities, ignoredNamespaces) {
|
|
1413
1461
|
capabilities.map(
|
|
@@ -1415,7 +1463,7 @@ function setupWatch(capabilities, ignoredNamespaces) {
|
|
|
1415
1463
|
);
|
|
1416
1464
|
}
|
|
1417
1465
|
async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
1418
|
-
const phaseMatch = eventToPhaseMap[binding.event] || eventToPhaseMap["*" /*
|
|
1466
|
+
const phaseMatch = eventToPhaseMap[binding.event] || eventToPhaseMap["*" /* ANY */];
|
|
1419
1467
|
logger_default.debug({ watchCfg }, "Effective WatchConfig");
|
|
1420
1468
|
const watchCallback = async (kubernetesObject, phase) => {
|
|
1421
1469
|
if (phaseMatch.includes(phase)) {
|
|
@@ -1449,7 +1497,7 @@ async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
|
1449
1497
|
shouldRemoveFinalizer === false ? logger_default.debug({ obj: kubernetesObject }, `Skipping removal of finalizer '${peprFinal}' from '${resource}'`) : await removeFinalizer(binding, kubernetesObject);
|
|
1450
1498
|
}
|
|
1451
1499
|
};
|
|
1452
|
-
const watcher = (0,
|
|
1500
|
+
const watcher = (0, import_kubernetes_fluent_client6.K8s)(binding.model, binding.filters).Watch(async (obj, phase) => {
|
|
1453
1501
|
logger_default.debug(obj, `Watch event ${phase} received`);
|
|
1454
1502
|
if (binding.isQueue) {
|
|
1455
1503
|
const queue = getOrCreateQueue(obj);
|
|
@@ -1458,30 +1506,30 @@ async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
|
1458
1506
|
await watchCallback(obj, phase);
|
|
1459
1507
|
}
|
|
1460
1508
|
}, watchCfg);
|
|
1461
|
-
watcher.events.on(
|
|
1509
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, (err) => {
|
|
1462
1510
|
logger_default.error(err, "Watch failed after 5 attempts, giving up");
|
|
1463
1511
|
process.exit(1);
|
|
1464
1512
|
});
|
|
1465
|
-
watcher.events.on(
|
|
1466
|
-
watcher.events.on(
|
|
1513
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.CONNECT, (url) => logEvent(import_kubernetes_fluent_client6.WatchEvent.CONNECT, url));
|
|
1514
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.DATA_ERROR, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.DATA_ERROR, err.message));
|
|
1467
1515
|
watcher.events.on(
|
|
1468
|
-
|
|
1469
|
-
(retryCount) => logEvent(
|
|
1516
|
+
import_kubernetes_fluent_client6.WatchEvent.RECONNECT,
|
|
1517
|
+
(retryCount) => logEvent(import_kubernetes_fluent_client6.WatchEvent.RECONNECT, `Reconnecting after ${retryCount} attempt${retryCount === 1 ? "" : "s"}`)
|
|
1470
1518
|
);
|
|
1471
|
-
watcher.events.on(
|
|
1472
|
-
watcher.events.on(
|
|
1473
|
-
watcher.events.on(
|
|
1474
|
-
watcher.events.on(
|
|
1475
|
-
watcher.events.on(
|
|
1476
|
-
watcher.events.on(
|
|
1477
|
-
watcher.events.on(
|
|
1478
|
-
watcher.events.on(
|
|
1519
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.RECONNECT_PENDING, () => logEvent(import_kubernetes_fluent_client6.WatchEvent.RECONNECT_PENDING));
|
|
1520
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, err.message));
|
|
1521
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.ABORT, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.ABORT, err.message));
|
|
1522
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.OLD_RESOURCE_VERSION, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.OLD_RESOURCE_VERSION, err));
|
|
1523
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.NETWORK_ERROR, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.NETWORK_ERROR, err.message));
|
|
1524
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.LIST_ERROR, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.LIST_ERROR, err.message));
|
|
1525
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.LIST, (list) => logEvent(import_kubernetes_fluent_client6.WatchEvent.LIST, JSON.stringify(list, void 0, 2)));
|
|
1526
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.CACHE_MISS, (windowName) => {
|
|
1479
1527
|
metricsCollector.incCacheMiss(windowName);
|
|
1480
1528
|
});
|
|
1481
|
-
watcher.events.on(
|
|
1529
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.INIT_CACHE_MISS, (windowName) => {
|
|
1482
1530
|
metricsCollector.initCacheMissWindow(windowName);
|
|
1483
1531
|
});
|
|
1484
|
-
watcher.events.on(
|
|
1532
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.INC_RESYNC_FAILURE_COUNT, (retryCount) => {
|
|
1485
1533
|
metricsCollector.incRetryCount(retryCount);
|
|
1486
1534
|
});
|
|
1487
1535
|
try {
|
|
@@ -1616,17 +1664,19 @@ var Storage = class {
|
|
|
1616
1664
|
*/
|
|
1617
1665
|
setItemAndWait = (key, value) => {
|
|
1618
1666
|
this.#dispatchUpdate("add", [v2StoreKey(key)], value);
|
|
1667
|
+
const record = {};
|
|
1619
1668
|
return new Promise((resolve, reject) => {
|
|
1620
|
-
|
|
1669
|
+
record.timeout = setTimeout(() => {
|
|
1670
|
+
record.unsubscribe();
|
|
1671
|
+
return reject(`MAX_WAIT_TIME elapsed: Key ${key} not seen in ${MAX_WAIT_TIME / 1e3}s`);
|
|
1672
|
+
}, MAX_WAIT_TIME);
|
|
1673
|
+
record.unsubscribe = this.subscribe((data) => {
|
|
1621
1674
|
if (data[`${v2UnescapedStoreKey(key)}`] === value) {
|
|
1622
|
-
unsubscribe();
|
|
1623
|
-
|
|
1675
|
+
record.unsubscribe();
|
|
1676
|
+
clearTimeout(record.timeout);
|
|
1677
|
+
resolve("ok");
|
|
1624
1678
|
}
|
|
1625
1679
|
});
|
|
1626
|
-
setTimeout(() => {
|
|
1627
|
-
unsubscribe();
|
|
1628
|
-
return reject();
|
|
1629
|
-
}, MAX_WAIT_TIME);
|
|
1630
1680
|
});
|
|
1631
1681
|
};
|
|
1632
1682
|
/**
|
|
@@ -1638,17 +1688,19 @@ var Storage = class {
|
|
|
1638
1688
|
*/
|
|
1639
1689
|
removeItemAndWait = (key) => {
|
|
1640
1690
|
this.#dispatchUpdate("remove", [v2StoreKey(key)]);
|
|
1691
|
+
const record = {};
|
|
1641
1692
|
return new Promise((resolve, reject) => {
|
|
1642
|
-
|
|
1693
|
+
record.timeout = setTimeout(() => {
|
|
1694
|
+
record.unsubscribe();
|
|
1695
|
+
return reject(`MAX_WAIT_TIME elapsed: Key ${key} still seen after ${MAX_WAIT_TIME / 1e3}s`);
|
|
1696
|
+
}, MAX_WAIT_TIME);
|
|
1697
|
+
record.unsubscribe = this.subscribe((data) => {
|
|
1643
1698
|
if (!Object.hasOwn(data, `${v2UnescapedStoreKey(key)}`)) {
|
|
1644
|
-
unsubscribe();
|
|
1645
|
-
|
|
1699
|
+
record.unsubscribe();
|
|
1700
|
+
clearTimeout(record.timeout);
|
|
1701
|
+
resolve("ok");
|
|
1646
1702
|
}
|
|
1647
1703
|
});
|
|
1648
|
-
setTimeout(() => {
|
|
1649
|
-
unsubscribe();
|
|
1650
|
-
return reject();
|
|
1651
|
-
}, MAX_WAIT_TIME);
|
|
1652
1704
|
});
|
|
1653
1705
|
};
|
|
1654
1706
|
subscribe = (subscriber) => {
|
|
@@ -1832,11 +1884,11 @@ var Capability = class {
|
|
|
1832
1884
|
* @returns
|
|
1833
1885
|
*/
|
|
1834
1886
|
OnSchedule = (schedule) => {
|
|
1835
|
-
const { name, every, unit, run, startTime, completions } = schedule;
|
|
1887
|
+
const { name: name2, every, unit, run, startTime, completions } = schedule;
|
|
1836
1888
|
this.hasSchedule = true;
|
|
1837
1889
|
if (process.env.PEPR_WATCH_MODE === "true" || process.env.PEPR_MODE === "dev") {
|
|
1838
1890
|
const newSchedule = {
|
|
1839
|
-
name,
|
|
1891
|
+
name: name2,
|
|
1840
1892
|
every,
|
|
1841
1893
|
unit,
|
|
1842
1894
|
run,
|
|
@@ -1938,16 +1990,16 @@ var Capability = class {
|
|
|
1938
1990
|
* @param kind if using a custom KubernetesObject not available in `a.*`, specify the GroupVersionKind
|
|
1939
1991
|
* @returns
|
|
1940
1992
|
*/
|
|
1941
|
-
When = (model,
|
|
1942
|
-
const matchedKind = (0,
|
|
1943
|
-
if (!matchedKind && !
|
|
1993
|
+
When = (model, kind3) => {
|
|
1994
|
+
const matchedKind = (0, import_kubernetes_fluent_client7.modelToGroupVersionKind)(model.name);
|
|
1995
|
+
if (!matchedKind && !kind3) {
|
|
1944
1996
|
throw new Error(`Kind not specified for ${model.name}`);
|
|
1945
1997
|
}
|
|
1946
1998
|
const binding = {
|
|
1947
1999
|
model,
|
|
1948
2000
|
// If the kind is not specified, use the matched kind from the model
|
|
1949
|
-
kind:
|
|
1950
|
-
event: "*" /*
|
|
2001
|
+
kind: kind3 || matchedKind,
|
|
2002
|
+
event: "*" /* ANY */,
|
|
1951
2003
|
filters: {
|
|
1952
2004
|
name: "",
|
|
1953
2005
|
namespaces: [],
|
|
@@ -2037,7 +2089,7 @@ var Capability = class {
|
|
|
2037
2089
|
...binding,
|
|
2038
2090
|
isMutate: true,
|
|
2039
2091
|
isFinalize: true,
|
|
2040
|
-
event: "*" /*
|
|
2092
|
+
event: "*" /* ANY */,
|
|
2041
2093
|
mutateCallback: addFinalizer
|
|
2042
2094
|
};
|
|
2043
2095
|
bindings.push(mutateBinding);
|
|
@@ -2047,7 +2099,7 @@ var Capability = class {
|
|
|
2047
2099
|
...binding,
|
|
2048
2100
|
isWatch: true,
|
|
2049
2101
|
isFinalize: true,
|
|
2050
|
-
event: "UPDATE" /*
|
|
2102
|
+
event: "UPDATE" /* UPDATE */,
|
|
2051
2103
|
finalizeCallback: async (update, logger = aliasLogger) => {
|
|
2052
2104
|
logger_default.info(`Executing finalize action with alias: ${binding.alias || "no alias provided"}`);
|
|
2053
2105
|
return await finalizeCallback(update, logger);
|
|
@@ -2076,9 +2128,9 @@ var Capability = class {
|
|
|
2076
2128
|
binding.filters.regexName = regexName.source;
|
|
2077
2129
|
return commonChain;
|
|
2078
2130
|
}
|
|
2079
|
-
function WithName(
|
|
2080
|
-
logger_default.debug(`Add name filter ${
|
|
2081
|
-
binding.filters.name =
|
|
2131
|
+
function WithName(name2) {
|
|
2132
|
+
logger_default.debug(`Add name filter ${name2}`, prefix);
|
|
2133
|
+
binding.filters.name = name2;
|
|
2082
2134
|
return commonChain;
|
|
2083
2135
|
}
|
|
2084
2136
|
function WithLabel(key, value = "") {
|
|
@@ -2109,10 +2161,10 @@ var Capability = class {
|
|
|
2109
2161
|
};
|
|
2110
2162
|
}
|
|
2111
2163
|
return {
|
|
2112
|
-
IsCreatedOrUpdated: () => bindEvent("CREATEORUPDATE" /*
|
|
2113
|
-
IsCreated: () => bindEvent("CREATE" /*
|
|
2114
|
-
IsUpdated: () => bindEvent("UPDATE" /*
|
|
2115
|
-
IsDeleted: () => bindEvent("DELETE" /*
|
|
2164
|
+
IsCreatedOrUpdated: () => bindEvent("CREATEORUPDATE" /* CREATE_OR_UPDATE */),
|
|
2165
|
+
IsCreated: () => bindEvent("CREATE" /* CREATE */),
|
|
2166
|
+
IsUpdated: () => bindEvent("UPDATE" /* UPDATE */),
|
|
2167
|
+
IsDeleted: () => bindEvent("DELETE" /* DELETE */)
|
|
2116
2168
|
};
|
|
2117
2169
|
};
|
|
2118
2170
|
};
|