pepr 0.42.0 → 0.42.2
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/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 +15 -0
- package/dist/cli/deploy.d.ts.map +1 -1
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.helpers.d.ts +3 -0
- package/dist/cli/format.helpers.d.ts.map +1 -0
- package/dist/cli/init/enums.d.ts +10 -0
- package/dist/cli/init/enums.d.ts.map +1 -0
- package/dist/cli/init/index.d.ts.map +1 -1
- package/dist/cli/init/templates.d.ts +15 -11
- package/dist/cli/init/templates.d.ts.map +1 -1
- package/dist/cli/init/utils.d.ts.map +1 -1
- package/dist/cli/init/walkthrough.d.ts +3 -2
- package/dist/cli/init/walkthrough.d.ts.map +1 -1
- package/dist/cli/kfc.d.ts.map +1 -1
- package/dist/cli/monitor.d.ts +23 -0
- package/dist/cli/monitor.d.ts.map +1 -1
- package/dist/cli/root.d.ts.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/uuid.d.ts.map +1 -1
- package/dist/cli.js +483 -586
- package/dist/controller.js +1 -195
- package/dist/fixtures/loader.d.ts.map +1 -1
- package/dist/lib/assets/deploy.d.ts.map +1 -1
- 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 +1 -1
- package/dist/lib/assets/index.d.ts.map +1 -1
- package/dist/lib/assets/pods.d.ts +6 -22
- package/dist/lib/assets/pods.d.ts.map +1 -1
- package/dist/lib/assets/rbac.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/controller/index.d.ts +2 -2
- package/dist/lib/controller/index.d.ts.map +1 -1
- package/dist/lib/controller/store.d.ts +1 -2
- package/dist/lib/controller/store.d.ts.map +1 -1
- package/dist/lib/controller/storeCache.d.ts +2 -1
- package/dist/lib/controller/storeCache.d.ts.map +1 -1
- package/dist/lib/{capability.d.ts → core/capability.d.ts} +1 -1
- package/dist/lib/core/capability.d.ts.map +1 -0
- package/dist/lib/{module.d.ts → core/module.d.ts} +2 -2
- package/dist/lib/core/module.d.ts.map +1 -0
- package/dist/lib/core/queue.d.ts.map +1 -0
- package/dist/lib/{schedule.d.ts → core/schedule.d.ts} +0 -1
- package/dist/lib/core/schedule.d.ts.map +1 -0
- package/dist/lib/{storage.d.ts → core/storage.d.ts} +4 -4
- package/dist/lib/core/storage.d.ts.map +1 -0
- package/dist/lib/deploymentChecks.d.ts.map +1 -1
- package/dist/lib/errors.d.ts +0 -5
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/filesystemService.d.ts.map +1 -1
- package/dist/lib/filter/adjudicators/adjudicators.d.ts +5 -4
- package/dist/lib/filter/adjudicators/adjudicators.d.ts.map +1 -1
- package/dist/lib/filter/filter.d.ts +33 -1
- package/dist/lib/filter/filter.d.ts.map +1 -1
- package/dist/lib/finalizer.d.ts.map +1 -1
- package/dist/lib/helpers.d.ts +4 -9
- package/dist/lib/helpers.d.ts.map +1 -1
- package/dist/lib/included-files.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/processors/mutate-processor.d.ts +28 -0
- package/dist/lib/processors/mutate-processor.d.ts.map +1 -0
- package/dist/lib/processors/validate-processor.d.ts +9 -0
- package/dist/lib/processors/validate-processor.d.ts.map +1 -0
- package/dist/lib/{watch-processor.d.ts → processors/watch-processor.d.ts} +2 -2
- package/dist/lib/processors/watch-processor.d.ts.map +1 -0
- package/dist/lib/telemetry/logger.d.ts.map +1 -1
- package/dist/lib/telemetry/metrics.d.ts.map +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/validate-request.d.ts +2 -2
- package/dist/lib/validate-request.d.ts.map +1 -1
- package/dist/lib.d.ts +2 -2
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +508 -341
- package/dist/lib.js.map +4 -4
- package/dist/sdk/heredoc.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/cli/build.helpers.ts +180 -0
- package/src/cli/build.ts +85 -133
- package/src/cli/deploy.ts +113 -74
- package/src/cli/dev.ts +2 -2
- package/src/cli/format.helpers.ts +27 -0
- package/src/cli/format.ts +4 -18
- package/src/cli/init/enums.ts +9 -0
- package/src/cli/init/index.ts +4 -3
- package/src/cli/init/templates.ts +30 -2
- package/src/cli/init/utils.ts +3 -3
- package/src/cli/init/walkthrough.ts +7 -8
- package/src/cli/kfc.ts +1 -1
- package/src/cli/monitor.ts +108 -65
- package/src/cli/root.ts +1 -1
- package/src/cli/update.ts +1 -1
- package/src/cli/uuid.ts +1 -1
- package/src/fixtures/loader.ts +2 -2
- package/src/lib/assets/deploy.ts +11 -11
- package/src/lib/assets/destroy.ts +1 -1
- package/src/lib/assets/helm.ts +6 -6
- package/src/lib/assets/index.ts +23 -23
- package/src/lib/assets/pods.ts +11 -6
- package/src/lib/assets/webhooks.ts +31 -46
- package/src/lib/assets/yaml.ts +12 -9
- package/src/lib/controller/index.ts +13 -11
- package/src/lib/controller/store.ts +25 -12
- package/src/lib/controller/storeCache.ts +16 -3
- package/src/lib/{capability.ts → core/capability.ts} +25 -14
- package/src/lib/{module.ts → core/module.ts} +10 -10
- package/src/lib/{queue.ts → core/queue.ts} +13 -5
- package/src/lib/{storage.ts → core/storage.ts} +33 -24
- package/src/lib/deploymentChecks.ts +2 -2
- package/src/lib/errors.ts +3 -8
- package/src/lib/filesystemService.ts +1 -1
- package/src/lib/filter/adjudicators/adjudicators.ts +40 -9
- package/src/lib/filter/filter.ts +204 -111
- package/src/lib/finalizer.ts +2 -2
- package/src/lib/helpers.ts +20 -133
- package/src/lib/included-files.ts +1 -1
- package/src/lib/mutate-request.ts +11 -11
- package/src/lib/processors/mutate-processor.ts +225 -0
- package/src/lib/processors/validate-processor.ts +93 -0
- package/src/lib/{watch-processor.ts → processors/watch-processor.ts} +19 -15
- package/src/lib/telemetry/logger.ts +3 -1
- package/src/lib/tls.ts +5 -1
- package/src/lib/utils.ts +5 -5
- package/src/lib/validate-request.ts +4 -4
- package/src/lib.ts +2 -2
- package/src/runtime/controller.ts +2 -2
- package/src/sdk/cosign.ts +4 -4
- package/src/sdk/heredoc.ts +1 -1
- package/dist/lib/capability.d.ts.map +0 -1
- package/dist/lib/module.d.ts.map +0 -1
- package/dist/lib/mutate-processor.d.ts +0 -6
- package/dist/lib/mutate-processor.d.ts.map +0 -1
- package/dist/lib/queue.d.ts.map +0 -1
- package/dist/lib/schedule.d.ts.map +0 -1
- package/dist/lib/storage.d.ts.map +0 -1
- package/dist/lib/validate-processor.d.ts +0 -6
- package/dist/lib/validate-processor.d.ts.map +0 -1
- package/dist/lib/watch-processor.d.ts.map +0 -1
- package/src/lib/mutate-processor.ts +0 -165
- package/src/lib/validate-processor.ts +0 -85
- /package/dist/lib/{queue.d.ts → core/queue.d.ts} +0 -0
- /package/src/lib/{schedule.ts → core/schedule.ts} +0 -0
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") {
|
|
@@ -49,9 +49,9 @@ module.exports = __toCommonJS(lib_exports);
|
|
|
49
49
|
var import_kubernetes_fluent_client8 = require("kubernetes-fluent-client");
|
|
50
50
|
var R = __toESM(require("ramda"));
|
|
51
51
|
|
|
52
|
-
// src/lib/capability.ts
|
|
53
|
-
var
|
|
54
|
-
var
|
|
52
|
+
// src/lib/core/capability.ts
|
|
53
|
+
var import_kubernetes_fluent_client6 = require("kubernetes-fluent-client");
|
|
54
|
+
var import_ramda8 = require("ramda");
|
|
55
55
|
|
|
56
56
|
// src/lib/telemetry/logger.ts
|
|
57
57
|
var import_pino = require("pino");
|
|
@@ -101,8 +101,8 @@ function redactedPatch(patch = {}) {
|
|
|
101
101
|
}
|
|
102
102
|
var logger_default = Log;
|
|
103
103
|
|
|
104
|
-
// src/lib/module.ts
|
|
105
|
-
var
|
|
104
|
+
// src/lib/core/module.ts
|
|
105
|
+
var import_ramda6 = require("ramda");
|
|
106
106
|
|
|
107
107
|
// src/lib/controller/index.ts
|
|
108
108
|
var import_express = __toESM(require("express"));
|
|
@@ -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.
|
|
@@ -238,21 +238,9 @@ var MetricsCollector = class {
|
|
|
238
238
|
};
|
|
239
239
|
var metricsCollector = new MetricsCollector("pepr");
|
|
240
240
|
|
|
241
|
-
// src/lib/mutate-processor.ts
|
|
241
|
+
// src/lib/processors/mutate-processor.ts
|
|
242
242
|
var import_fast_json_patch = __toESM(require("fast-json-patch"));
|
|
243
|
-
|
|
244
|
-
// src/lib/errors.ts
|
|
245
|
-
var Errors = {
|
|
246
|
-
audit: "audit",
|
|
247
|
-
ignore: "ignore",
|
|
248
|
-
reject: "reject"
|
|
249
|
-
};
|
|
250
|
-
var ErrorList = Object.values(Errors);
|
|
251
|
-
function ValidateError(error = "") {
|
|
252
|
-
if (!ErrorList.includes(error)) {
|
|
253
|
-
throw new Error(`Invalid error: ${error}. Must be one of: ${ErrorList.join(", ")}`);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
243
|
+
var import_ramda3 = require("ramda");
|
|
256
244
|
|
|
257
245
|
// src/lib/filter/adjudicators/adjudicators.ts
|
|
258
246
|
var import_ramda = require("ramda");
|
|
@@ -401,8 +389,15 @@ var mismatchedLabels = (0, import_ramda.allPass)([
|
|
|
401
389
|
]);
|
|
402
390
|
var uncarryableNamespace = (0, import_ramda.allPass)([
|
|
403
391
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
404
|
-
(0, import_ramda.pipe)((
|
|
405
|
-
|
|
392
|
+
(0, import_ramda.pipe)((namespaceSelector, kubernetesObject) => {
|
|
393
|
+
if (kubernetesObject?.kind === "Namespace") {
|
|
394
|
+
return namespaceSelector.includes(kubernetesObject?.metadata?.name);
|
|
395
|
+
}
|
|
396
|
+
if (carriesNamespace(kubernetesObject)) {
|
|
397
|
+
return namespaceSelector.includes(carriedNamespace(kubernetesObject));
|
|
398
|
+
}
|
|
399
|
+
return true;
|
|
400
|
+
}, import_ramda.not)
|
|
406
401
|
]);
|
|
407
402
|
var missingCarriableNamespace = (0, import_ramda.allPass)([
|
|
408
403
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
@@ -412,8 +407,15 @@ var missingCarriableNamespace = (0, import_ramda.allPass)([
|
|
|
412
407
|
]);
|
|
413
408
|
var carriesIgnoredNamespace = (0, import_ramda.allPass)([
|
|
414
409
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
415
|
-
(0, import_ramda.pipe)((
|
|
416
|
-
|
|
410
|
+
(0, import_ramda.pipe)((namespaceSelector, kubernetesObject) => {
|
|
411
|
+
if (kubernetesObject?.kind === "Namespace") {
|
|
412
|
+
return namespaceSelector.includes(kubernetesObject?.metadata?.name);
|
|
413
|
+
}
|
|
414
|
+
if (carriesNamespace(kubernetesObject)) {
|
|
415
|
+
return namespaceSelector.includes(carriedNamespace(kubernetesObject));
|
|
416
|
+
}
|
|
417
|
+
return false;
|
|
418
|
+
})
|
|
417
419
|
]);
|
|
418
420
|
var unbindableNamespaces = (0, import_ramda.allPass)([
|
|
419
421
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
@@ -450,9 +452,108 @@ var mismatchedKind = (0, import_ramda.allPass)([
|
|
|
450
452
|
|
|
451
453
|
// src/lib/filter/filter.ts
|
|
452
454
|
function shouldSkipRequest(binding, req, capabilityNamespaces, ignoredNamespaces) {
|
|
453
|
-
const prefix = "Ignoring Admission Callback:";
|
|
454
455
|
const obj = req.operation === "DELETE" /* DELETE */ ? req.oldObject : req.object;
|
|
455
|
-
|
|
456
|
+
const prefix = "Ignoring Admission Callback:";
|
|
457
|
+
const adjudicators = [
|
|
458
|
+
() => adjudicateMisboundDeleteWithDeletionTimestamp(binding),
|
|
459
|
+
() => adjudicateMismatchedDeletionTimestamp(binding, obj),
|
|
460
|
+
() => adjudicateMismatchedEvent(binding, req),
|
|
461
|
+
() => adjudicateMismatchedName(binding, obj),
|
|
462
|
+
() => adjudicateMismatchedGroup(binding, req),
|
|
463
|
+
() => adjudicateMismatchedVersion(binding, req),
|
|
464
|
+
() => adjudicateMismatchedKind(binding, req),
|
|
465
|
+
() => adjudicateUnbindableNamespaces(capabilityNamespaces, binding),
|
|
466
|
+
() => adjudicateUncarryableNamespace(capabilityNamespaces, obj),
|
|
467
|
+
() => adjudicateMismatchedNamespace(binding, obj),
|
|
468
|
+
() => adjudicateMismatchedLabels(binding, obj),
|
|
469
|
+
() => adjudicateMismatchedAnnotations(binding, obj),
|
|
470
|
+
() => adjudicateMismatchedNamespaceRegex(binding, obj),
|
|
471
|
+
() => adjudicateMismatchedNameRegex(binding, obj),
|
|
472
|
+
() => adjudicateCarriesIgnoredNamespace(ignoredNamespaces, obj),
|
|
473
|
+
() => adjudicateMissingCarriableNamespace(capabilityNamespaces, obj)
|
|
474
|
+
];
|
|
475
|
+
for (const adjudicator of adjudicators) {
|
|
476
|
+
const result = adjudicator();
|
|
477
|
+
if (result) {
|
|
478
|
+
return `${prefix} ${result}`;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return "";
|
|
482
|
+
}
|
|
483
|
+
function filterNoMatchReason(binding, obj, capabilityNamespaces, ignoredNamespaces) {
|
|
484
|
+
const prefix = "Ignoring Watch Callback:";
|
|
485
|
+
const adjudicators = [
|
|
486
|
+
() => adjudicateMismatchedDeletionTimestamp(binding, obj),
|
|
487
|
+
() => adjudicateMismatchedName(binding, obj),
|
|
488
|
+
() => adjudicateMisboundNamespace(binding),
|
|
489
|
+
() => adjudicateMismatchedLabels(binding, obj),
|
|
490
|
+
() => adjudicateMismatchedAnnotations(binding, obj),
|
|
491
|
+
() => adjudicateUncarryableNamespace(capabilityNamespaces, obj),
|
|
492
|
+
() => adjudicateUnbindableNamespaces(capabilityNamespaces, binding),
|
|
493
|
+
() => adjudicateMismatchedNamespace(binding, obj),
|
|
494
|
+
() => adjudicateMismatchedNamespaceRegex(binding, obj),
|
|
495
|
+
() => adjudicateMismatchedNameRegex(binding, obj),
|
|
496
|
+
() => adjudicateCarriesIgnoredNamespace(ignoredNamespaces, obj),
|
|
497
|
+
() => adjudicateMissingCarriableNamespace(capabilityNamespaces, obj)
|
|
498
|
+
];
|
|
499
|
+
for (const adjudicator of adjudicators) {
|
|
500
|
+
const result = adjudicator();
|
|
501
|
+
if (result) {
|
|
502
|
+
return `${prefix} ${result}`;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return "";
|
|
506
|
+
}
|
|
507
|
+
function adjudicateMisboundNamespace(binding) {
|
|
508
|
+
return misboundNamespace(binding) ? "Cannot use namespace filter on a namespace object." : null;
|
|
509
|
+
}
|
|
510
|
+
function adjudicateMisboundDeleteWithDeletionTimestamp(binding) {
|
|
511
|
+
return misboundDeleteWithDeletionTimestamp(binding) ? "Cannot use deletionTimestamp filter on a DELETE operation." : null;
|
|
512
|
+
}
|
|
513
|
+
function adjudicateMismatchedDeletionTimestamp(binding, obj) {
|
|
514
|
+
return mismatchedDeletionTimestamp(binding, obj) ? "Binding defines deletionTimestamp but Object does not carry it." : null;
|
|
515
|
+
}
|
|
516
|
+
function adjudicateMismatchedEvent(binding, req) {
|
|
517
|
+
return mismatchedEvent(binding, req) ? `Binding defines event '${definedEvent(binding)}' but Request declares '${declaredOperation(req)}'.` : null;
|
|
518
|
+
}
|
|
519
|
+
function adjudicateMismatchedName(binding, obj) {
|
|
520
|
+
return mismatchedName(binding, obj) ? `Binding defines name '${definedName(binding)}' but Object carries '${carriedName(obj)}'.` : null;
|
|
521
|
+
}
|
|
522
|
+
function adjudicateMismatchedGroup(binding, req) {
|
|
523
|
+
return mismatchedGroup(binding, req) ? `Binding defines group '${definedGroup(binding)}' but Request declares '${declaredGroup(req)}'.` : null;
|
|
524
|
+
}
|
|
525
|
+
function adjudicateMismatchedVersion(binding, req) {
|
|
526
|
+
return mismatchedVersion(binding, req) ? `Binding defines version '${definedVersion(binding)}' but Request declares '${declaredVersion(req)}'.` : null;
|
|
527
|
+
}
|
|
528
|
+
function adjudicateMismatchedKind(binding, req) {
|
|
529
|
+
return mismatchedKind(binding, req) ? `Binding defines kind '${definedKind(binding)}' but Request declares '${declaredKind(req)}'.` : null;
|
|
530
|
+
}
|
|
531
|
+
function adjudicateUnbindableNamespaces(capabilityNamespaces, binding) {
|
|
532
|
+
return unbindableNamespaces(capabilityNamespaces, binding) ? `Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : null;
|
|
533
|
+
}
|
|
534
|
+
function adjudicateUncarryableNamespace(capabilityNamespaces, obj) {
|
|
535
|
+
return uncarryableNamespace(capabilityNamespaces, obj) ? `Object carries namespace '${obj.kind && obj.kind === "Namespace" ? obj.metadata?.name : carriedNamespace(obj)}' but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : null;
|
|
536
|
+
}
|
|
537
|
+
function adjudicateMismatchedNamespace(binding, obj) {
|
|
538
|
+
return mismatchedNamespace(binding, obj) ? `Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' but Object carries '${carriedNamespace(obj)}'.` : null;
|
|
539
|
+
}
|
|
540
|
+
function adjudicateMismatchedLabels(binding, obj) {
|
|
541
|
+
return mismatchedLabels(binding, obj) ? `Binding defines labels '${JSON.stringify(definedLabels(binding))}' but Object carries '${JSON.stringify(carriedLabels(obj))}'.` : null;
|
|
542
|
+
}
|
|
543
|
+
function adjudicateMismatchedAnnotations(binding, obj) {
|
|
544
|
+
return mismatchedAnnotations(binding, obj) ? `Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' but Object carries '${JSON.stringify(carriedAnnotations(obj))}'.` : null;
|
|
545
|
+
}
|
|
546
|
+
function adjudicateMismatchedNamespaceRegex(binding, obj) {
|
|
547
|
+
return mismatchedNamespaceRegex(binding, obj) ? `Binding defines namespace regexes '${JSON.stringify(definedNamespaceRegexes(binding))}' but Object carries '${carriedNamespace(obj)}'.` : null;
|
|
548
|
+
}
|
|
549
|
+
function adjudicateMismatchedNameRegex(binding, obj) {
|
|
550
|
+
return mismatchedNameRegex(binding, obj) ? `Binding defines name regex '${definedNameRegex(binding)}' but Object carries '${carriedName(obj)}'.` : null;
|
|
551
|
+
}
|
|
552
|
+
function adjudicateCarriesIgnoredNamespace(ignoredNamespaces, obj) {
|
|
553
|
+
return carriesIgnoredNamespace(ignoredNamespaces, obj) ? `Object carries namespace '${obj.kind && obj.kind === "Namespace" ? obj.metadata?.name : carriedNamespace(obj)}' but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.` : null;
|
|
554
|
+
}
|
|
555
|
+
function adjudicateMissingCarriableNamespace(capabilityNamespaces, obj) {
|
|
556
|
+
return missingCarriableNamespace(capabilityNamespaces, obj) ? `Object does not carry a namespace but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : null;
|
|
456
557
|
}
|
|
457
558
|
|
|
458
559
|
// src/lib/mutate-request.ts
|
|
@@ -562,80 +663,126 @@ function base64Encode(data) {
|
|
|
562
663
|
return Buffer.from(data).toString("base64");
|
|
563
664
|
}
|
|
564
665
|
|
|
565
|
-
// src/
|
|
666
|
+
// src/cli/init/enums.ts
|
|
667
|
+
var OnError = /* @__PURE__ */ ((OnError2) => {
|
|
668
|
+
OnError2["AUDIT"] = "audit";
|
|
669
|
+
OnError2["IGNORE"] = "ignore";
|
|
670
|
+
OnError2["REJECT"] = "reject";
|
|
671
|
+
return OnError2;
|
|
672
|
+
})(OnError || {});
|
|
673
|
+
|
|
674
|
+
// src/lib/processors/mutate-processor.ts
|
|
675
|
+
function updateStatus(config, name2, wrapped, status) {
|
|
676
|
+
if (wrapped.Request.operation === "DELETE") {
|
|
677
|
+
return wrapped;
|
|
678
|
+
}
|
|
679
|
+
wrapped.SetAnnotation(`${config.uuid}.pepr.dev/${name2}`, status);
|
|
680
|
+
return wrapped;
|
|
681
|
+
}
|
|
682
|
+
function logMutateErrorMessage(e) {
|
|
683
|
+
try {
|
|
684
|
+
if (e.message && e.message !== "[object Object]") {
|
|
685
|
+
return e.message;
|
|
686
|
+
} else {
|
|
687
|
+
throw new Error("An error occurred in the mutate action.");
|
|
688
|
+
}
|
|
689
|
+
} catch (e2) {
|
|
690
|
+
return "An error occurred with the mutate action.";
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
function decodeData(wrapped) {
|
|
694
|
+
let skipped = [];
|
|
695
|
+
const isSecret = wrapped.Request.kind.version === "v1" && wrapped.Request.kind.kind === "Secret";
|
|
696
|
+
if (isSecret) {
|
|
697
|
+
skipped = convertFromBase64Map(wrapped.Raw);
|
|
698
|
+
}
|
|
699
|
+
return { skipped, wrapped };
|
|
700
|
+
}
|
|
701
|
+
function reencodeData(wrapped, skipped) {
|
|
702
|
+
const transformed = (0, import_ramda3.clone)(wrapped.Raw);
|
|
703
|
+
const isSecret = wrapped.Request.kind.version === "v1" && wrapped.Request.kind.kind === "Secret";
|
|
704
|
+
if (isSecret) {
|
|
705
|
+
convertToBase64Map(transformed, skipped);
|
|
706
|
+
}
|
|
707
|
+
return transformed;
|
|
708
|
+
}
|
|
709
|
+
async function processRequest(bindable, wrapped, response) {
|
|
710
|
+
const { binding, actMeta, name: name2, config } = bindable;
|
|
711
|
+
const label = binding.mutateCallback.name;
|
|
712
|
+
logger_default.info(actMeta, `Processing mutation action (${label})`);
|
|
713
|
+
wrapped = updateStatus(config, name2, wrapped, "started");
|
|
714
|
+
try {
|
|
715
|
+
await binding.mutateCallback(wrapped);
|
|
716
|
+
logger_default.info(actMeta, `Mutation action succeeded (${label})`);
|
|
717
|
+
wrapped = updateStatus(config, name2, wrapped, "succeeded");
|
|
718
|
+
} catch (e) {
|
|
719
|
+
wrapped = updateStatus(config, name2, wrapped, "warning");
|
|
720
|
+
response.warnings = response.warnings || [];
|
|
721
|
+
const errorMessage = logMutateErrorMessage(e);
|
|
722
|
+
logger_default.error(actMeta, `Action failed: ${errorMessage}`);
|
|
723
|
+
response.warnings.push(`Action failed: ${errorMessage}`);
|
|
724
|
+
switch (config.onError) {
|
|
725
|
+
case "reject" /* REJECT */:
|
|
726
|
+
response.result = "Pepr module configured to reject on error";
|
|
727
|
+
break;
|
|
728
|
+
case "audit" /* AUDIT */:
|
|
729
|
+
response.auditAnnotations = response.auditAnnotations || {};
|
|
730
|
+
response.auditAnnotations[Date.now()] = `Action failed: ${errorMessage}`;
|
|
731
|
+
break;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
return { wrapped, response };
|
|
735
|
+
}
|
|
566
736
|
async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
567
|
-
|
|
568
|
-
const response = {
|
|
737
|
+
let response = {
|
|
569
738
|
uid: req.uid,
|
|
570
739
|
warnings: [],
|
|
571
740
|
allowed: false
|
|
572
741
|
};
|
|
573
|
-
|
|
574
|
-
let
|
|
575
|
-
const isSecret = req.kind.version === "v1" && req.kind.kind === "Secret";
|
|
576
|
-
if (isSecret) {
|
|
577
|
-
skipDecode = convertFromBase64Map(wrapped.Raw);
|
|
578
|
-
}
|
|
742
|
+
const decoded = decodeData(new PeprMutateRequest(req));
|
|
743
|
+
let wrapped = decoded.wrapped;
|
|
579
744
|
logger_default.info(reqMetadata, `Processing request`);
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
response.warnings = response.warnings || [];
|
|
611
|
-
const errorMessage = logMutateErrorMessage(e);
|
|
612
|
-
logger_default.error(actionMetadata, `Action failed: ${errorMessage}`);
|
|
613
|
-
response.warnings.push(`Action failed: ${errorMessage}`);
|
|
614
|
-
switch (config.onError) {
|
|
615
|
-
case Errors.reject:
|
|
616
|
-
logger_default.error(actionMetadata, `Action failed: ${errorMessage}`);
|
|
617
|
-
response.result = "Pepr module configured to reject on error";
|
|
618
|
-
return response;
|
|
619
|
-
case Errors.audit:
|
|
620
|
-
response.auditAnnotations = response.auditAnnotations || {};
|
|
621
|
-
response.auditAnnotations[Date.now()] = `Action failed: ${errorMessage}`;
|
|
622
|
-
break;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
745
|
+
let bindables = capabilities.flatMap(
|
|
746
|
+
(capa) => capa.bindings.map((bind) => ({
|
|
747
|
+
req,
|
|
748
|
+
config,
|
|
749
|
+
name: capa.name,
|
|
750
|
+
namespaces: capa.namespaces,
|
|
751
|
+
binding: bind,
|
|
752
|
+
actMeta: { ...reqMetadata, name: capa.name }
|
|
753
|
+
}))
|
|
754
|
+
);
|
|
755
|
+
bindables = bindables.filter((bind) => {
|
|
756
|
+
if (!bind.binding.mutateCallback) {
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
const shouldSkip = shouldSkipRequest(
|
|
760
|
+
bind.binding,
|
|
761
|
+
bind.req,
|
|
762
|
+
bind.namespaces,
|
|
763
|
+
bind.config?.alwaysIgnore?.namespaces
|
|
764
|
+
);
|
|
765
|
+
if (shouldSkip !== "") {
|
|
766
|
+
logger_default.debug(shouldSkip);
|
|
767
|
+
return false;
|
|
768
|
+
}
|
|
769
|
+
return true;
|
|
770
|
+
});
|
|
771
|
+
for (const bindable of bindables) {
|
|
772
|
+
({ wrapped, response } = await processRequest(bindable, wrapped, response));
|
|
773
|
+
if (config.onError === "reject" /* REJECT */ && response?.warnings.length > 0) {
|
|
774
|
+
return response;
|
|
625
775
|
}
|
|
626
776
|
}
|
|
627
777
|
response.allowed = true;
|
|
628
|
-
if (
|
|
778
|
+
if (bindables.length === 0) {
|
|
629
779
|
logger_default.info(reqMetadata, `No matching actions found`);
|
|
630
780
|
return response;
|
|
631
781
|
}
|
|
632
782
|
if (req.operation === "DELETE") {
|
|
633
783
|
return response;
|
|
634
784
|
}
|
|
635
|
-
const transformed = wrapped.
|
|
636
|
-
if (isSecret) {
|
|
637
|
-
convertToBase64Map(transformed, skipDecode);
|
|
638
|
-
}
|
|
785
|
+
const transformed = reencodeData(wrapped, decoded.skipped);
|
|
639
786
|
const patches = import_fast_json_patch.default.compare(req.object, transformed);
|
|
640
787
|
if (patches.length > 0) {
|
|
641
788
|
response.patchType = "JSONPatch";
|
|
@@ -647,20 +794,9 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
647
794
|
logger_default.debug({ ...reqMetadata, patches }, `Patches generated`);
|
|
648
795
|
return response;
|
|
649
796
|
}
|
|
650
|
-
var logMutateErrorMessage = (e) => {
|
|
651
|
-
try {
|
|
652
|
-
if (e.message && e.message !== "[object Object]") {
|
|
653
|
-
return e.message;
|
|
654
|
-
} else {
|
|
655
|
-
throw new Error("An error occurred in the mutate action.");
|
|
656
|
-
}
|
|
657
|
-
} catch (e2) {
|
|
658
|
-
return "An error occurred with the mutate action.";
|
|
659
|
-
}
|
|
660
|
-
};
|
|
661
797
|
|
|
662
798
|
// src/lib/validate-request.ts
|
|
663
|
-
var
|
|
799
|
+
var import_ramda4 = require("ramda");
|
|
664
800
|
var PeprValidateRequest = class {
|
|
665
801
|
Raw;
|
|
666
802
|
#input;
|
|
@@ -685,9 +821,9 @@ var PeprValidateRequest = class {
|
|
|
685
821
|
constructor(input) {
|
|
686
822
|
this.#input = input;
|
|
687
823
|
if (input.operation.toUpperCase() === "DELETE" /* DELETE */) {
|
|
688
|
-
this.Raw = (0,
|
|
824
|
+
this.Raw = (0, import_ramda4.clone)(input.oldObject);
|
|
689
825
|
} else {
|
|
690
|
-
this.Raw = (0,
|
|
826
|
+
this.Raw = (0, import_ramda4.clone)(input.object);
|
|
691
827
|
}
|
|
692
828
|
if (!this.Raw) {
|
|
693
829
|
throw new Error("unable to load the request object into PeprRequest.Raw");
|
|
@@ -737,7 +873,36 @@ var PeprValidateRequest = class {
|
|
|
737
873
|
};
|
|
738
874
|
};
|
|
739
875
|
|
|
740
|
-
// src/lib/validate-processor.ts
|
|
876
|
+
// src/lib/processors/validate-processor.ts
|
|
877
|
+
async function processRequest2(binding, actionMetadata, peprValidateRequest) {
|
|
878
|
+
const label = binding.validateCallback.name;
|
|
879
|
+
logger_default.info(actionMetadata, `Processing validation action (${label})`);
|
|
880
|
+
const valResp = {
|
|
881
|
+
uid: peprValidateRequest.Request.uid,
|
|
882
|
+
allowed: true
|
|
883
|
+
// Assume it's allowed until a validation check fails
|
|
884
|
+
};
|
|
885
|
+
try {
|
|
886
|
+
const callbackResp = await binding.validateCallback(peprValidateRequest);
|
|
887
|
+
valResp.allowed = callbackResp.allowed;
|
|
888
|
+
if (callbackResp.statusCode || callbackResp.statusMessage) {
|
|
889
|
+
valResp.status = {
|
|
890
|
+
code: callbackResp.statusCode || 400,
|
|
891
|
+
message: callbackResp.statusMessage || `Validation failed for ${name}`
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
logger_default.info(actionMetadata, `Validation action complete (${label}): ${callbackResp.allowed ? "allowed" : "denied"}`);
|
|
895
|
+
return valResp;
|
|
896
|
+
} catch (e) {
|
|
897
|
+
logger_default.error(actionMetadata, `Action failed: ${JSON.stringify(e)}`);
|
|
898
|
+
valResp.allowed = false;
|
|
899
|
+
valResp.status = {
|
|
900
|
+
code: 500,
|
|
901
|
+
message: `Action failed with error: ${JSON.stringify(e)}`
|
|
902
|
+
};
|
|
903
|
+
return valResp;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
741
906
|
async function validateProcessor(config, capabilities, req, reqMetadata) {
|
|
742
907
|
const wrapped = new PeprValidateRequest(req);
|
|
743
908
|
const response = [];
|
|
@@ -746,44 +911,19 @@ async function validateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
746
911
|
convertFromBase64Map(wrapped.Raw);
|
|
747
912
|
}
|
|
748
913
|
logger_default.info(reqMetadata, `Processing validation request`);
|
|
749
|
-
for (const { name, bindings, namespaces } of capabilities) {
|
|
750
|
-
const actionMetadata = { ...reqMetadata, name };
|
|
751
|
-
for (const
|
|
752
|
-
if (!
|
|
914
|
+
for (const { name: name2, bindings, namespaces } of capabilities) {
|
|
915
|
+
const actionMetadata = { ...reqMetadata, name: name2 };
|
|
916
|
+
for (const binding of bindings) {
|
|
917
|
+
if (!binding.validateCallback) {
|
|
753
918
|
continue;
|
|
754
919
|
}
|
|
755
|
-
const
|
|
756
|
-
uid: req.uid,
|
|
757
|
-
allowed: true
|
|
758
|
-
// Assume it's allowed until a validation check fails
|
|
759
|
-
};
|
|
760
|
-
const shouldSkip = shouldSkipRequest(action, req, namespaces, config?.alwaysIgnore?.namespaces);
|
|
920
|
+
const shouldSkip = shouldSkipRequest(binding, req, namespaces, config?.alwaysIgnore?.namespaces);
|
|
761
921
|
if (shouldSkip !== "") {
|
|
762
922
|
logger_default.debug(shouldSkip);
|
|
763
923
|
continue;
|
|
764
924
|
}
|
|
765
|
-
const
|
|
766
|
-
|
|
767
|
-
try {
|
|
768
|
-
const resp = await action.validateCallback(wrapped);
|
|
769
|
-
localResponse.allowed = resp.allowed;
|
|
770
|
-
if (resp.statusCode || resp.statusMessage) {
|
|
771
|
-
localResponse.status = {
|
|
772
|
-
code: resp.statusCode || 400,
|
|
773
|
-
message: resp.statusMessage || `Validation failed for ${name}`
|
|
774
|
-
};
|
|
775
|
-
}
|
|
776
|
-
logger_default.info(actionMetadata, `Validation action complete (${label}): ${resp.allowed ? "allowed" : "denied"}`);
|
|
777
|
-
} catch (e) {
|
|
778
|
-
logger_default.error(actionMetadata, `Action failed: ${JSON.stringify(e)}`);
|
|
779
|
-
localResponse.allowed = false;
|
|
780
|
-
localResponse.status = {
|
|
781
|
-
code: 500,
|
|
782
|
-
message: `Action failed with error: ${JSON.stringify(e)}`
|
|
783
|
-
};
|
|
784
|
-
return [localResponse];
|
|
785
|
-
}
|
|
786
|
-
response.push(localResponse);
|
|
925
|
+
const resp = await processRequest2(binding, actionMetadata, wrapped);
|
|
926
|
+
response.push(resp);
|
|
787
927
|
}
|
|
788
928
|
}
|
|
789
929
|
return response;
|
|
@@ -791,7 +931,7 @@ async function validateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
791
931
|
|
|
792
932
|
// src/lib/controller/store.ts
|
|
793
933
|
var import_kubernetes_fluent_client3 = require("kubernetes-fluent-client");
|
|
794
|
-
var
|
|
934
|
+
var import_ramda5 = require("ramda");
|
|
795
935
|
|
|
796
936
|
// src/lib/k8s.ts
|
|
797
937
|
var import_kubernetes_fluent_client = require("kubernetes-fluent-client");
|
|
@@ -807,12 +947,12 @@ var peprStoreGVK = {
|
|
|
807
947
|
// src/lib/controller/storeCache.ts
|
|
808
948
|
var import_kubernetes_fluent_client2 = require("kubernetes-fluent-client");
|
|
809
949
|
var import_http_status_codes = require("http-status-codes");
|
|
810
|
-
var sendUpdatesAndFlushCache = async (cache, namespace2,
|
|
950
|
+
var sendUpdatesAndFlushCache = async (cache, namespace2, name2) => {
|
|
811
951
|
const indexes = Object.keys(cache);
|
|
812
952
|
const payload = Object.values(cache);
|
|
813
953
|
try {
|
|
814
954
|
if (payload.length > 0) {
|
|
815
|
-
await (0, import_kubernetes_fluent_client2.K8s)(Store, { namespace: namespace2, name }).Patch(payload);
|
|
955
|
+
await (0, import_kubernetes_fluent_client2.K8s)(Store, { namespace: namespace2, name: name2 }).Patch(updateCacheID(payload));
|
|
816
956
|
Object.keys(cache).forEach((key) => delete cache[key]);
|
|
817
957
|
}
|
|
818
958
|
} catch (err) {
|
|
@@ -844,32 +984,41 @@ var fillStoreCache = (cache, capabilityName, op, cacheItem) => {
|
|
|
844
984
|
}
|
|
845
985
|
return cache;
|
|
846
986
|
};
|
|
987
|
+
function updateCacheID(payload) {
|
|
988
|
+
payload.push({
|
|
989
|
+
op: "replace",
|
|
990
|
+
path: "/metadata/labels/pepr.dev-cacheID",
|
|
991
|
+
value: `${Date.now()}`
|
|
992
|
+
});
|
|
993
|
+
return payload;
|
|
994
|
+
}
|
|
847
995
|
|
|
848
996
|
// src/lib/controller/store.ts
|
|
849
997
|
var namespace = "pepr-system";
|
|
850
|
-
var
|
|
998
|
+
var debounceBackoffReceive = 1e3;
|
|
999
|
+
var debounceBackoffSend = 4e3;
|
|
851
1000
|
var StoreController = class {
|
|
852
1001
|
#name;
|
|
853
1002
|
#stores = {};
|
|
854
1003
|
#sendDebounce;
|
|
855
1004
|
#onReady;
|
|
856
|
-
constructor(capabilities,
|
|
1005
|
+
constructor(capabilities, name2, onReady) {
|
|
857
1006
|
this.#onReady = onReady;
|
|
858
|
-
this.#name =
|
|
859
|
-
const setStorageInstance = (registrationFunction,
|
|
1007
|
+
this.#name = name2;
|
|
1008
|
+
const setStorageInstance = (registrationFunction, name3) => {
|
|
860
1009
|
const scheduleStore = registrationFunction();
|
|
861
|
-
scheduleStore.registerSender(this.#send(
|
|
862
|
-
this.#stores[
|
|
1010
|
+
scheduleStore.registerSender(this.#send(name3));
|
|
1011
|
+
this.#stores[name3] = scheduleStore;
|
|
863
1012
|
};
|
|
864
|
-
if (
|
|
865
|
-
for (const { name:
|
|
1013
|
+
if (name2.includes("schedule")) {
|
|
1014
|
+
for (const { name: name3, registerScheduleStore, hasSchedule } of capabilities) {
|
|
866
1015
|
if (hasSchedule === true) {
|
|
867
|
-
setStorageInstance(registerScheduleStore,
|
|
1016
|
+
setStorageInstance(registerScheduleStore, name3);
|
|
868
1017
|
}
|
|
869
1018
|
}
|
|
870
1019
|
} else {
|
|
871
|
-
for (const { name:
|
|
872
|
-
setStorageInstance(registerStore,
|
|
1020
|
+
for (const { name: name3, registerStore } of capabilities) {
|
|
1021
|
+
setStorageInstance(registerStore, name3);
|
|
873
1022
|
}
|
|
874
1023
|
}
|
|
875
1024
|
setTimeout(
|
|
@@ -884,17 +1033,24 @@ var StoreController = class {
|
|
|
884
1033
|
};
|
|
885
1034
|
#migrateAndSetupWatch = async (store) => {
|
|
886
1035
|
logger_default.debug(redactedStore(store), "Pepr Store migration");
|
|
1036
|
+
await (0, import_kubernetes_fluent_client3.K8s)(Store, { namespace, name: this.#name }).Patch([
|
|
1037
|
+
{
|
|
1038
|
+
op: "add",
|
|
1039
|
+
path: "/metadata/labels/pepr.dev-cacheID",
|
|
1040
|
+
value: `${Date.now()}`
|
|
1041
|
+
}
|
|
1042
|
+
]);
|
|
887
1043
|
const data = store.data || {};
|
|
888
1044
|
let storeCache = {};
|
|
889
|
-
for (const
|
|
890
|
-
const offset = `${
|
|
1045
|
+
for (const name2 of Object.keys(this.#stores)) {
|
|
1046
|
+
const offset = `${name2}-`.length;
|
|
891
1047
|
for (const key of Object.keys(data)) {
|
|
892
|
-
if ((0,
|
|
893
|
-
storeCache = fillStoreCache(storeCache,
|
|
1048
|
+
if ((0, import_ramda5.startsWith)(name2, key) && !(0, import_ramda5.startsWith)(`${name2}-v2`, key)) {
|
|
1049
|
+
storeCache = fillStoreCache(storeCache, name2, "remove", {
|
|
894
1050
|
key: [key.slice(offset)],
|
|
895
1051
|
value: data[key]
|
|
896
1052
|
});
|
|
897
|
-
storeCache = fillStoreCache(storeCache,
|
|
1053
|
+
storeCache = fillStoreCache(storeCache, name2, "add", {
|
|
898
1054
|
key: [key.slice(offset)],
|
|
899
1055
|
value: data[key],
|
|
900
1056
|
version: "v2"
|
|
@@ -909,15 +1065,15 @@ var StoreController = class {
|
|
|
909
1065
|
logger_default.debug(redactedStore(store), "Pepr Store update");
|
|
910
1066
|
const debounced = () => {
|
|
911
1067
|
const data = store.data || {};
|
|
912
|
-
for (const
|
|
913
|
-
const offset = `${
|
|
1068
|
+
for (const name2 of Object.keys(this.#stores)) {
|
|
1069
|
+
const offset = `${name2}-`.length;
|
|
914
1070
|
const filtered = {};
|
|
915
1071
|
for (const key of Object.keys(data)) {
|
|
916
|
-
if ((0,
|
|
1072
|
+
if ((0, import_ramda5.startsWith)(name2, key)) {
|
|
917
1073
|
filtered[key.slice(offset)] = data[key];
|
|
918
1074
|
}
|
|
919
1075
|
}
|
|
920
|
-
this.#stores[
|
|
1076
|
+
this.#stores[name2].receive(filtered);
|
|
921
1077
|
}
|
|
922
1078
|
if (this.#onReady) {
|
|
923
1079
|
this.#onReady();
|
|
@@ -925,7 +1081,7 @@ var StoreController = class {
|
|
|
925
1081
|
}
|
|
926
1082
|
};
|
|
927
1083
|
clearTimeout(this.#sendDebounce);
|
|
928
|
-
this.#sendDebounce = setTimeout(debounced, this.#onReady ? 0 :
|
|
1084
|
+
this.#sendDebounce = setTimeout(debounced, this.#onReady ? 0 : debounceBackoffReceive);
|
|
929
1085
|
};
|
|
930
1086
|
#send = (capabilityName) => {
|
|
931
1087
|
let storeCache = {};
|
|
@@ -937,7 +1093,7 @@ var StoreController = class {
|
|
|
937
1093
|
logger_default.debug(redactedPatch(storeCache), "Sending updates to Pepr store");
|
|
938
1094
|
void sendUpdatesAndFlushCache(storeCache, namespace, this.#name);
|
|
939
1095
|
}
|
|
940
|
-
},
|
|
1096
|
+
}, debounceBackoffSend);
|
|
941
1097
|
return sender;
|
|
942
1098
|
};
|
|
943
1099
|
#createStoreResource = async (e) => {
|
|
@@ -947,7 +1103,10 @@ var StoreController = class {
|
|
|
947
1103
|
await (0, import_kubernetes_fluent_client3.K8s)(Store).Apply({
|
|
948
1104
|
metadata: {
|
|
949
1105
|
name: this.#name,
|
|
950
|
-
namespace
|
|
1106
|
+
namespace,
|
|
1107
|
+
labels: {
|
|
1108
|
+
"pepr.dev-cacheID": `${Date.now()}`
|
|
1109
|
+
}
|
|
951
1110
|
},
|
|
952
1111
|
data: {
|
|
953
1112
|
// JSON Patch will die if the data is empty, so we need to add a placeholder
|
|
@@ -1125,12 +1284,12 @@ var Controller = class _Controller {
|
|
|
1125
1284
|
const startTime = MetricsCollector.observeStart();
|
|
1126
1285
|
try {
|
|
1127
1286
|
const request = req.body?.request || {};
|
|
1128
|
-
const { name, namespace: namespace2, gvk } = {
|
|
1287
|
+
const { name: name2, namespace: namespace2, gvk } = {
|
|
1129
1288
|
name: request?.name ? `/${request.name}` : "",
|
|
1130
1289
|
namespace: request?.namespace || "",
|
|
1131
1290
|
gvk: request?.kind || { group: "", version: "", kind: "" }
|
|
1132
1291
|
};
|
|
1133
|
-
const reqMetadata = { uid: request.uid, namespace: namespace2, name };
|
|
1292
|
+
const reqMetadata = { uid: request.uid, namespace: namespace2, name: name2 };
|
|
1134
1293
|
logger_default.info({ ...reqMetadata, gvk, operation: request.operation, admissionKind }, "Incoming request");
|
|
1135
1294
|
logger_default.debug({ ...reqMetadata, request }, "Incoming request body");
|
|
1136
1295
|
this.#beforeHook && this.#beforeHook(request || {});
|
|
@@ -1192,131 +1351,26 @@ var Controller = class _Controller {
|
|
|
1192
1351
|
}
|
|
1193
1352
|
};
|
|
1194
1353
|
|
|
1195
|
-
// src/lib/
|
|
1196
|
-
var
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
var sdk_exports = {};
|
|
1201
|
-
__export(sdk_exports, {
|
|
1202
|
-
containers: () => containers,
|
|
1203
|
-
getOwnerRefFrom: () => getOwnerRefFrom,
|
|
1204
|
-
sanitizeResourceName: () => sanitizeResourceName,
|
|
1205
|
-
writeEvent: () => writeEvent
|
|
1206
|
-
});
|
|
1207
|
-
var import_kubernetes_fluent_client4 = require("kubernetes-fluent-client");
|
|
1208
|
-
function containers(request, containerType) {
|
|
1209
|
-
const containers2 = request.Raw.spec?.containers || [];
|
|
1210
|
-
const initContainers = request.Raw.spec?.initContainers || [];
|
|
1211
|
-
const ephemeralContainers = request.Raw.spec?.ephemeralContainers || [];
|
|
1212
|
-
if (containerType === "containers") {
|
|
1213
|
-
return containers2;
|
|
1214
|
-
}
|
|
1215
|
-
if (containerType === "initContainers") {
|
|
1216
|
-
return initContainers;
|
|
1217
|
-
}
|
|
1218
|
-
if (containerType === "ephemeralContainers") {
|
|
1219
|
-
return ephemeralContainers;
|
|
1354
|
+
// src/lib/errors.ts
|
|
1355
|
+
var ErrorList = Object.values(OnError);
|
|
1356
|
+
function ValidateError(error = "") {
|
|
1357
|
+
if (!ErrorList.includes(error)) {
|
|
1358
|
+
throw new Error(`Invalid error: ${error}. Must be one of: ${ErrorList.join(", ")}`);
|
|
1220
1359
|
}
|
|
1221
|
-
return [...containers2, ...initContainers, ...ephemeralContainers];
|
|
1222
|
-
}
|
|
1223
|
-
async function writeEvent(cr, event, eventType, eventReason, reportingComponent, reportingInstance) {
|
|
1224
|
-
await (0, import_kubernetes_fluent_client4.K8s)(import_kubernetes_fluent_client4.kind.CoreEvent).Create({
|
|
1225
|
-
type: eventType,
|
|
1226
|
-
reason: eventReason,
|
|
1227
|
-
...event,
|
|
1228
|
-
// Fixed values
|
|
1229
|
-
metadata: {
|
|
1230
|
-
namespace: cr.metadata.namespace,
|
|
1231
|
-
generateName: cr.metadata.name
|
|
1232
|
-
},
|
|
1233
|
-
involvedObject: {
|
|
1234
|
-
apiVersion: cr.apiVersion,
|
|
1235
|
-
kind: cr.kind,
|
|
1236
|
-
name: cr.metadata.name,
|
|
1237
|
-
namespace: cr.metadata.namespace,
|
|
1238
|
-
uid: cr.metadata.uid
|
|
1239
|
-
},
|
|
1240
|
-
firstTimestamp: /* @__PURE__ */ new Date(),
|
|
1241
|
-
reportingComponent,
|
|
1242
|
-
reportingInstance
|
|
1243
|
-
});
|
|
1244
|
-
}
|
|
1245
|
-
function getOwnerRefFrom(customResource, blockOwnerDeletion, controller) {
|
|
1246
|
-
const { apiVersion, kind: kind3, metadata } = customResource;
|
|
1247
|
-
const { name, uid } = metadata;
|
|
1248
|
-
return [
|
|
1249
|
-
{
|
|
1250
|
-
apiVersion,
|
|
1251
|
-
kind: kind3,
|
|
1252
|
-
uid,
|
|
1253
|
-
name,
|
|
1254
|
-
...blockOwnerDeletion !== void 0 && { blockOwnerDeletion },
|
|
1255
|
-
...controller !== void 0 && { controller }
|
|
1256
|
-
}
|
|
1257
|
-
];
|
|
1258
|
-
}
|
|
1259
|
-
function sanitizeResourceName(name) {
|
|
1260
|
-
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 250).replace(/^[^a-z]+|[^a-z]+$/g, "");
|
|
1261
1360
|
}
|
|
1262
1361
|
|
|
1263
|
-
// src/lib/
|
|
1264
|
-
function filterNoMatchReason(binding, kubernetesObject, capabilityNamespaces, ignoredNamespaces) {
|
|
1265
|
-
const prefix = "Ignoring Watch Callback:";
|
|
1266
|
-
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)}'.` : "";
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
// src/lib/finalizer.ts
|
|
1362
|
+
// src/lib/processors/watch-processor.ts
|
|
1270
1363
|
var import_kubernetes_fluent_client5 = require("kubernetes-fluent-client");
|
|
1271
|
-
function addFinalizer(request) {
|
|
1272
|
-
if (request.Request.operation === "DELETE" /* DELETE */) {
|
|
1273
|
-
return;
|
|
1274
|
-
}
|
|
1275
|
-
if (request.Request.operation === "UPDATE" /* UPDATE */ && request.Raw.metadata?.deletionTimestamp) {
|
|
1276
|
-
return;
|
|
1277
|
-
}
|
|
1278
|
-
const peprFinal = "pepr.dev/finalizer";
|
|
1279
|
-
const finalizers = request.Raw.metadata?.finalizers || [];
|
|
1280
|
-
if (!finalizers.includes(peprFinal)) {
|
|
1281
|
-
finalizers.push(peprFinal);
|
|
1282
|
-
}
|
|
1283
|
-
request.Merge({ metadata: { finalizers } });
|
|
1284
|
-
}
|
|
1285
|
-
async function removeFinalizer(binding, obj) {
|
|
1286
|
-
const peprFinal = "pepr.dev/finalizer";
|
|
1287
|
-
const meta = obj.metadata;
|
|
1288
|
-
const resource = `${meta.namespace || "ClusterScoped"}/${meta.name}`;
|
|
1289
|
-
logger_default.debug({ obj }, `Removing finalizer '${peprFinal}' from '${resource}'`);
|
|
1290
|
-
const { model, kind: kind3 } = binding;
|
|
1291
|
-
try {
|
|
1292
|
-
(0, import_kubernetes_fluent_client5.RegisterKind)(model, kind3);
|
|
1293
|
-
} catch (e) {
|
|
1294
|
-
const expected = e.message === `GVK ${model.name} already registered`;
|
|
1295
|
-
if (!expected) {
|
|
1296
|
-
logger_default.error({ model, kind: kind3, error: e }, `Error registering "${kind3}" during finalization.`);
|
|
1297
|
-
return;
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
const finalizers = meta.finalizers?.filter((f) => f !== peprFinal) || [];
|
|
1301
|
-
obj = await (0, import_kubernetes_fluent_client5.K8s)(model, meta).Patch([
|
|
1302
|
-
{
|
|
1303
|
-
op: "replace",
|
|
1304
|
-
path: `/metadata/finalizers`,
|
|
1305
|
-
value: finalizers
|
|
1306
|
-
}
|
|
1307
|
-
]);
|
|
1308
|
-
logger_default.debug({ obj }, `Removed finalizer '${peprFinal}' from '${resource}'`);
|
|
1309
|
-
}
|
|
1310
1364
|
|
|
1311
|
-
// src/lib/queue.ts
|
|
1365
|
+
// src/lib/core/queue.ts
|
|
1312
1366
|
var import_node_crypto = require("node:crypto");
|
|
1313
1367
|
var Queue = class {
|
|
1314
1368
|
#name;
|
|
1315
1369
|
#uid;
|
|
1316
1370
|
#queue = [];
|
|
1317
1371
|
#pendingPromise = false;
|
|
1318
|
-
constructor(
|
|
1319
|
-
this.#name =
|
|
1372
|
+
constructor(name2) {
|
|
1373
|
+
this.#name = name2;
|
|
1320
1374
|
this.#uid = `${Date.now()}-${(0, import_node_crypto.randomBytes)(2).toString("hex")}`;
|
|
1321
1375
|
}
|
|
1322
1376
|
label() {
|
|
@@ -1396,7 +1450,52 @@ var Queue = class {
|
|
|
1396
1450
|
}
|
|
1397
1451
|
};
|
|
1398
1452
|
|
|
1399
|
-
// src/lib/watch-processor.ts
|
|
1453
|
+
// src/lib/processors/watch-processor.ts
|
|
1454
|
+
var import_types = require("kubernetes-fluent-client/dist/fluent/types");
|
|
1455
|
+
|
|
1456
|
+
// src/lib/finalizer.ts
|
|
1457
|
+
var import_kubernetes_fluent_client4 = require("kubernetes-fluent-client");
|
|
1458
|
+
function addFinalizer(request) {
|
|
1459
|
+
if (request.Request.operation === "DELETE" /* DELETE */) {
|
|
1460
|
+
return;
|
|
1461
|
+
}
|
|
1462
|
+
if (request.Request.operation === "UPDATE" /* UPDATE */ && request.Raw.metadata?.deletionTimestamp) {
|
|
1463
|
+
return;
|
|
1464
|
+
}
|
|
1465
|
+
const peprFinal = "pepr.dev/finalizer";
|
|
1466
|
+
const finalizers = request.Raw.metadata?.finalizers || [];
|
|
1467
|
+
if (!finalizers.includes(peprFinal)) {
|
|
1468
|
+
finalizers.push(peprFinal);
|
|
1469
|
+
}
|
|
1470
|
+
request.Merge({ metadata: { finalizers } });
|
|
1471
|
+
}
|
|
1472
|
+
async function removeFinalizer(binding, obj) {
|
|
1473
|
+
const peprFinal = "pepr.dev/finalizer";
|
|
1474
|
+
const meta = obj.metadata;
|
|
1475
|
+
const resource = `${meta.namespace || "ClusterScoped"}/${meta.name}`;
|
|
1476
|
+
logger_default.debug({ obj }, `Removing finalizer '${peprFinal}' from '${resource}'`);
|
|
1477
|
+
const { model, kind: kind3 } = binding;
|
|
1478
|
+
try {
|
|
1479
|
+
(0, import_kubernetes_fluent_client4.RegisterKind)(model, kind3);
|
|
1480
|
+
} catch (e) {
|
|
1481
|
+
const expected = e.message === `GVK ${model.name} already registered`;
|
|
1482
|
+
if (!expected) {
|
|
1483
|
+
logger_default.error({ model, kind: kind3, error: e }, `Error registering "${kind3}" during finalization.`);
|
|
1484
|
+
return;
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
const finalizers = meta.finalizers?.filter((f) => f !== peprFinal) || [];
|
|
1488
|
+
obj = await (0, import_kubernetes_fluent_client4.K8s)(model, meta).Patch([
|
|
1489
|
+
{
|
|
1490
|
+
op: "replace",
|
|
1491
|
+
path: `/metadata/finalizers`,
|
|
1492
|
+
value: finalizers
|
|
1493
|
+
}
|
|
1494
|
+
]);
|
|
1495
|
+
logger_default.debug({ obj }, `Removed finalizer '${peprFinal}' from '${resource}'`);
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
// src/lib/processors/watch-processor.ts
|
|
1400
1499
|
var queues = {};
|
|
1401
1500
|
function queueKey(obj) {
|
|
1402
1501
|
const options = ["kind", "kindNs", "kindNsName", "global"];
|
|
@@ -1405,11 +1504,11 @@ function queueKey(obj) {
|
|
|
1405
1504
|
strat = options.includes(strat) ? strat : d3fault;
|
|
1406
1505
|
const ns = obj.metadata?.namespace ?? "cluster-scoped";
|
|
1407
1506
|
const kind3 = obj.kind ?? "UnknownKind";
|
|
1408
|
-
const
|
|
1507
|
+
const name2 = obj.metadata?.name ?? "Unnamed";
|
|
1409
1508
|
const lookup = {
|
|
1410
1509
|
kind: `${kind3}`,
|
|
1411
1510
|
kindNs: `${kind3}/${ns}`,
|
|
1412
|
-
kindNsName: `${kind3}/${ns}/${
|
|
1511
|
+
kindNsName: `${kind3}/${ns}/${name2}`,
|
|
1413
1512
|
global: "global"
|
|
1414
1513
|
};
|
|
1415
1514
|
return lookup[strat];
|
|
@@ -1474,7 +1573,7 @@ async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
|
1474
1573
|
shouldRemoveFinalizer === false ? logger_default.debug({ obj: kubernetesObject }, `Skipping removal of finalizer '${peprFinal}' from '${resource}'`) : await removeFinalizer(binding, kubernetesObject);
|
|
1475
1574
|
}
|
|
1476
1575
|
};
|
|
1477
|
-
const watcher = (0,
|
|
1576
|
+
const watcher = (0, import_kubernetes_fluent_client5.K8s)(binding.model, binding.filters).Watch(async (obj, phase) => {
|
|
1478
1577
|
logger_default.debug(obj, `Watch event ${phase} received`);
|
|
1479
1578
|
if (binding.isQueue) {
|
|
1480
1579
|
const queue = getOrCreateQueue(obj);
|
|
@@ -1483,30 +1582,30 @@ async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
|
1483
1582
|
await watchCallback(obj, phase);
|
|
1484
1583
|
}
|
|
1485
1584
|
}, watchCfg);
|
|
1486
|
-
watcher.events.on(
|
|
1585
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.GIVE_UP, (err) => {
|
|
1487
1586
|
logger_default.error(err, "Watch failed after 5 attempts, giving up");
|
|
1488
1587
|
process.exit(1);
|
|
1489
1588
|
});
|
|
1490
|
-
watcher.events.on(
|
|
1491
|
-
watcher.events.on(
|
|
1589
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.CONNECT, (url) => logEvent(import_kubernetes_fluent_client5.WatchEvent.CONNECT, url));
|
|
1590
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.DATA_ERROR, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.DATA_ERROR, err.message));
|
|
1492
1591
|
watcher.events.on(
|
|
1493
|
-
|
|
1494
|
-
(retryCount) => logEvent(
|
|
1592
|
+
import_kubernetes_fluent_client5.WatchEvent.RECONNECT,
|
|
1593
|
+
(retryCount) => logEvent(import_kubernetes_fluent_client5.WatchEvent.RECONNECT, `Reconnecting after ${retryCount} attempt${retryCount === 1 ? "" : "s"}`)
|
|
1495
1594
|
);
|
|
1496
|
-
watcher.events.on(
|
|
1497
|
-
watcher.events.on(
|
|
1498
|
-
watcher.events.on(
|
|
1499
|
-
watcher.events.on(
|
|
1500
|
-
watcher.events.on(
|
|
1501
|
-
watcher.events.on(
|
|
1502
|
-
watcher.events.on(
|
|
1503
|
-
watcher.events.on(
|
|
1595
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.RECONNECT_PENDING, () => logEvent(import_kubernetes_fluent_client5.WatchEvent.RECONNECT_PENDING));
|
|
1596
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.GIVE_UP, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.GIVE_UP, err.message));
|
|
1597
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.ABORT, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.ABORT, err.message));
|
|
1598
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.OLD_RESOURCE_VERSION, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.OLD_RESOURCE_VERSION, err));
|
|
1599
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.NETWORK_ERROR, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.NETWORK_ERROR, err.message));
|
|
1600
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.LIST_ERROR, (err) => logEvent(import_kubernetes_fluent_client5.WatchEvent.LIST_ERROR, err.message));
|
|
1601
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.LIST, (list) => logEvent(import_kubernetes_fluent_client5.WatchEvent.LIST, JSON.stringify(list, void 0, 2)));
|
|
1602
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.CACHE_MISS, (windowName) => {
|
|
1504
1603
|
metricsCollector.incCacheMiss(windowName);
|
|
1505
1604
|
});
|
|
1506
|
-
watcher.events.on(
|
|
1605
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.INIT_CACHE_MISS, (windowName) => {
|
|
1507
1606
|
metricsCollector.initCacheMissWindow(windowName);
|
|
1508
1607
|
});
|
|
1509
|
-
watcher.events.on(
|
|
1608
|
+
watcher.events.on(import_kubernetes_fluent_client5.WatchEvent.INC_RESYNC_FAILURE_COUNT, (retryCount) => {
|
|
1510
1609
|
metricsCollector.incRetryCount(retryCount);
|
|
1511
1610
|
});
|
|
1512
1611
|
try {
|
|
@@ -1525,7 +1624,7 @@ function logEvent(event, message = "", obj) {
|
|
|
1525
1624
|
}
|
|
1526
1625
|
}
|
|
1527
1626
|
|
|
1528
|
-
// src/lib/module.ts
|
|
1627
|
+
// src/lib/core/module.ts
|
|
1529
1628
|
var isWatchMode = () => process.env.PEPR_WATCH_MODE === "true";
|
|
1530
1629
|
var isBuildMode = () => process.env.PEPR_MODE === "build";
|
|
1531
1630
|
var isDevMode = () => process.env.PEPR_MODE === "dev";
|
|
@@ -1539,7 +1638,7 @@ var PeprModule = class {
|
|
|
1539
1638
|
* @param opts Options for the Pepr runtime
|
|
1540
1639
|
*/
|
|
1541
1640
|
constructor({ description, pepr }, capabilities = [], opts = {}) {
|
|
1542
|
-
const config = (0,
|
|
1641
|
+
const config = (0, import_ramda6.clone)(pepr);
|
|
1543
1642
|
config.description = description;
|
|
1544
1643
|
ValidateError(config.onError);
|
|
1545
1644
|
if (isBuildMode()) {
|
|
@@ -1585,8 +1684,8 @@ var PeprModule = class {
|
|
|
1585
1684
|
};
|
|
1586
1685
|
};
|
|
1587
1686
|
|
|
1588
|
-
// src/lib/storage.ts
|
|
1589
|
-
var
|
|
1687
|
+
// src/lib/core/storage.ts
|
|
1688
|
+
var import_ramda7 = require("ramda");
|
|
1590
1689
|
var import_json_pointer = __toESM(require("json-pointer"));
|
|
1591
1690
|
var MAX_WAIT_TIME = 15e3;
|
|
1592
1691
|
var STORE_VERSION_PREFIX = "v2";
|
|
@@ -1609,7 +1708,7 @@ var Storage = class {
|
|
|
1609
1708
|
this.#store = data || {};
|
|
1610
1709
|
this.#onReady();
|
|
1611
1710
|
for (const idx in this.#subscribers) {
|
|
1612
|
-
this.#subscribers[idx]((0,
|
|
1711
|
+
this.#subscribers[idx]((0, import_ramda7.clone)(this.#store));
|
|
1613
1712
|
}
|
|
1614
1713
|
};
|
|
1615
1714
|
getItem = (key) => {
|
|
@@ -1641,17 +1740,19 @@ var Storage = class {
|
|
|
1641
1740
|
*/
|
|
1642
1741
|
setItemAndWait = (key, value) => {
|
|
1643
1742
|
this.#dispatchUpdate("add", [v2StoreKey(key)], value);
|
|
1743
|
+
const record = {};
|
|
1644
1744
|
return new Promise((resolve, reject) => {
|
|
1645
|
-
|
|
1745
|
+
record.timeout = setTimeout(() => {
|
|
1746
|
+
record.unsubscribe();
|
|
1747
|
+
return reject(`MAX_WAIT_TIME elapsed: Key ${key} not seen in ${MAX_WAIT_TIME / 1e3}s`);
|
|
1748
|
+
}, MAX_WAIT_TIME);
|
|
1749
|
+
record.unsubscribe = this.subscribe((data) => {
|
|
1646
1750
|
if (data[`${v2UnescapedStoreKey(key)}`] === value) {
|
|
1647
|
-
unsubscribe();
|
|
1648
|
-
|
|
1751
|
+
record.unsubscribe();
|
|
1752
|
+
clearTimeout(record.timeout);
|
|
1753
|
+
resolve("ok");
|
|
1649
1754
|
}
|
|
1650
1755
|
});
|
|
1651
|
-
setTimeout(() => {
|
|
1652
|
-
unsubscribe();
|
|
1653
|
-
return reject();
|
|
1654
|
-
}, MAX_WAIT_TIME);
|
|
1655
1756
|
});
|
|
1656
1757
|
};
|
|
1657
1758
|
/**
|
|
@@ -1663,17 +1764,19 @@ var Storage = class {
|
|
|
1663
1764
|
*/
|
|
1664
1765
|
removeItemAndWait = (key) => {
|
|
1665
1766
|
this.#dispatchUpdate("remove", [v2StoreKey(key)]);
|
|
1767
|
+
const record = {};
|
|
1666
1768
|
return new Promise((resolve, reject) => {
|
|
1667
|
-
|
|
1769
|
+
record.timeout = setTimeout(() => {
|
|
1770
|
+
record.unsubscribe();
|
|
1771
|
+
return reject(`MAX_WAIT_TIME elapsed: Key ${key} still seen after ${MAX_WAIT_TIME / 1e3}s`);
|
|
1772
|
+
}, MAX_WAIT_TIME);
|
|
1773
|
+
record.unsubscribe = this.subscribe((data) => {
|
|
1668
1774
|
if (!Object.hasOwn(data, `${v2UnescapedStoreKey(key)}`)) {
|
|
1669
|
-
unsubscribe();
|
|
1670
|
-
|
|
1775
|
+
record.unsubscribe();
|
|
1776
|
+
clearTimeout(record.timeout);
|
|
1777
|
+
resolve("ok");
|
|
1671
1778
|
}
|
|
1672
1779
|
});
|
|
1673
|
-
setTimeout(() => {
|
|
1674
|
-
unsubscribe();
|
|
1675
|
-
return reject();
|
|
1676
|
-
}, MAX_WAIT_TIME);
|
|
1677
1780
|
});
|
|
1678
1781
|
};
|
|
1679
1782
|
subscribe = (subscriber) => {
|
|
@@ -1693,7 +1796,7 @@ var Storage = class {
|
|
|
1693
1796
|
};
|
|
1694
1797
|
#onReady = () => {
|
|
1695
1798
|
for (const handler of this.#readyHandlers) {
|
|
1696
|
-
handler((0,
|
|
1799
|
+
handler((0, import_ramda7.clone)(this.#store));
|
|
1697
1800
|
}
|
|
1698
1801
|
this.#onReady = () => {
|
|
1699
1802
|
};
|
|
@@ -1709,7 +1812,7 @@ var Storage = class {
|
|
|
1709
1812
|
};
|
|
1710
1813
|
};
|
|
1711
1814
|
|
|
1712
|
-
// src/lib/schedule.ts
|
|
1815
|
+
// src/lib/core/schedule.ts
|
|
1713
1816
|
var OnSchedule = class {
|
|
1714
1817
|
intervalId = null;
|
|
1715
1818
|
store;
|
|
@@ -1837,7 +1940,7 @@ var OnSchedule = class {
|
|
|
1837
1940
|
}
|
|
1838
1941
|
};
|
|
1839
1942
|
|
|
1840
|
-
// src/lib/capability.ts
|
|
1943
|
+
// src/lib/core/capability.ts
|
|
1841
1944
|
var registerAdmission = isBuildMode() || !isWatchMode();
|
|
1842
1945
|
var registerWatch = isBuildMode() || isWatchMode() || isDevMode();
|
|
1843
1946
|
var Capability = class {
|
|
@@ -1857,11 +1960,11 @@ var Capability = class {
|
|
|
1857
1960
|
* @returns
|
|
1858
1961
|
*/
|
|
1859
1962
|
OnSchedule = (schedule) => {
|
|
1860
|
-
const { name, every, unit, run, startTime, completions } = schedule;
|
|
1963
|
+
const { name: name2, every, unit, run, startTime, completions } = schedule;
|
|
1861
1964
|
this.hasSchedule = true;
|
|
1862
1965
|
if (process.env.PEPR_WATCH_MODE === "true" || process.env.PEPR_MODE === "dev") {
|
|
1863
1966
|
const newSchedule = {
|
|
1864
|
-
name,
|
|
1967
|
+
name: name2,
|
|
1865
1968
|
every,
|
|
1866
1969
|
unit,
|
|
1867
1970
|
run,
|
|
@@ -1964,7 +2067,7 @@ var Capability = class {
|
|
|
1964
2067
|
* @returns
|
|
1965
2068
|
*/
|
|
1966
2069
|
When = (model, kind3) => {
|
|
1967
|
-
const matchedKind = (0,
|
|
2070
|
+
const matchedKind = (0, import_kubernetes_fluent_client6.modelToGroupVersionKind)(model.name);
|
|
1968
2071
|
if (!matchedKind && !kind3) {
|
|
1969
2072
|
throw new Error(`Kind not specified for ${model.name}`);
|
|
1970
2073
|
}
|
|
@@ -1988,7 +2091,7 @@ var Capability = class {
|
|
|
1988
2091
|
const commonChain = { WithLabel, WithAnnotation, WithDeletionTimestamp, Mutate, Validate, Watch, Reconcile, Alias };
|
|
1989
2092
|
const isNotEmpty = (value) => Object.keys(value).length > 0;
|
|
1990
2093
|
const log = (message, cbString) => {
|
|
1991
|
-
const filteredObj = (0,
|
|
2094
|
+
const filteredObj = (0, import_ramda8.pickBy)(isNotEmpty, binding.filters);
|
|
1992
2095
|
logger_default.info(`${message} configured for ${binding.event}`, prefix);
|
|
1993
2096
|
logger_default.info(filteredObj, prefix);
|
|
1994
2097
|
logger_default.debug(cbString, prefix);
|
|
@@ -2101,9 +2204,9 @@ var Capability = class {
|
|
|
2101
2204
|
binding.filters.regexName = regexName.source;
|
|
2102
2205
|
return commonChain;
|
|
2103
2206
|
}
|
|
2104
|
-
function WithName(
|
|
2105
|
-
logger_default.debug(`Add name filter ${
|
|
2106
|
-
binding.filters.name =
|
|
2207
|
+
function WithName(name2) {
|
|
2208
|
+
logger_default.debug(`Add name filter ${name2}`, prefix);
|
|
2209
|
+
binding.filters.name = name2;
|
|
2107
2210
|
return commonChain;
|
|
2108
2211
|
}
|
|
2109
2212
|
function WithLabel(key, value = "") {
|
|
@@ -2141,6 +2244,70 @@ var Capability = class {
|
|
|
2141
2244
|
};
|
|
2142
2245
|
};
|
|
2143
2246
|
};
|
|
2247
|
+
|
|
2248
|
+
// src/sdk/sdk.ts
|
|
2249
|
+
var sdk_exports = {};
|
|
2250
|
+
__export(sdk_exports, {
|
|
2251
|
+
containers: () => containers,
|
|
2252
|
+
getOwnerRefFrom: () => getOwnerRefFrom,
|
|
2253
|
+
sanitizeResourceName: () => sanitizeResourceName,
|
|
2254
|
+
writeEvent: () => writeEvent
|
|
2255
|
+
});
|
|
2256
|
+
var import_kubernetes_fluent_client7 = require("kubernetes-fluent-client");
|
|
2257
|
+
function containers(request, containerType) {
|
|
2258
|
+
const containers2 = request.Raw.spec?.containers || [];
|
|
2259
|
+
const initContainers = request.Raw.spec?.initContainers || [];
|
|
2260
|
+
const ephemeralContainers = request.Raw.spec?.ephemeralContainers || [];
|
|
2261
|
+
if (containerType === "containers") {
|
|
2262
|
+
return containers2;
|
|
2263
|
+
}
|
|
2264
|
+
if (containerType === "initContainers") {
|
|
2265
|
+
return initContainers;
|
|
2266
|
+
}
|
|
2267
|
+
if (containerType === "ephemeralContainers") {
|
|
2268
|
+
return ephemeralContainers;
|
|
2269
|
+
}
|
|
2270
|
+
return [...containers2, ...initContainers, ...ephemeralContainers];
|
|
2271
|
+
}
|
|
2272
|
+
async function writeEvent(cr, event, eventType, eventReason, reportingComponent, reportingInstance) {
|
|
2273
|
+
await (0, import_kubernetes_fluent_client7.K8s)(import_kubernetes_fluent_client7.kind.CoreEvent).Create({
|
|
2274
|
+
type: eventType,
|
|
2275
|
+
reason: eventReason,
|
|
2276
|
+
...event,
|
|
2277
|
+
// Fixed values
|
|
2278
|
+
metadata: {
|
|
2279
|
+
namespace: cr.metadata.namespace,
|
|
2280
|
+
generateName: cr.metadata.name
|
|
2281
|
+
},
|
|
2282
|
+
involvedObject: {
|
|
2283
|
+
apiVersion: cr.apiVersion,
|
|
2284
|
+
kind: cr.kind,
|
|
2285
|
+
name: cr.metadata.name,
|
|
2286
|
+
namespace: cr.metadata.namespace,
|
|
2287
|
+
uid: cr.metadata.uid
|
|
2288
|
+
},
|
|
2289
|
+
firstTimestamp: /* @__PURE__ */ new Date(),
|
|
2290
|
+
reportingComponent,
|
|
2291
|
+
reportingInstance
|
|
2292
|
+
});
|
|
2293
|
+
}
|
|
2294
|
+
function getOwnerRefFrom(customResource, blockOwnerDeletion, controller) {
|
|
2295
|
+
const { apiVersion, kind: kind3, metadata } = customResource;
|
|
2296
|
+
const { name: name2, uid } = metadata;
|
|
2297
|
+
return [
|
|
2298
|
+
{
|
|
2299
|
+
apiVersion,
|
|
2300
|
+
kind: kind3,
|
|
2301
|
+
uid,
|
|
2302
|
+
name: name2,
|
|
2303
|
+
...blockOwnerDeletion !== void 0 && { blockOwnerDeletion },
|
|
2304
|
+
...controller !== void 0 && { controller }
|
|
2305
|
+
}
|
|
2306
|
+
];
|
|
2307
|
+
}
|
|
2308
|
+
function sanitizeResourceName(name2) {
|
|
2309
|
+
return name2.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 250).replace(/^[^a-z]+|[^a-z]+$/g, "");
|
|
2310
|
+
}
|
|
2144
2311
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2145
2312
|
0 && (module.exports = {
|
|
2146
2313
|
Capability,
|