pepr 0.38.3 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/build.d.ts +1 -1
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.helpers.d.ts +19 -0
- package/dist/cli/build.helpers.d.ts.map +1 -0
- package/dist/cli/deploy.d.ts.map +1 -1
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/init/index.d.ts.map +1 -1
- package/dist/cli/init/templates.d.ts +6 -2
- package/dist/cli/init/templates.d.ts.map +1 -1
- package/dist/cli/monitor.d.ts.map +1 -1
- package/dist/cli.js +278 -225
- package/dist/controller.js +37 -27
- package/dist/lib/assets/deploy.d.ts.map +1 -1
- package/dist/lib/assets/helm.d.ts +1 -0
- 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/rbac.d.ts +31 -4
- package/dist/lib/assets/rbac.d.ts.map +1 -1
- package/dist/lib/assets/yaml.d.ts +2 -2
- package/dist/lib/assets/yaml.d.ts.map +1 -1
- package/dist/lib/capability.d.ts +2 -8
- package/dist/lib/capability.d.ts.map +1 -1
- package/dist/lib/controller/store.d.ts +1 -5
- package/dist/lib/controller/store.d.ts.map +1 -1
- package/dist/lib/controller/storeCache.d.ts +11 -0
- package/dist/lib/controller/storeCache.d.ts.map +1 -0
- package/dist/lib/enums.d.ts +17 -0
- package/dist/lib/enums.d.ts.map +1 -0
- package/dist/lib/{adjudicators.d.ts → filter/adjudicators.d.ts} +15 -13
- package/dist/lib/filter/adjudicators.d.ts.map +1 -0
- package/dist/lib/{filter.d.ts → filter/filter.d.ts} +1 -1
- package/dist/lib/filter/filter.d.ts.map +1 -0
- package/dist/lib/helpers.d.ts +1 -2
- package/dist/lib/helpers.d.ts.map +1 -1
- package/dist/lib/k8s.d.ts +1 -1
- package/dist/lib/k8s.d.ts.map +1 -1
- package/dist/lib/logger.d.ts +4 -0
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/metrics.d.ts.map +1 -1
- package/dist/lib/module.d.ts +5 -0
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/mutate-processor.d.ts.map +1 -1
- package/dist/lib/mutate-request.d.ts +1 -60
- package/dist/lib/mutate-request.d.ts.map +1 -1
- package/dist/lib/types.d.ts +8 -24
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/validate-request.d.ts.map +1 -1
- package/dist/lib/watch-processor.d.ts.map +1 -1
- package/dist/lib.js +220 -295
- package/dist/lib.js.map +4 -4
- package/dist/sdk/cosign.d.ts +18 -0
- package/dist/sdk/cosign.d.ts.map +1 -0
- package/dist/sdk/heredoc.d.ts +2 -0
- package/dist/sdk/heredoc.d.ts.map +1 -0
- package/dist/sdk/sdk.d.ts +1 -2
- package/dist/sdk/sdk.d.ts.map +1 -1
- package/package.json +11 -7
- package/src/cli/build.helpers.ts +28 -0
- package/src/cli/build.ts +124 -121
- package/src/cli/deploy.ts +27 -24
- package/src/cli/dev.ts +3 -3
- package/src/cli/format.ts +3 -6
- package/src/cli/init/index.ts +23 -19
- package/src/cli/monitor.ts +34 -36
- package/src/lib/assets/deploy.ts +12 -3
- package/src/lib/assets/helm.ts +14 -0
- package/src/lib/assets/index.ts +12 -8
- package/src/lib/assets/rbac.ts +69 -17
- package/src/lib/assets/webhooks.ts +1 -1
- package/src/lib/assets/yaml.ts +8 -4
- package/src/lib/capability.ts +7 -12
- package/src/lib/controller/index.ts +3 -3
- package/src/lib/controller/store.ts +42 -202
- package/src/lib/controller/storeCache.ts +63 -0
- package/src/lib/enums.ts +21 -0
- package/src/lib/{adjudicators.ts → filter/adjudicators.ts} +39 -28
- package/src/lib/{filter.ts → filter/filter.ts} +3 -2
- package/src/lib/finalizer.ts +1 -1
- package/src/lib/helpers.ts +19 -15
- package/src/lib/k8s.ts +2 -2
- package/src/lib/logger.ts +41 -0
- package/src/lib/metrics.ts +3 -1
- package/src/lib/module.ts +5 -0
- package/src/lib/mutate-processor.ts +14 -12
- package/src/lib/mutate-request.ts +4 -69
- package/src/lib/types.ts +9 -28
- package/src/lib/validate-processor.ts +1 -1
- package/src/lib/validate-request.ts +2 -1
- package/src/lib/watch-processor.ts +34 -20
- package/src/sdk/cosign.ts +327 -0
- package/src/sdk/heredoc.ts +36 -0
- package/src/sdk/sdk.ts +1 -2
- package/dist/lib/adjudicators.d.ts.map +0 -1
- package/dist/lib/filter.d.ts.map +0 -1
package/dist/lib.js
CHANGED
|
@@ -31,31 +31,32 @@ 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_client9.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_client9.RegisterKind,
|
|
42
|
+
a: () => import_kubernetes_fluent_client9.kind,
|
|
43
|
+
fetch: () => import_kubernetes_fluent_client9.fetch,
|
|
44
|
+
fetchStatus: () => import_kubernetes_fluent_client9.fetchStatus,
|
|
45
|
+
kind: () => import_kubernetes_fluent_client9.kind,
|
|
46
46
|
sdk: () => sdk_exports
|
|
47
47
|
});
|
|
48
48
|
module.exports = __toCommonJS(lib_exports);
|
|
49
|
-
var
|
|
49
|
+
var import_kubernetes_fluent_client9 = 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_client8 = require("kubernetes-fluent-client");
|
|
54
54
|
var import_ramda7 = require("ramda");
|
|
55
55
|
|
|
56
56
|
// src/lib/logger.ts
|
|
57
57
|
var import_pino = require("pino");
|
|
58
58
|
var isPrettyLog = process.env.PEPR_PRETTY_LOGS === "true";
|
|
59
|
+
var redactedValue = "**redacted**";
|
|
59
60
|
var pretty = {
|
|
60
61
|
target: "pino-pretty",
|
|
61
62
|
options: {
|
|
@@ -71,6 +72,33 @@ var Log = (0, import_pino.pino)({
|
|
|
71
72
|
if (process.env.LOG_LEVEL) {
|
|
72
73
|
Log.level = process.env.LOG_LEVEL;
|
|
73
74
|
}
|
|
75
|
+
function redactedStore(store) {
|
|
76
|
+
const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
|
|
77
|
+
return {
|
|
78
|
+
...store,
|
|
79
|
+
data: Object.keys(store.data).reduce((acc, key) => {
|
|
80
|
+
acc[key] = redacted ? redactedValue : store.data[key];
|
|
81
|
+
return acc;
|
|
82
|
+
}, {})
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function redactedPatch(patch = {}) {
|
|
86
|
+
const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
|
|
87
|
+
if (!redacted) {
|
|
88
|
+
return patch;
|
|
89
|
+
}
|
|
90
|
+
const redactedCache = {};
|
|
91
|
+
Object.entries(patch).forEach(([key, operation]) => {
|
|
92
|
+
const isRedacted = key.includes(":");
|
|
93
|
+
const targetKey = isRedacted ? `${key.substring(0, key.lastIndexOf(":"))}:**redacted**` : key;
|
|
94
|
+
const redactedOperation = isRedacted ? {
|
|
95
|
+
...operation,
|
|
96
|
+
...Object.hasOwn(operation, "value") ? { value: redactedValue } : {}
|
|
97
|
+
} : operation;
|
|
98
|
+
redactedCache[targetKey] = redactedOperation;
|
|
99
|
+
});
|
|
100
|
+
return redactedCache;
|
|
101
|
+
}
|
|
74
102
|
var logger_default = Log;
|
|
75
103
|
|
|
76
104
|
// src/lib/module.ts
|
|
@@ -201,7 +229,9 @@ var MetricsCollector = class {
|
|
|
201
229
|
const maxCacheMissWindows = process.env.PEPR_MAX_CACHE_MISS_WINDOWS ? parseInt(process.env.PEPR_MAX_CACHE_MISS_WINDOWS, 10) : void 0;
|
|
202
230
|
if (maxCacheMissWindows !== void 0 && this.#cacheMissWindows.size >= maxCacheMissWindows) {
|
|
203
231
|
const firstKey = this.#cacheMissWindows.keys().next().value;
|
|
204
|
-
|
|
232
|
+
if (firstKey !== void 0) {
|
|
233
|
+
this.#cacheMissWindows.delete(firstKey);
|
|
234
|
+
}
|
|
205
235
|
this.#gauges.get(this.#getMetricName(this.#metricNames.cacheMiss))?.remove({ window: firstKey });
|
|
206
236
|
}
|
|
207
237
|
};
|
|
@@ -224,23 +254,28 @@ function ValidateError(error = "") {
|
|
|
224
254
|
}
|
|
225
255
|
}
|
|
226
256
|
|
|
227
|
-
// src/lib/adjudicators.ts
|
|
257
|
+
// src/lib/filter/adjudicators.ts
|
|
228
258
|
var import_ramda = require("ramda");
|
|
229
259
|
var declaredOperation = (0, import_ramda.pipe)((request) => request?.operation, (0, import_ramda.defaultTo)(""));
|
|
230
260
|
var declaredGroup = (0, import_ramda.pipe)((request) => request?.kind?.group, (0, import_ramda.defaultTo)(""));
|
|
231
261
|
var declaredVersion = (0, import_ramda.pipe)((request) => request?.kind?.version, (0, import_ramda.defaultTo)(""));
|
|
232
262
|
var declaredKind = (0, import_ramda.pipe)((request) => request?.kind?.kind, (0, import_ramda.defaultTo)(""));
|
|
233
263
|
var declaredUid = (0, import_ramda.pipe)((request) => request?.uid, (0, import_ramda.defaultTo)(""));
|
|
234
|
-
var carriesDeletionTimestamp = (0, import_ramda.pipe)(
|
|
264
|
+
var carriesDeletionTimestamp = (0, import_ramda.pipe)(
|
|
265
|
+
(kubernetesObject) => !!kubernetesObject.metadata?.deletionTimestamp,
|
|
266
|
+
(0, import_ramda.defaultTo)(false)
|
|
267
|
+
);
|
|
235
268
|
var missingDeletionTimestamp = (0, import_ramda.complement)(carriesDeletionTimestamp);
|
|
236
|
-
var
|
|
269
|
+
var carriedKind = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.kind, (0, import_ramda.defaultTo)("not set"));
|
|
270
|
+
var carriedVersion = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.version, (0, import_ramda.defaultTo)("not set"));
|
|
271
|
+
var carriedName = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.name, (0, import_ramda.defaultTo)(""));
|
|
237
272
|
var carriesName = (0, import_ramda.pipe)(carriedName, (0, import_ramda.equals)(""), import_ramda.not);
|
|
238
273
|
var missingName = (0, import_ramda.complement)(carriesName);
|
|
239
|
-
var carriedNamespace = (0, import_ramda.pipe)((
|
|
274
|
+
var carriedNamespace = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.namespace, (0, import_ramda.defaultTo)(""));
|
|
240
275
|
var carriesNamespace = (0, import_ramda.pipe)(carriedNamespace, (0, import_ramda.equals)(""), import_ramda.not);
|
|
241
|
-
var carriedAnnotations = (0, import_ramda.pipe)((
|
|
276
|
+
var carriedAnnotations = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.annotations, (0, import_ramda.defaultTo)({}));
|
|
242
277
|
var carriesAnnotations = (0, import_ramda.pipe)(carriedAnnotations, (0, import_ramda.equals)({}), import_ramda.not);
|
|
243
|
-
var carriedLabels = (0, import_ramda.pipe)((
|
|
278
|
+
var carriedLabels = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.labels, (0, import_ramda.defaultTo)({}));
|
|
244
279
|
var carriesLabels = (0, import_ramda.pipe)(carriedLabels, (0, import_ramda.equals)({}), import_ramda.not);
|
|
245
280
|
var definesDeletionTimestamp = (0, import_ramda.pipe)((binding) => binding?.filters?.deletionTimestamp, (0, import_ramda.defaultTo)(false));
|
|
246
281
|
var ignoresDeletionTimestamp = (0, import_ramda.complement)(definesDeletionTimestamp);
|
|
@@ -271,46 +306,46 @@ var definedCategory = (0, import_ramda.pipe)((binding) => {
|
|
|
271
306
|
var definedCallback = (0, import_ramda.pipe)((binding) => {
|
|
272
307
|
return binding.isFinalize ? binding.finalizeCallback : binding.isWatch ? binding.watchCallback : binding.isMutate ? binding.mutateCallback : binding.isValidate ? binding.validateCallback : null;
|
|
273
308
|
});
|
|
274
|
-
var definedCallbackName = (0, import_ramda.pipe)(definedCallback, (0, import_ramda.defaultTo)({ name: "" }), (
|
|
309
|
+
var definedCallbackName = (0, import_ramda.pipe)(definedCallback, (0, import_ramda.defaultTo)({ name: "" }), (callback) => callback.name);
|
|
275
310
|
var mismatchedDeletionTimestamp = (0, import_ramda.allPass)([
|
|
276
311
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesDeletionTimestamp),
|
|
277
312
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), missingDeletionTimestamp)
|
|
278
313
|
]);
|
|
279
314
|
var mismatchedName = (0, import_ramda.allPass)([
|
|
280
315
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesName),
|
|
281
|
-
(0, import_ramda.pipe)((
|
|
316
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => definedName(binding) !== carriedName(kubernetesObject))
|
|
282
317
|
]);
|
|
283
318
|
var mismatchedNameRegex = (0, import_ramda.allPass)([
|
|
284
319
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNameRegex),
|
|
285
|
-
(0, import_ramda.pipe)((
|
|
320
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => new RegExp(definedNameRegex(binding)).test(carriedName(kubernetesObject)), import_ramda.not)
|
|
286
321
|
]);
|
|
287
322
|
var bindsToKind = (0, import_ramda.curry)(
|
|
288
|
-
(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)((
|
|
323
|
+
(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, kind4) => definedKind(binding) === kind4)])
|
|
289
324
|
);
|
|
290
325
|
var bindsToNamespace = (0, import_ramda.curry)((0, import_ramda.pipe)(bindsToKind(import_ramda.__, "Namespace")));
|
|
291
326
|
var misboundNamespace = (0, import_ramda.allPass)([bindsToNamespace, definesNamespaces]);
|
|
292
327
|
var mismatchedNamespace = (0, import_ramda.allPass)([
|
|
293
328
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNamespaces),
|
|
294
|
-
(0, import_ramda.pipe)((
|
|
329
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => definedNamespaces(binding).includes(carriedNamespace(kubernetesObject)), import_ramda.not)
|
|
295
330
|
]);
|
|
296
331
|
var mismatchedNamespaceRegex = (0, import_ramda.allPass)([
|
|
297
332
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNamespaceRegexes),
|
|
298
333
|
(0, import_ramda.pipe)(
|
|
299
|
-
(
|
|
300
|
-
(0, import_ramda.any)((
|
|
334
|
+
(binding, kubernetesObject) => (0, import_ramda.pipe)(
|
|
335
|
+
(0, import_ramda.any)((regEx) => new RegExp(regEx).test(carriedNamespace(kubernetesObject))),
|
|
301
336
|
import_ramda.not
|
|
302
|
-
)(definedNamespaceRegexes(
|
|
337
|
+
)(definedNamespaceRegexes(binding))
|
|
303
338
|
)
|
|
304
339
|
]);
|
|
305
340
|
var metasMismatch = (0, import_ramda.pipe)(
|
|
306
341
|
(defined, carried) => {
|
|
307
342
|
const result = { defined, carried, unalike: {} };
|
|
308
|
-
result.unalike = Object.entries(result.defined).map(([key,
|
|
343
|
+
result.unalike = Object.entries(result.defined).map(([key, value]) => {
|
|
309
344
|
const keyMissing = !Object.hasOwn(result.carried, key);
|
|
310
|
-
const noValue = !
|
|
345
|
+
const noValue = !value;
|
|
311
346
|
const valMissing = !result.carried[key];
|
|
312
347
|
const valDiffers = result.carried[key] !== result.defined[key];
|
|
313
|
-
return keyMissing ? { [key]:
|
|
348
|
+
return keyMissing ? { [key]: value } : noValue ? {} : valMissing ? { [key]: value } : valDiffers ? { [key]: value } : {};
|
|
314
349
|
}).reduce((acc, cur) => ({ ...acc, ...cur }), {});
|
|
315
350
|
return result.unalike;
|
|
316
351
|
},
|
|
@@ -318,32 +353,37 @@ var metasMismatch = (0, import_ramda.pipe)(
|
|
|
318
353
|
);
|
|
319
354
|
var mismatchedAnnotations = (0, import_ramda.allPass)([
|
|
320
355
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesAnnotations),
|
|
321
|
-
(0, import_ramda.pipe)((
|
|
356
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => metasMismatch(definedAnnotations(binding), carriedAnnotations(kubernetesObject)))
|
|
322
357
|
]);
|
|
323
358
|
var mismatchedLabels = (0, import_ramda.allPass)([
|
|
324
359
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesLabels),
|
|
325
|
-
(0, import_ramda.pipe)((
|
|
360
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => metasMismatch(definedLabels(binding), carriedLabels(kubernetesObject)))
|
|
326
361
|
]);
|
|
327
362
|
var uncarryableNamespace = (0, import_ramda.allPass)([
|
|
328
363
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
329
364
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), carriesNamespace),
|
|
330
|
-
(0, import_ramda.pipe)((
|
|
365
|
+
(0, import_ramda.pipe)((namespaceSelector, kubernetesObject) => namespaceSelector.includes(carriedNamespace(kubernetesObject)), import_ramda.not)
|
|
331
366
|
]);
|
|
332
367
|
var carriesIgnoredNamespace = (0, import_ramda.allPass)([
|
|
333
368
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
334
369
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), carriesNamespace),
|
|
335
|
-
(0, import_ramda.pipe)((
|
|
370
|
+
(0, import_ramda.pipe)((namespaceSelector, kubernetesObject) => namespaceSelector.includes(carriedNamespace(kubernetesObject)))
|
|
336
371
|
]);
|
|
337
372
|
var unbindableNamespaces = (0, import_ramda.allPass)([
|
|
338
373
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
339
374
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), definesNamespaces),
|
|
340
|
-
(0, import_ramda.pipe)(
|
|
375
|
+
(0, import_ramda.pipe)(
|
|
376
|
+
(namespaceSelector, binding) => (0, import_ramda.difference)(definedNamespaces(binding), namespaceSelector),
|
|
377
|
+
import_ramda.length,
|
|
378
|
+
(0, import_ramda.equals)(0),
|
|
379
|
+
import_ramda.not
|
|
380
|
+
)
|
|
341
381
|
]);
|
|
342
382
|
var misboundDeleteWithDeletionTimestamp = (0, import_ramda.allPass)([definesDelete, definesDeletionTimestamp]);
|
|
343
383
|
var operationMatchesEvent = (0, import_ramda.anyPass)([
|
|
344
384
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), (0, import_ramda.equals)("*" /* Any */)),
|
|
345
|
-
(0, import_ramda.pipe)((
|
|
346
|
-
(0, import_ramda.pipe)((
|
|
385
|
+
(0, import_ramda.pipe)((operation, event) => operation === event),
|
|
386
|
+
(0, import_ramda.pipe)((operation, event) => operation ? event.includes(operation) : false)
|
|
347
387
|
]);
|
|
348
388
|
var mismatchedEvent = (0, import_ramda.pipe)(
|
|
349
389
|
(binding, request) => operationMatchesEvent(declaredOperation(request), definedEvent(binding)),
|
|
@@ -362,7 +402,7 @@ var mismatchedKind = (0, import_ramda.allPass)([
|
|
|
362
402
|
(0, import_ramda.pipe)((binding, request) => definedKind(binding) !== declaredKind(request))
|
|
363
403
|
]);
|
|
364
404
|
|
|
365
|
-
// src/lib/filter.ts
|
|
405
|
+
// src/lib/filter/filter.ts
|
|
366
406
|
function shouldSkipRequest(binding, req, capabilityNamespaces, ignoredNamespaces) {
|
|
367
407
|
const prefix = "Ignoring Admission Callback:";
|
|
368
408
|
const obj = req.operation === "DELETE" /* DELETE */ ? req.oldObject : req.object;
|
|
@@ -377,31 +417,15 @@ var PeprMutateRequest = class {
|
|
|
377
417
|
get PermitSideEffects() {
|
|
378
418
|
return !this.#input.dryRun;
|
|
379
419
|
}
|
|
380
|
-
/**
|
|
381
|
-
* Indicates whether the request is a dry run.
|
|
382
|
-
* @returns true if the request is a dry run, false otherwise.
|
|
383
|
-
*/
|
|
384
420
|
get IsDryRun() {
|
|
385
421
|
return this.#input.dryRun;
|
|
386
422
|
}
|
|
387
|
-
/**
|
|
388
|
-
* Provides access to the old resource in the request if available.
|
|
389
|
-
* @returns The old Kubernetes resource object or null if not available.
|
|
390
|
-
*/
|
|
391
423
|
get OldResource() {
|
|
392
424
|
return this.#input.oldObject;
|
|
393
425
|
}
|
|
394
|
-
/**
|
|
395
|
-
* Provides access to the request object.
|
|
396
|
-
* @returns The request object containing the Kubernetes resource.
|
|
397
|
-
*/
|
|
398
426
|
get Request() {
|
|
399
427
|
return this.#input;
|
|
400
428
|
}
|
|
401
|
-
/**
|
|
402
|
-
* Creates a new instance of the action class.
|
|
403
|
-
* @param input - The request object containing the Kubernetes resource to modify.
|
|
404
|
-
*/
|
|
405
429
|
constructor(input) {
|
|
406
430
|
this.#input = input;
|
|
407
431
|
if (input.operation.toUpperCase() === "DELETE" /* DELETE */) {
|
|
@@ -410,23 +434,12 @@ var PeprMutateRequest = class {
|
|
|
410
434
|
this.Raw = (0, import_ramda2.clone)(input.object);
|
|
411
435
|
}
|
|
412
436
|
if (!this.Raw) {
|
|
413
|
-
throw new Error("
|
|
437
|
+
throw new Error("Unable to load the request object into PeprRequest.Raw");
|
|
414
438
|
}
|
|
415
439
|
}
|
|
416
|
-
/**
|
|
417
|
-
* Deep merges the provided object with the current resource.
|
|
418
|
-
*
|
|
419
|
-
* @param obj - The object to merge with the current resource.
|
|
420
|
-
*/
|
|
421
440
|
Merge = (obj) => {
|
|
422
441
|
this.Raw = (0, import_ramda2.mergeDeepRight)(this.Raw, obj);
|
|
423
442
|
};
|
|
424
|
-
/**
|
|
425
|
-
* Updates a label on the Kubernetes resource.
|
|
426
|
-
* @param key - The key of the label to update.
|
|
427
|
-
* @param value - The value of the label.
|
|
428
|
-
* @returns The current action instance for method chaining.
|
|
429
|
-
*/
|
|
430
443
|
SetLabel = (key, value) => {
|
|
431
444
|
const ref = this.Raw;
|
|
432
445
|
ref.metadata = ref.metadata ?? {};
|
|
@@ -434,12 +447,6 @@ var PeprMutateRequest = class {
|
|
|
434
447
|
ref.metadata.labels[key] = value;
|
|
435
448
|
return this;
|
|
436
449
|
};
|
|
437
|
-
/**
|
|
438
|
-
* Updates an annotation on the Kubernetes resource.
|
|
439
|
-
* @param key - The key of the annotation to update.
|
|
440
|
-
* @param value - The value of the annotation.
|
|
441
|
-
* @returns The current action instance for method chaining.
|
|
442
|
-
*/
|
|
443
450
|
SetAnnotation = (key, value) => {
|
|
444
451
|
const ref = this.Raw;
|
|
445
452
|
ref.metadata = ref.metadata ?? {};
|
|
@@ -447,43 +454,21 @@ var PeprMutateRequest = class {
|
|
|
447
454
|
ref.metadata.annotations[key] = value;
|
|
448
455
|
return this;
|
|
449
456
|
};
|
|
450
|
-
/**
|
|
451
|
-
* Removes a label from the Kubernetes resource.
|
|
452
|
-
* @param key - The key of the label to remove.
|
|
453
|
-
* @returns The current Action instance for method chaining.
|
|
454
|
-
*/
|
|
455
457
|
RemoveLabel = (key) => {
|
|
456
458
|
if (this.Raw.metadata?.labels?.[key]) {
|
|
457
459
|
delete this.Raw.metadata.labels[key];
|
|
458
460
|
}
|
|
459
461
|
return this;
|
|
460
462
|
};
|
|
461
|
-
/**
|
|
462
|
-
* Removes an annotation from the Kubernetes resource.
|
|
463
|
-
* @param key - The key of the annotation to remove.
|
|
464
|
-
* @returns The current Action instance for method chaining.
|
|
465
|
-
*/
|
|
466
463
|
RemoveAnnotation = (key) => {
|
|
467
464
|
if (this.Raw.metadata?.annotations?.[key]) {
|
|
468
465
|
delete this.Raw.metadata.annotations[key];
|
|
469
466
|
}
|
|
470
467
|
return this;
|
|
471
468
|
};
|
|
472
|
-
/**
|
|
473
|
-
* Check if a label exists on the Kubernetes resource.
|
|
474
|
-
*
|
|
475
|
-
* @param key the label key to check
|
|
476
|
-
* @returns
|
|
477
|
-
*/
|
|
478
469
|
HasLabel = (key) => {
|
|
479
470
|
return this.Raw.metadata?.labels?.[key] !== void 0;
|
|
480
471
|
};
|
|
481
|
-
/**
|
|
482
|
-
* Check if an annotation exists on the Kubernetes resource.
|
|
483
|
-
*
|
|
484
|
-
* @param key the annotation key to check
|
|
485
|
-
* @returns
|
|
486
|
-
*/
|
|
487
472
|
HasAnnotation = (key) => {
|
|
488
473
|
return this.Raw.metadata?.annotations?.[key] !== void 0;
|
|
489
474
|
};
|
|
@@ -577,16 +562,7 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
577
562
|
} catch (e) {
|
|
578
563
|
updateStatus("warning");
|
|
579
564
|
response.warnings = response.warnings || [];
|
|
580
|
-
|
|
581
|
-
try {
|
|
582
|
-
if (e.message && e.message !== "[object Object]") {
|
|
583
|
-
errorMessage = e.message;
|
|
584
|
-
} else {
|
|
585
|
-
throw new Error("An error occurred in the mutate action.");
|
|
586
|
-
}
|
|
587
|
-
} catch (e2) {
|
|
588
|
-
errorMessage = "An error occurred with the mutate action.";
|
|
589
|
-
}
|
|
565
|
+
const errorMessage = logMutateErrorMessage(e);
|
|
590
566
|
logger_default.error(actionMetadata, `Action failed: ${errorMessage}`);
|
|
591
567
|
response.warnings.push(`Action failed: ${errorMessage}`);
|
|
592
568
|
switch (config.onError) {
|
|
@@ -625,6 +601,17 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
625
601
|
logger_default.debug({ ...reqMetadata, patches }, `Patches generated`);
|
|
626
602
|
return response;
|
|
627
603
|
}
|
|
604
|
+
var logMutateErrorMessage = (e) => {
|
|
605
|
+
try {
|
|
606
|
+
if (e.message && e.message !== "[object Object]") {
|
|
607
|
+
return e.message;
|
|
608
|
+
} else {
|
|
609
|
+
throw new Error("An error occurred in the mutate action.");
|
|
610
|
+
}
|
|
611
|
+
} catch (e2) {
|
|
612
|
+
return "An error occurred with the mutate action.";
|
|
613
|
+
}
|
|
614
|
+
};
|
|
628
615
|
|
|
629
616
|
// src/lib/validate-request.ts
|
|
630
617
|
var import_ramda3 = require("ramda");
|
|
@@ -757,25 +744,65 @@ async function validateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
757
744
|
}
|
|
758
745
|
|
|
759
746
|
// src/lib/controller/store.ts
|
|
760
|
-
var
|
|
747
|
+
var import_kubernetes_fluent_client3 = require("kubernetes-fluent-client");
|
|
761
748
|
var import_ramda4 = require("ramda");
|
|
762
749
|
|
|
763
750
|
// src/lib/k8s.ts
|
|
764
751
|
var import_kubernetes_fluent_client = require("kubernetes-fluent-client");
|
|
765
|
-
var
|
|
752
|
+
var Store = class extends import_kubernetes_fluent_client.GenericKind {
|
|
766
753
|
};
|
|
767
754
|
var peprStoreGVK = {
|
|
768
755
|
kind: "PeprStore",
|
|
769
756
|
version: "v1",
|
|
770
757
|
group: "pepr.dev"
|
|
771
758
|
};
|
|
772
|
-
(0, import_kubernetes_fluent_client.RegisterKind)(
|
|
759
|
+
(0, import_kubernetes_fluent_client.RegisterKind)(Store, peprStoreGVK);
|
|
760
|
+
|
|
761
|
+
// src/lib/controller/storeCache.ts
|
|
762
|
+
var import_kubernetes_fluent_client2 = require("kubernetes-fluent-client");
|
|
763
|
+
var import_http_status_codes = require("http-status-codes");
|
|
764
|
+
var sendUpdatesAndFlushCache = async (cache, namespace2, name) => {
|
|
765
|
+
const indexes = Object.keys(cache);
|
|
766
|
+
const payload = Object.values(cache);
|
|
767
|
+
try {
|
|
768
|
+
if (payload.length > 0) {
|
|
769
|
+
await (0, import_kubernetes_fluent_client2.K8s)(Store, { namespace: namespace2, name }).Patch(payload);
|
|
770
|
+
Object.keys(cache).forEach((key) => delete cache[key]);
|
|
771
|
+
}
|
|
772
|
+
} catch (err) {
|
|
773
|
+
logger_default.error(err, "Pepr store update failure");
|
|
774
|
+
if (err.status === import_http_status_codes.StatusCodes.UNPROCESSABLE_ENTITY) {
|
|
775
|
+
Object.keys(cache).forEach((key) => delete cache[key]);
|
|
776
|
+
} else {
|
|
777
|
+
indexes.forEach((index) => {
|
|
778
|
+
cache[index] = payload[Number(index)];
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
return cache;
|
|
783
|
+
};
|
|
784
|
+
var fillStoreCache = (cache, capabilityName, op, cacheItem) => {
|
|
785
|
+
const path = [`/data/${capabilityName}`, cacheItem.version, cacheItem.key].filter((str) => str !== "" && str !== void 0).join("-");
|
|
786
|
+
if (op === "add") {
|
|
787
|
+
const value = cacheItem.value || "";
|
|
788
|
+
const cacheIdx = [op, path, value].join(":");
|
|
789
|
+
cache[cacheIdx] = { op, path, value };
|
|
790
|
+
} else if (op === "remove") {
|
|
791
|
+
if (cacheItem.key.length < 1) {
|
|
792
|
+
throw new Error(`Key is required for REMOVE operation`);
|
|
793
|
+
}
|
|
794
|
+
const cacheIndex = [op, path].join(":");
|
|
795
|
+
cache[cacheIndex] = { op, path };
|
|
796
|
+
} else {
|
|
797
|
+
throw new Error(`Unsupported operation: ${op}`);
|
|
798
|
+
}
|
|
799
|
+
return cache;
|
|
800
|
+
};
|
|
773
801
|
|
|
774
802
|
// src/lib/controller/store.ts
|
|
775
|
-
var redactedValue = "**redacted**";
|
|
776
803
|
var namespace = "pepr-system";
|
|
777
804
|
var debounceBackoff = 5e3;
|
|
778
|
-
var
|
|
805
|
+
var StoreController = class {
|
|
779
806
|
#name;
|
|
780
807
|
#stores = {};
|
|
781
808
|
#sendDebounce;
|
|
@@ -783,87 +810,53 @@ var PeprControllerStore = class {
|
|
|
783
810
|
constructor(capabilities, name, onReady) {
|
|
784
811
|
this.#onReady = onReady;
|
|
785
812
|
this.#name = name;
|
|
813
|
+
const setStorageInstance = (registrationFunction, name2) => {
|
|
814
|
+
const scheduleStore = registrationFunction();
|
|
815
|
+
scheduleStore.registerSender(this.#send(name2));
|
|
816
|
+
this.#stores[name2] = scheduleStore;
|
|
817
|
+
};
|
|
786
818
|
if (name.includes("schedule")) {
|
|
787
819
|
for (const { name: name2, registerScheduleStore, hasSchedule } of capabilities) {
|
|
788
|
-
if (hasSchedule
|
|
789
|
-
|
|
820
|
+
if (hasSchedule === true) {
|
|
821
|
+
setStorageInstance(registerScheduleStore, name2);
|
|
790
822
|
}
|
|
791
|
-
const { scheduleStore } = registerScheduleStore();
|
|
792
|
-
scheduleStore.registerSender(this.#send(name2));
|
|
793
|
-
this.#stores[name2] = scheduleStore;
|
|
794
823
|
}
|
|
795
824
|
} else {
|
|
796
825
|
for (const { name: name2, registerStore } of capabilities) {
|
|
797
|
-
|
|
798
|
-
store.registerSender(this.#send(name2));
|
|
799
|
-
this.#stores[name2] = store;
|
|
826
|
+
setStorageInstance(registerStore, name2);
|
|
800
827
|
}
|
|
801
828
|
}
|
|
802
829
|
setTimeout(
|
|
803
|
-
() => (0,
|
|
830
|
+
() => (0, import_kubernetes_fluent_client3.K8s)(Store).InNamespace(namespace).Get(this.#name).then(async (store) => await this.#migrateAndSetupWatch(store)).catch(this.#createStoreResource),
|
|
804
831
|
Math.random() * 3e3
|
|
832
|
+
// Add a jitter to the Store creation to avoid collisions
|
|
805
833
|
);
|
|
806
834
|
}
|
|
807
835
|
#setupWatch = () => {
|
|
808
|
-
const watcher = (0,
|
|
836
|
+
const watcher = (0, import_kubernetes_fluent_client3.K8s)(Store, { name: this.#name, namespace }).Watch(this.#receive);
|
|
809
837
|
watcher.start().catch((e) => logger_default.error(e, "Error starting Pepr store watch"));
|
|
810
838
|
};
|
|
811
839
|
#migrateAndSetupWatch = async (store) => {
|
|
812
840
|
logger_default.debug(redactedStore(store), "Pepr Store migration");
|
|
813
841
|
const data = store.data || {};
|
|
814
|
-
|
|
815
|
-
const flushCache = async () => {
|
|
816
|
-
const indexes = Object.keys(migrateCache);
|
|
817
|
-
const payload = Object.values(migrateCache);
|
|
818
|
-
for (const idx of indexes) {
|
|
819
|
-
delete migrateCache[idx];
|
|
820
|
-
}
|
|
821
|
-
try {
|
|
822
|
-
if (payload.length > 0) {
|
|
823
|
-
await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
|
|
824
|
-
}
|
|
825
|
-
} catch (err) {
|
|
826
|
-
logger_default.error(err, "Pepr store update failure");
|
|
827
|
-
if (err.status === 422) {
|
|
828
|
-
Object.keys(migrateCache).forEach((key) => delete migrateCache[key]);
|
|
829
|
-
} else {
|
|
830
|
-
for (const idx of indexes) {
|
|
831
|
-
migrateCache[idx] = payload[Number(idx)];
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
};
|
|
836
|
-
const fillCache = (name, op, key, val) => {
|
|
837
|
-
if (op === "add") {
|
|
838
|
-
const path = `/data/${name}-v2-${key}`;
|
|
839
|
-
const value = val || "";
|
|
840
|
-
const cacheIdx = [op, path, value].join(":");
|
|
841
|
-
migrateCache[cacheIdx] = { op, path, value };
|
|
842
|
-
return;
|
|
843
|
-
}
|
|
844
|
-
if (op === "remove") {
|
|
845
|
-
if (key.length < 1) {
|
|
846
|
-
throw new Error(`Key is required for REMOVE operation`);
|
|
847
|
-
}
|
|
848
|
-
for (const k of key) {
|
|
849
|
-
const path = `/data/${name}-${k}`;
|
|
850
|
-
const cacheIdx = [op, path].join(":");
|
|
851
|
-
migrateCache[cacheIdx] = { op, path };
|
|
852
|
-
}
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
855
|
-
throw new Error(`Unsupported operation: ${op}`);
|
|
856
|
-
};
|
|
842
|
+
let storeCache = {};
|
|
857
843
|
for (const name of Object.keys(this.#stores)) {
|
|
858
844
|
const offset = `${name}-`.length;
|
|
859
845
|
for (const key of Object.keys(data)) {
|
|
860
846
|
if ((0, import_ramda4.startsWith)(name, key) && !(0, import_ramda4.startsWith)(`${name}-v2`, key)) {
|
|
861
|
-
|
|
862
|
-
|
|
847
|
+
storeCache = fillStoreCache(storeCache, name, "remove", {
|
|
848
|
+
key: [key.slice(offset)],
|
|
849
|
+
value: data[key]
|
|
850
|
+
});
|
|
851
|
+
storeCache = fillStoreCache(storeCache, name, "add", {
|
|
852
|
+
key: [key.slice(offset)],
|
|
853
|
+
value: data[key],
|
|
854
|
+
version: "v2"
|
|
855
|
+
});
|
|
863
856
|
}
|
|
864
857
|
}
|
|
865
858
|
}
|
|
866
|
-
await
|
|
859
|
+
storeCache = await sendUpdatesAndFlushCache(storeCache, namespace, this.#name);
|
|
867
860
|
this.#setupWatch();
|
|
868
861
|
};
|
|
869
862
|
#receive = (store) => {
|
|
@@ -889,56 +882,14 @@ var PeprControllerStore = class {
|
|
|
889
882
|
this.#sendDebounce = setTimeout(debounced, this.#onReady ? 0 : debounceBackoff);
|
|
890
883
|
};
|
|
891
884
|
#send = (capabilityName) => {
|
|
892
|
-
|
|
893
|
-
const
|
|
894
|
-
|
|
895
|
-
const path = `/data/${capabilityName}-${key}`;
|
|
896
|
-
const value = val || "";
|
|
897
|
-
const cacheIdx = [op, path, value].join(":");
|
|
898
|
-
sendCache[cacheIdx] = { op, path, value };
|
|
899
|
-
return;
|
|
900
|
-
}
|
|
901
|
-
if (op === "remove") {
|
|
902
|
-
if (key.length < 1) {
|
|
903
|
-
throw new Error(`Key is required for REMOVE operation`);
|
|
904
|
-
}
|
|
905
|
-
for (const k of key) {
|
|
906
|
-
const path = `/data/${capabilityName}-${k}`;
|
|
907
|
-
const cacheIdx = [op, path].join(":");
|
|
908
|
-
sendCache[cacheIdx] = { op, path };
|
|
909
|
-
}
|
|
910
|
-
return;
|
|
911
|
-
}
|
|
912
|
-
throw new Error(`Unsupported operation: ${op}`);
|
|
913
|
-
};
|
|
914
|
-
const flushCache = async () => {
|
|
915
|
-
const indexes = Object.keys(sendCache);
|
|
916
|
-
const payload = Object.values(sendCache);
|
|
917
|
-
for (const idx of indexes) {
|
|
918
|
-
delete sendCache[idx];
|
|
919
|
-
}
|
|
920
|
-
try {
|
|
921
|
-
if (payload.length > 0) {
|
|
922
|
-
await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
|
|
923
|
-
}
|
|
924
|
-
} catch (err) {
|
|
925
|
-
logger_default.error(err, "Pepr store update failure");
|
|
926
|
-
if (err.status === 422) {
|
|
927
|
-
Object.keys(sendCache).forEach((key) => delete sendCache[key]);
|
|
928
|
-
} else {
|
|
929
|
-
for (const idx of indexes) {
|
|
930
|
-
sendCache[idx] = payload[Number(idx)];
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
};
|
|
935
|
-
const sender = async (op, key, val) => {
|
|
936
|
-
fillCache(op, key, val);
|
|
885
|
+
let storeCache = {};
|
|
886
|
+
const sender = async (op, key, value) => {
|
|
887
|
+
storeCache = fillStoreCache(storeCache, capabilityName, op, { key, value });
|
|
937
888
|
};
|
|
938
889
|
setInterval(() => {
|
|
939
|
-
if (Object.keys(
|
|
940
|
-
logger_default.debug(redactedPatch(
|
|
941
|
-
void
|
|
890
|
+
if (Object.keys(storeCache).length > 0) {
|
|
891
|
+
logger_default.debug(redactedPatch(storeCache), "Sending updates to Pepr store");
|
|
892
|
+
void sendUpdatesAndFlushCache(storeCache, namespace, this.#name);
|
|
942
893
|
}
|
|
943
894
|
}, debounceBackoff);
|
|
944
895
|
return sender;
|
|
@@ -947,7 +898,7 @@ var PeprControllerStore = class {
|
|
|
947
898
|
logger_default.info(`Pepr store not found, creating...`);
|
|
948
899
|
logger_default.debug(e);
|
|
949
900
|
try {
|
|
950
|
-
await (0,
|
|
901
|
+
await (0, import_kubernetes_fluent_client3.K8s)(Store).Apply({
|
|
951
902
|
metadata: {
|
|
952
903
|
name: this.#name,
|
|
953
904
|
namespace
|
|
@@ -963,33 +914,6 @@ var PeprControllerStore = class {
|
|
|
963
914
|
}
|
|
964
915
|
};
|
|
965
916
|
};
|
|
966
|
-
function redactedStore(store) {
|
|
967
|
-
const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
|
|
968
|
-
return {
|
|
969
|
-
...store,
|
|
970
|
-
data: Object.keys(store.data).reduce((acc, key) => {
|
|
971
|
-
acc[key] = redacted ? redactedValue : store.data[key];
|
|
972
|
-
return acc;
|
|
973
|
-
}, {})
|
|
974
|
-
};
|
|
975
|
-
}
|
|
976
|
-
function redactedPatch(patch = {}) {
|
|
977
|
-
const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
|
|
978
|
-
if (!redacted) {
|
|
979
|
-
return patch;
|
|
980
|
-
}
|
|
981
|
-
const redactedCache = {};
|
|
982
|
-
Object.keys(patch).forEach((key) => {
|
|
983
|
-
const operation = patch[key];
|
|
984
|
-
const redactedKey = key.includes(":") ? key.substring(0, key.lastIndexOf(":")) + ":**redacted**" : key;
|
|
985
|
-
const redactedOperation = {
|
|
986
|
-
...operation,
|
|
987
|
-
..."value" in operation ? { value: "**redacted**" } : {}
|
|
988
|
-
};
|
|
989
|
-
redactedCache[redactedKey] = redactedOperation;
|
|
990
|
-
});
|
|
991
|
-
return redactedCache;
|
|
992
|
-
}
|
|
993
917
|
|
|
994
918
|
// src/lib/controller/index.ts
|
|
995
919
|
if (!process.env.PEPR_NODE_WARNINGS) {
|
|
@@ -1012,11 +936,11 @@ var Controller = class _Controller {
|
|
|
1012
936
|
constructor(config, capabilities, beforeHook, afterHook, onReady) {
|
|
1013
937
|
this.#config = config;
|
|
1014
938
|
this.#capabilities = capabilities;
|
|
1015
|
-
new
|
|
939
|
+
new StoreController(capabilities, `pepr-${config.uuid}-store`, () => {
|
|
1016
940
|
this.#bindEndpoints();
|
|
1017
941
|
onReady && onReady();
|
|
1018
942
|
logger_default.info("\u2705 Controller startup complete");
|
|
1019
|
-
new
|
|
943
|
+
new StoreController(capabilities, `pepr-${config.uuid}-schedule`, () => {
|
|
1020
944
|
logger_default.info("\u2705 Scheduling processed");
|
|
1021
945
|
});
|
|
1022
946
|
});
|
|
@@ -1222,11 +1146,11 @@ var Controller = class _Controller {
|
|
|
1222
1146
|
};
|
|
1223
1147
|
|
|
1224
1148
|
// src/lib/watch-processor.ts
|
|
1225
|
-
var
|
|
1226
|
-
var
|
|
1149
|
+
var import_kubernetes_fluent_client7 = require("kubernetes-fluent-client");
|
|
1150
|
+
var import_types = require("kubernetes-fluent-client/dist/fluent/types");
|
|
1227
1151
|
|
|
1228
1152
|
// src/lib/helpers.ts
|
|
1229
|
-
var
|
|
1153
|
+
var import_kubernetes_fluent_client5 = require("kubernetes-fluent-client");
|
|
1230
1154
|
|
|
1231
1155
|
// src/sdk/sdk.ts
|
|
1232
1156
|
var sdk_exports = {};
|
|
@@ -1236,7 +1160,7 @@ __export(sdk_exports, {
|
|
|
1236
1160
|
sanitizeResourceName: () => sanitizeResourceName,
|
|
1237
1161
|
writeEvent: () => writeEvent
|
|
1238
1162
|
});
|
|
1239
|
-
var
|
|
1163
|
+
var import_kubernetes_fluent_client4 = require("kubernetes-fluent-client");
|
|
1240
1164
|
function containers(request, containerType) {
|
|
1241
1165
|
const containers2 = request.Raw.spec?.containers || [];
|
|
1242
1166
|
const initContainers = request.Raw.spec?.initContainers || [];
|
|
@@ -1254,7 +1178,7 @@ function containers(request, containerType) {
|
|
|
1254
1178
|
}
|
|
1255
1179
|
async function writeEvent(cr, event, eventType, eventReason, reportingComponent, reportingInstance) {
|
|
1256
1180
|
logger_default.debug(cr.metadata, `Writing event: ${event.message}`);
|
|
1257
|
-
await (0,
|
|
1181
|
+
await (0, import_kubernetes_fluent_client4.K8s)(import_kubernetes_fluent_client4.kind.CoreEvent).Create({
|
|
1258
1182
|
type: eventType,
|
|
1259
1183
|
reason: eventReason,
|
|
1260
1184
|
...event,
|
|
@@ -1300,7 +1224,7 @@ function filterNoMatchReason(binding, obj, capabilityNamespaces, ignoredNamespac
|
|
|
1300
1224
|
}
|
|
1301
1225
|
|
|
1302
1226
|
// src/lib/finalizer.ts
|
|
1303
|
-
var
|
|
1227
|
+
var import_kubernetes_fluent_client6 = require("kubernetes-fluent-client");
|
|
1304
1228
|
function addFinalizer(request) {
|
|
1305
1229
|
if (request.Request.operation === "DELETE" /* DELETE */) {
|
|
1306
1230
|
return;
|
|
@@ -1322,7 +1246,7 @@ async function removeFinalizer(binding, obj) {
|
|
|
1322
1246
|
logger_default.debug({ obj }, `Removing finalizer '${peprFinal}' from '${resource}'`);
|
|
1323
1247
|
const { model, kind: kind4 } = binding;
|
|
1324
1248
|
try {
|
|
1325
|
-
(0,
|
|
1249
|
+
(0, import_kubernetes_fluent_client6.RegisterKind)(model, kind4);
|
|
1326
1250
|
} catch (e) {
|
|
1327
1251
|
const expected = e.message === `GVK ${model.name} already registered`;
|
|
1328
1252
|
if (!expected) {
|
|
@@ -1331,7 +1255,7 @@ async function removeFinalizer(binding, obj) {
|
|
|
1331
1255
|
}
|
|
1332
1256
|
}
|
|
1333
1257
|
const finalizers = meta.finalizers?.filter((f) => f !== peprFinal) || [];
|
|
1334
|
-
obj = await (0,
|
|
1258
|
+
obj = await (0, import_kubernetes_fluent_client6.K8s)(model, meta).Patch([
|
|
1335
1259
|
{
|
|
1336
1260
|
op: "replace",
|
|
1337
1261
|
path: `/metadata/finalizers`,
|
|
@@ -1455,18 +1379,18 @@ function getOrCreateQueue(obj) {
|
|
|
1455
1379
|
return queues[key];
|
|
1456
1380
|
}
|
|
1457
1381
|
var watchCfg = {
|
|
1458
|
-
|
|
1382
|
+
useLegacyWatch: process.env.PEPR_USE_LEGACY_WATCH === "true",
|
|
1459
1383
|
resyncFailureMax: process.env.PEPR_RESYNC_FAILURE_MAX ? parseInt(process.env.PEPR_RESYNC_FAILURE_MAX, 10) : 5,
|
|
1460
1384
|
resyncDelaySec: process.env.PEPR_RESYNC_DELAY_SECONDS ? parseInt(process.env.PEPR_RESYNC_DELAY_SECONDS, 10) : 5,
|
|
1461
1385
|
lastSeenLimitSeconds: process.env.PEPR_LAST_SEEN_LIMIT_SECONDS ? parseInt(process.env.PEPR_LAST_SEEN_LIMIT_SECONDS, 10) : 300,
|
|
1462
1386
|
relistIntervalSec: process.env.PEPR_RELIST_INTERVAL_SECONDS ? parseInt(process.env.PEPR_RELIST_INTERVAL_SECONDS, 10) : 600
|
|
1463
1387
|
};
|
|
1464
1388
|
var eventToPhaseMap = {
|
|
1465
|
-
["CREATE" /* Create */]: [
|
|
1466
|
-
["UPDATE" /* Update */]: [
|
|
1467
|
-
["CREATEORUPDATE" /* CreateOrUpdate */]: [
|
|
1468
|
-
["DELETE" /* Delete */]: [
|
|
1469
|
-
["*" /* Any */]: [
|
|
1389
|
+
["CREATE" /* Create */]: [import_types.WatchPhase.Added],
|
|
1390
|
+
["UPDATE" /* Update */]: [import_types.WatchPhase.Modified],
|
|
1391
|
+
["CREATEORUPDATE" /* CreateOrUpdate */]: [import_types.WatchPhase.Added, import_types.WatchPhase.Modified],
|
|
1392
|
+
["DELETE" /* Delete */]: [import_types.WatchPhase.Deleted],
|
|
1393
|
+
["*" /* Any */]: [import_types.WatchPhase.Added, import_types.WatchPhase.Modified, import_types.WatchPhase.Deleted]
|
|
1470
1394
|
};
|
|
1471
1395
|
function setupWatch(capabilities, ignoredNamespaces) {
|
|
1472
1396
|
capabilities.map(
|
|
@@ -1476,32 +1400,39 @@ function setupWatch(capabilities, ignoredNamespaces) {
|
|
|
1476
1400
|
async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
1477
1401
|
const phaseMatch = eventToPhaseMap[binding.event] || eventToPhaseMap["*" /* Any */];
|
|
1478
1402
|
logger_default.debug({ watchCfg }, "Effective WatchConfig");
|
|
1479
|
-
const watchCallback = async (
|
|
1403
|
+
const watchCallback = async (kubernetesObject, phase) => {
|
|
1480
1404
|
if (phaseMatch.includes(phase)) {
|
|
1481
1405
|
try {
|
|
1482
|
-
const filterMatch = filterNoMatchReason(binding,
|
|
1483
|
-
if (filterMatch
|
|
1484
|
-
if (binding.isFinalize) {
|
|
1485
|
-
if (!obj.metadata?.deletionTimestamp) {
|
|
1486
|
-
return;
|
|
1487
|
-
}
|
|
1488
|
-
try {
|
|
1489
|
-
await binding.finalizeCallback?.(obj);
|
|
1490
|
-
} finally {
|
|
1491
|
-
await removeFinalizer(binding, obj);
|
|
1492
|
-
}
|
|
1493
|
-
} else {
|
|
1494
|
-
await binding.watchCallback?.(obj, phase);
|
|
1495
|
-
}
|
|
1496
|
-
} else {
|
|
1406
|
+
const filterMatch = filterNoMatchReason(binding, kubernetesObject, capabilityNamespaces, ignoredNamespaces);
|
|
1407
|
+
if (filterMatch !== "") {
|
|
1497
1408
|
logger_default.debug(filterMatch);
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
if (binding.isFinalize) {
|
|
1412
|
+
await handleFinalizerRemoval(kubernetesObject);
|
|
1413
|
+
} else {
|
|
1414
|
+
await binding.watchCallback?.(kubernetesObject, phase);
|
|
1498
1415
|
}
|
|
1499
1416
|
} catch (e) {
|
|
1500
1417
|
logger_default.error(e, "Error executing watch callback");
|
|
1501
1418
|
}
|
|
1502
1419
|
}
|
|
1503
1420
|
};
|
|
1504
|
-
const
|
|
1421
|
+
const handleFinalizerRemoval = async (kubernetesObject) => {
|
|
1422
|
+
if (!kubernetesObject.metadata?.deletionTimestamp) {
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
let shouldRemoveFinalizer = true;
|
|
1426
|
+
try {
|
|
1427
|
+
shouldRemoveFinalizer = await binding.finalizeCallback?.(kubernetesObject);
|
|
1428
|
+
} finally {
|
|
1429
|
+
const peprFinal = "pepr.dev/finalizer";
|
|
1430
|
+
const meta = kubernetesObject.metadata;
|
|
1431
|
+
const resource = `${meta.namespace || "ClusterScoped"}/${meta.name}`;
|
|
1432
|
+
shouldRemoveFinalizer === false ? logger_default.debug({ obj: kubernetesObject }, `Skipping removal of finalizer '${peprFinal}' from '${resource}'`) : await removeFinalizer(binding, kubernetesObject);
|
|
1433
|
+
}
|
|
1434
|
+
};
|
|
1435
|
+
const watcher = (0, import_kubernetes_fluent_client7.K8s)(binding.model, binding.filters).Watch(async (obj, phase) => {
|
|
1505
1436
|
logger_default.debug(obj, `Watch event ${phase} received`);
|
|
1506
1437
|
if (binding.isQueue) {
|
|
1507
1438
|
const queue = getOrCreateQueue(obj);
|
|
@@ -1510,30 +1441,30 @@ async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
|
1510
1441
|
await watchCallback(obj, phase);
|
|
1511
1442
|
}
|
|
1512
1443
|
}, watchCfg);
|
|
1513
|
-
watcher.events.on(
|
|
1444
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.GIVE_UP, (err) => {
|
|
1514
1445
|
logger_default.error(err, "Watch failed after 5 attempts, giving up");
|
|
1515
1446
|
process.exit(1);
|
|
1516
1447
|
});
|
|
1517
|
-
watcher.events.on(
|
|
1518
|
-
watcher.events.on(
|
|
1448
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.CONNECT, (url) => logEvent(import_kubernetes_fluent_client7.WatchEvent.CONNECT, url));
|
|
1449
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.DATA_ERROR, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.DATA_ERROR, err.message));
|
|
1519
1450
|
watcher.events.on(
|
|
1520
|
-
|
|
1521
|
-
(retryCount) => logEvent(
|
|
1451
|
+
import_kubernetes_fluent_client7.WatchEvent.RECONNECT,
|
|
1452
|
+
(retryCount) => logEvent(import_kubernetes_fluent_client7.WatchEvent.RECONNECT, `Reconnecting after ${retryCount} attempt${retryCount === 1 ? "" : "s"}`)
|
|
1522
1453
|
);
|
|
1523
|
-
watcher.events.on(
|
|
1524
|
-
watcher.events.on(
|
|
1525
|
-
watcher.events.on(
|
|
1526
|
-
watcher.events.on(
|
|
1527
|
-
watcher.events.on(
|
|
1528
|
-
watcher.events.on(
|
|
1529
|
-
watcher.events.on(
|
|
1530
|
-
watcher.events.on(
|
|
1454
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.RECONNECT_PENDING, () => logEvent(import_kubernetes_fluent_client7.WatchEvent.RECONNECT_PENDING));
|
|
1455
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.GIVE_UP, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.GIVE_UP, err.message));
|
|
1456
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.ABORT, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.ABORT, err.message));
|
|
1457
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.OLD_RESOURCE_VERSION, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.OLD_RESOURCE_VERSION, err));
|
|
1458
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.NETWORK_ERROR, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.NETWORK_ERROR, err.message));
|
|
1459
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.LIST_ERROR, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.LIST_ERROR, err.message));
|
|
1460
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.LIST, (list) => logEvent(import_kubernetes_fluent_client7.WatchEvent.LIST, JSON.stringify(list, void 0, 2)));
|
|
1461
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.CACHE_MISS, (windowName) => {
|
|
1531
1462
|
metricsCollector.incCacheMiss(windowName);
|
|
1532
1463
|
});
|
|
1533
|
-
watcher.events.on(
|
|
1464
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.INIT_CACHE_MISS, (windowName) => {
|
|
1534
1465
|
metricsCollector.initCacheMissWindow(windowName);
|
|
1535
1466
|
});
|
|
1536
|
-
watcher.events.on(
|
|
1467
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.INC_RESYNC_FAILURE_COUNT, (retryCount) => {
|
|
1537
1468
|
metricsCollector.incRetryCount(retryCount);
|
|
1538
1469
|
});
|
|
1539
1470
|
try {
|
|
@@ -1959,8 +1890,6 @@ var Capability = class {
|
|
|
1959
1890
|
}
|
|
1960
1891
|
/**
|
|
1961
1892
|
* Register the store with the capability. This is called automatically by the Pepr controller.
|
|
1962
|
-
*
|
|
1963
|
-
* @param store
|
|
1964
1893
|
*/
|
|
1965
1894
|
registerScheduleStore = () => {
|
|
1966
1895
|
logger_default.info(`Registering schedule store for ${this.#name}`);
|
|
@@ -1968,9 +1897,7 @@ var Capability = class {
|
|
|
1968
1897
|
throw new Error(`Schedule store already registered for ${this.#name}`);
|
|
1969
1898
|
}
|
|
1970
1899
|
this.#scheduleRegistered = true;
|
|
1971
|
-
return
|
|
1972
|
-
scheduleStore: this.#scheduleStore
|
|
1973
|
-
};
|
|
1900
|
+
return this.#scheduleStore;
|
|
1974
1901
|
};
|
|
1975
1902
|
/**
|
|
1976
1903
|
* Register the store with the capability. This is called automatically by the Pepr controller.
|
|
@@ -1983,9 +1910,7 @@ var Capability = class {
|
|
|
1983
1910
|
throw new Error(`Store already registered for ${this.#name}`);
|
|
1984
1911
|
}
|
|
1985
1912
|
this.#registered = true;
|
|
1986
|
-
return
|
|
1987
|
-
store: this.#store
|
|
1988
|
-
};
|
|
1913
|
+
return this.#store;
|
|
1989
1914
|
};
|
|
1990
1915
|
/**
|
|
1991
1916
|
* The When method is used to register a action to be executed when a Kubernetes resource is
|
|
@@ -1997,7 +1922,7 @@ var Capability = class {
|
|
|
1997
1922
|
* @returns
|
|
1998
1923
|
*/
|
|
1999
1924
|
When = (model, kind4) => {
|
|
2000
|
-
const matchedKind = (0,
|
|
1925
|
+
const matchedKind = (0, import_kubernetes_fluent_client8.modelToGroupVersionKind)(model.name);
|
|
2001
1926
|
if (!matchedKind && !kind4) {
|
|
2002
1927
|
throw new Error(`Kind not specified for ${model.name}`);
|
|
2003
1928
|
}
|
|
@@ -2108,7 +2033,7 @@ var Capability = class {
|
|
|
2108
2033
|
event: "UPDATE" /* Update */,
|
|
2109
2034
|
finalizeCallback: async (update, logger = aliasLogger) => {
|
|
2110
2035
|
logger_default.info(`Executing finalize action with alias: ${binding.alias || "no alias provided"}`);
|
|
2111
|
-
await finalizeCallback(update, logger);
|
|
2036
|
+
return await finalizeCallback(update, logger);
|
|
2112
2037
|
}
|
|
2113
2038
|
};
|
|
2114
2039
|
bindings.push(watchBinding);
|