pepr 0.38.3 → 0.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +294 -229
- package/dist/controller.js +53 -31
- 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} +23 -18
- 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 +236 -299
- 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 +12 -8
- 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} +56 -31
- 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,40 @@ 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
|
-
var declaredOperation = (0, import_ramda.pipe)(
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
259
|
+
var declaredOperation = (0, import_ramda.pipe)(
|
|
260
|
+
(request) => request?.operation,
|
|
261
|
+
(0, import_ramda.defaultTo)("")
|
|
262
|
+
);
|
|
263
|
+
var declaredGroup = (0, import_ramda.pipe)(
|
|
264
|
+
(request) => request?.kind?.group,
|
|
265
|
+
(0, import_ramda.defaultTo)("")
|
|
266
|
+
);
|
|
267
|
+
var declaredVersion = (0, import_ramda.pipe)(
|
|
268
|
+
(request) => request?.kind?.version,
|
|
269
|
+
(0, import_ramda.defaultTo)("")
|
|
270
|
+
);
|
|
271
|
+
var declaredKind = (0, import_ramda.pipe)(
|
|
272
|
+
(request) => request?.kind?.kind,
|
|
273
|
+
(0, import_ramda.defaultTo)("")
|
|
274
|
+
);
|
|
233
275
|
var declaredUid = (0, import_ramda.pipe)((request) => request?.uid, (0, import_ramda.defaultTo)(""));
|
|
234
|
-
var carriesDeletionTimestamp = (0, import_ramda.pipe)(
|
|
276
|
+
var carriesDeletionTimestamp = (0, import_ramda.pipe)(
|
|
277
|
+
(kubernetesObject) => !!kubernetesObject.metadata?.deletionTimestamp,
|
|
278
|
+
(0, import_ramda.defaultTo)(false)
|
|
279
|
+
);
|
|
235
280
|
var missingDeletionTimestamp = (0, import_ramda.complement)(carriesDeletionTimestamp);
|
|
236
|
-
var
|
|
281
|
+
var carriedKind = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.kind, (0, import_ramda.defaultTo)("not set"));
|
|
282
|
+
var carriedVersion = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.version, (0, import_ramda.defaultTo)("not set"));
|
|
283
|
+
var carriedName = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.name, (0, import_ramda.defaultTo)(""));
|
|
237
284
|
var carriesName = (0, import_ramda.pipe)(carriedName, (0, import_ramda.equals)(""), import_ramda.not);
|
|
238
285
|
var missingName = (0, import_ramda.complement)(carriesName);
|
|
239
|
-
var carriedNamespace = (0, import_ramda.pipe)((
|
|
286
|
+
var carriedNamespace = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.namespace, (0, import_ramda.defaultTo)(""));
|
|
240
287
|
var carriesNamespace = (0, import_ramda.pipe)(carriedNamespace, (0, import_ramda.equals)(""), import_ramda.not);
|
|
241
|
-
var carriedAnnotations = (0, import_ramda.pipe)((
|
|
288
|
+
var carriedAnnotations = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.annotations, (0, import_ramda.defaultTo)({}));
|
|
242
289
|
var carriesAnnotations = (0, import_ramda.pipe)(carriedAnnotations, (0, import_ramda.equals)({}), import_ramda.not);
|
|
243
|
-
var carriedLabels = (0, import_ramda.pipe)((
|
|
290
|
+
var carriedLabels = (0, import_ramda.pipe)((kubernetesObject) => kubernetesObject?.metadata?.labels, (0, import_ramda.defaultTo)({}));
|
|
244
291
|
var carriesLabels = (0, import_ramda.pipe)(carriedLabels, (0, import_ramda.equals)({}), import_ramda.not);
|
|
245
292
|
var definesDeletionTimestamp = (0, import_ramda.pipe)((binding) => binding?.filters?.deletionTimestamp, (0, import_ramda.defaultTo)(false));
|
|
246
293
|
var ignoresDeletionTimestamp = (0, import_ramda.complement)(definesDeletionTimestamp);
|
|
@@ -271,46 +318,46 @@ var definedCategory = (0, import_ramda.pipe)((binding) => {
|
|
|
271
318
|
var definedCallback = (0, import_ramda.pipe)((binding) => {
|
|
272
319
|
return binding.isFinalize ? binding.finalizeCallback : binding.isWatch ? binding.watchCallback : binding.isMutate ? binding.mutateCallback : binding.isValidate ? binding.validateCallback : null;
|
|
273
320
|
});
|
|
274
|
-
var definedCallbackName = (0, import_ramda.pipe)(definedCallback, (0, import_ramda.defaultTo)({ name: "" }), (
|
|
321
|
+
var definedCallbackName = (0, import_ramda.pipe)(definedCallback, (0, import_ramda.defaultTo)({ name: "" }), (callback) => callback.name);
|
|
275
322
|
var mismatchedDeletionTimestamp = (0, import_ramda.allPass)([
|
|
276
323
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesDeletionTimestamp),
|
|
277
324
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), missingDeletionTimestamp)
|
|
278
325
|
]);
|
|
279
326
|
var mismatchedName = (0, import_ramda.allPass)([
|
|
280
327
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesName),
|
|
281
|
-
(0, import_ramda.pipe)((
|
|
328
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => definedName(binding) !== carriedName(kubernetesObject))
|
|
282
329
|
]);
|
|
283
330
|
var mismatchedNameRegex = (0, import_ramda.allPass)([
|
|
284
331
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNameRegex),
|
|
285
|
-
(0, import_ramda.pipe)((
|
|
332
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => new RegExp(definedNameRegex(binding)).test(carriedName(kubernetesObject)), import_ramda.not)
|
|
286
333
|
]);
|
|
287
334
|
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)((
|
|
335
|
+
(0, import_ramda.allPass)([(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definedKind, (0, import_ramda.equals)(""), import_ramda.not), (0, import_ramda.pipe)((binding, kind4) => definedKind(binding) === kind4)])
|
|
289
336
|
);
|
|
290
337
|
var bindsToNamespace = (0, import_ramda.curry)((0, import_ramda.pipe)(bindsToKind(import_ramda.__, "Namespace")));
|
|
291
338
|
var misboundNamespace = (0, import_ramda.allPass)([bindsToNamespace, definesNamespaces]);
|
|
292
339
|
var mismatchedNamespace = (0, import_ramda.allPass)([
|
|
293
340
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNamespaces),
|
|
294
|
-
(0, import_ramda.pipe)((
|
|
341
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => definedNamespaces(binding).includes(carriedNamespace(kubernetesObject)), import_ramda.not)
|
|
295
342
|
]);
|
|
296
343
|
var mismatchedNamespaceRegex = (0, import_ramda.allPass)([
|
|
297
344
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNamespaceRegexes),
|
|
298
345
|
(0, import_ramda.pipe)(
|
|
299
|
-
(
|
|
300
|
-
(0, import_ramda.any)((
|
|
346
|
+
(binding, kubernetesObject) => (0, import_ramda.pipe)(
|
|
347
|
+
(0, import_ramda.any)((regEx) => new RegExp(regEx).test(carriedNamespace(kubernetesObject))),
|
|
301
348
|
import_ramda.not
|
|
302
|
-
)(definedNamespaceRegexes(
|
|
349
|
+
)(definedNamespaceRegexes(binding))
|
|
303
350
|
)
|
|
304
351
|
]);
|
|
305
352
|
var metasMismatch = (0, import_ramda.pipe)(
|
|
306
353
|
(defined, carried) => {
|
|
307
354
|
const result = { defined, carried, unalike: {} };
|
|
308
|
-
result.unalike = Object.entries(result.defined).map(([key,
|
|
355
|
+
result.unalike = Object.entries(result.defined).map(([key, value]) => {
|
|
309
356
|
const keyMissing = !Object.hasOwn(result.carried, key);
|
|
310
|
-
const noValue = !
|
|
357
|
+
const noValue = !value;
|
|
311
358
|
const valMissing = !result.carried[key];
|
|
312
359
|
const valDiffers = result.carried[key] !== result.defined[key];
|
|
313
|
-
return keyMissing ? { [key]:
|
|
360
|
+
return keyMissing ? { [key]: value } : noValue ? {} : valMissing ? { [key]: value } : valDiffers ? { [key]: value } : {};
|
|
314
361
|
}).reduce((acc, cur) => ({ ...acc, ...cur }), {});
|
|
315
362
|
return result.unalike;
|
|
316
363
|
},
|
|
@@ -318,32 +365,37 @@ var metasMismatch = (0, import_ramda.pipe)(
|
|
|
318
365
|
);
|
|
319
366
|
var mismatchedAnnotations = (0, import_ramda.allPass)([
|
|
320
367
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesAnnotations),
|
|
321
|
-
(0, import_ramda.pipe)((
|
|
368
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => metasMismatch(definedAnnotations(binding), carriedAnnotations(kubernetesObject)))
|
|
322
369
|
]);
|
|
323
370
|
var mismatchedLabels = (0, import_ramda.allPass)([
|
|
324
371
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesLabels),
|
|
325
|
-
(0, import_ramda.pipe)((
|
|
372
|
+
(0, import_ramda.pipe)((binding, kubernetesObject) => metasMismatch(definedLabels(binding), carriedLabels(kubernetesObject)))
|
|
326
373
|
]);
|
|
327
374
|
var uncarryableNamespace = (0, import_ramda.allPass)([
|
|
328
375
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
329
376
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), carriesNamespace),
|
|
330
|
-
(0, import_ramda.pipe)((
|
|
377
|
+
(0, import_ramda.pipe)((namespaceSelector, kubernetesObject) => namespaceSelector.includes(carriedNamespace(kubernetesObject)), import_ramda.not)
|
|
331
378
|
]);
|
|
332
379
|
var carriesIgnoredNamespace = (0, import_ramda.allPass)([
|
|
333
380
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
334
381
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), carriesNamespace),
|
|
335
|
-
(0, import_ramda.pipe)((
|
|
382
|
+
(0, import_ramda.pipe)((namespaceSelector, kubernetesObject) => namespaceSelector.includes(carriedNamespace(kubernetesObject)))
|
|
336
383
|
]);
|
|
337
384
|
var unbindableNamespaces = (0, import_ramda.allPass)([
|
|
338
385
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
339
386
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), definesNamespaces),
|
|
340
|
-
(0, import_ramda.pipe)(
|
|
387
|
+
(0, import_ramda.pipe)(
|
|
388
|
+
(namespaceSelector, binding) => (0, import_ramda.difference)(definedNamespaces(binding), namespaceSelector),
|
|
389
|
+
import_ramda.length,
|
|
390
|
+
(0, import_ramda.equals)(0),
|
|
391
|
+
import_ramda.not
|
|
392
|
+
)
|
|
341
393
|
]);
|
|
342
394
|
var misboundDeleteWithDeletionTimestamp = (0, import_ramda.allPass)([definesDelete, definesDeletionTimestamp]);
|
|
343
395
|
var operationMatchesEvent = (0, import_ramda.anyPass)([
|
|
344
396
|
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), (0, import_ramda.equals)("*" /* Any */)),
|
|
345
|
-
(0, import_ramda.pipe)((
|
|
346
|
-
(0, import_ramda.pipe)((
|
|
397
|
+
(0, import_ramda.pipe)((operation, event) => operation === event),
|
|
398
|
+
(0, import_ramda.pipe)((operation, event) => operation ? event.includes(operation) : false)
|
|
347
399
|
]);
|
|
348
400
|
var mismatchedEvent = (0, import_ramda.pipe)(
|
|
349
401
|
(binding, request) => operationMatchesEvent(declaredOperation(request), definedEvent(binding)),
|
|
@@ -362,7 +414,7 @@ var mismatchedKind = (0, import_ramda.allPass)([
|
|
|
362
414
|
(0, import_ramda.pipe)((binding, request) => definedKind(binding) !== declaredKind(request))
|
|
363
415
|
]);
|
|
364
416
|
|
|
365
|
-
// src/lib/filter.ts
|
|
417
|
+
// src/lib/filter/filter.ts
|
|
366
418
|
function shouldSkipRequest(binding, req, capabilityNamespaces, ignoredNamespaces) {
|
|
367
419
|
const prefix = "Ignoring Admission Callback:";
|
|
368
420
|
const obj = req.operation === "DELETE" /* DELETE */ ? req.oldObject : req.object;
|
|
@@ -377,31 +429,15 @@ var PeprMutateRequest = class {
|
|
|
377
429
|
get PermitSideEffects() {
|
|
378
430
|
return !this.#input.dryRun;
|
|
379
431
|
}
|
|
380
|
-
/**
|
|
381
|
-
* Indicates whether the request is a dry run.
|
|
382
|
-
* @returns true if the request is a dry run, false otherwise.
|
|
383
|
-
*/
|
|
384
432
|
get IsDryRun() {
|
|
385
433
|
return this.#input.dryRun;
|
|
386
434
|
}
|
|
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
435
|
get OldResource() {
|
|
392
436
|
return this.#input.oldObject;
|
|
393
437
|
}
|
|
394
|
-
/**
|
|
395
|
-
* Provides access to the request object.
|
|
396
|
-
* @returns The request object containing the Kubernetes resource.
|
|
397
|
-
*/
|
|
398
438
|
get Request() {
|
|
399
439
|
return this.#input;
|
|
400
440
|
}
|
|
401
|
-
/**
|
|
402
|
-
* Creates a new instance of the action class.
|
|
403
|
-
* @param input - The request object containing the Kubernetes resource to modify.
|
|
404
|
-
*/
|
|
405
441
|
constructor(input) {
|
|
406
442
|
this.#input = input;
|
|
407
443
|
if (input.operation.toUpperCase() === "DELETE" /* DELETE */) {
|
|
@@ -410,23 +446,12 @@ var PeprMutateRequest = class {
|
|
|
410
446
|
this.Raw = (0, import_ramda2.clone)(input.object);
|
|
411
447
|
}
|
|
412
448
|
if (!this.Raw) {
|
|
413
|
-
throw new Error("
|
|
449
|
+
throw new Error("Unable to load the request object into PeprRequest.Raw");
|
|
414
450
|
}
|
|
415
451
|
}
|
|
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
452
|
Merge = (obj) => {
|
|
422
453
|
this.Raw = (0, import_ramda2.mergeDeepRight)(this.Raw, obj);
|
|
423
454
|
};
|
|
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
455
|
SetLabel = (key, value) => {
|
|
431
456
|
const ref = this.Raw;
|
|
432
457
|
ref.metadata = ref.metadata ?? {};
|
|
@@ -434,12 +459,6 @@ var PeprMutateRequest = class {
|
|
|
434
459
|
ref.metadata.labels[key] = value;
|
|
435
460
|
return this;
|
|
436
461
|
};
|
|
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
462
|
SetAnnotation = (key, value) => {
|
|
444
463
|
const ref = this.Raw;
|
|
445
464
|
ref.metadata = ref.metadata ?? {};
|
|
@@ -447,43 +466,21 @@ var PeprMutateRequest = class {
|
|
|
447
466
|
ref.metadata.annotations[key] = value;
|
|
448
467
|
return this;
|
|
449
468
|
};
|
|
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
469
|
RemoveLabel = (key) => {
|
|
456
470
|
if (this.Raw.metadata?.labels?.[key]) {
|
|
457
471
|
delete this.Raw.metadata.labels[key];
|
|
458
472
|
}
|
|
459
473
|
return this;
|
|
460
474
|
};
|
|
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
475
|
RemoveAnnotation = (key) => {
|
|
467
476
|
if (this.Raw.metadata?.annotations?.[key]) {
|
|
468
477
|
delete this.Raw.metadata.annotations[key];
|
|
469
478
|
}
|
|
470
479
|
return this;
|
|
471
480
|
};
|
|
472
|
-
/**
|
|
473
|
-
* Check if a label exists on the Kubernetes resource.
|
|
474
|
-
*
|
|
475
|
-
* @param key the label key to check
|
|
476
|
-
* @returns
|
|
477
|
-
*/
|
|
478
481
|
HasLabel = (key) => {
|
|
479
482
|
return this.Raw.metadata?.labels?.[key] !== void 0;
|
|
480
483
|
};
|
|
481
|
-
/**
|
|
482
|
-
* Check if an annotation exists on the Kubernetes resource.
|
|
483
|
-
*
|
|
484
|
-
* @param key the annotation key to check
|
|
485
|
-
* @returns
|
|
486
|
-
*/
|
|
487
484
|
HasAnnotation = (key) => {
|
|
488
485
|
return this.Raw.metadata?.annotations?.[key] !== void 0;
|
|
489
486
|
};
|
|
@@ -577,16 +574,7 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
577
574
|
} catch (e) {
|
|
578
575
|
updateStatus("warning");
|
|
579
576
|
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
|
-
}
|
|
577
|
+
const errorMessage = logMutateErrorMessage(e);
|
|
590
578
|
logger_default.error(actionMetadata, `Action failed: ${errorMessage}`);
|
|
591
579
|
response.warnings.push(`Action failed: ${errorMessage}`);
|
|
592
580
|
switch (config.onError) {
|
|
@@ -625,6 +613,17 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
625
613
|
logger_default.debug({ ...reqMetadata, patches }, `Patches generated`);
|
|
626
614
|
return response;
|
|
627
615
|
}
|
|
616
|
+
var logMutateErrorMessage = (e) => {
|
|
617
|
+
try {
|
|
618
|
+
if (e.message && e.message !== "[object Object]") {
|
|
619
|
+
return e.message;
|
|
620
|
+
} else {
|
|
621
|
+
throw new Error("An error occurred in the mutate action.");
|
|
622
|
+
}
|
|
623
|
+
} catch (e2) {
|
|
624
|
+
return "An error occurred with the mutate action.";
|
|
625
|
+
}
|
|
626
|
+
};
|
|
628
627
|
|
|
629
628
|
// src/lib/validate-request.ts
|
|
630
629
|
var import_ramda3 = require("ramda");
|
|
@@ -757,25 +756,65 @@ async function validateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
757
756
|
}
|
|
758
757
|
|
|
759
758
|
// src/lib/controller/store.ts
|
|
760
|
-
var
|
|
759
|
+
var import_kubernetes_fluent_client3 = require("kubernetes-fluent-client");
|
|
761
760
|
var import_ramda4 = require("ramda");
|
|
762
761
|
|
|
763
762
|
// src/lib/k8s.ts
|
|
764
763
|
var import_kubernetes_fluent_client = require("kubernetes-fluent-client");
|
|
765
|
-
var
|
|
764
|
+
var Store = class extends import_kubernetes_fluent_client.GenericKind {
|
|
766
765
|
};
|
|
767
766
|
var peprStoreGVK = {
|
|
768
767
|
kind: "PeprStore",
|
|
769
768
|
version: "v1",
|
|
770
769
|
group: "pepr.dev"
|
|
771
770
|
};
|
|
772
|
-
(0, import_kubernetes_fluent_client.RegisterKind)(
|
|
771
|
+
(0, import_kubernetes_fluent_client.RegisterKind)(Store, peprStoreGVK);
|
|
772
|
+
|
|
773
|
+
// src/lib/controller/storeCache.ts
|
|
774
|
+
var import_kubernetes_fluent_client2 = require("kubernetes-fluent-client");
|
|
775
|
+
var import_http_status_codes = require("http-status-codes");
|
|
776
|
+
var sendUpdatesAndFlushCache = async (cache, namespace2, name) => {
|
|
777
|
+
const indexes = Object.keys(cache);
|
|
778
|
+
const payload = Object.values(cache);
|
|
779
|
+
try {
|
|
780
|
+
if (payload.length > 0) {
|
|
781
|
+
await (0, import_kubernetes_fluent_client2.K8s)(Store, { namespace: namespace2, name }).Patch(payload);
|
|
782
|
+
Object.keys(cache).forEach((key) => delete cache[key]);
|
|
783
|
+
}
|
|
784
|
+
} catch (err) {
|
|
785
|
+
logger_default.error(err, "Pepr store update failure");
|
|
786
|
+
if (err.status === import_http_status_codes.StatusCodes.UNPROCESSABLE_ENTITY) {
|
|
787
|
+
Object.keys(cache).forEach((key) => delete cache[key]);
|
|
788
|
+
} else {
|
|
789
|
+
indexes.forEach((index) => {
|
|
790
|
+
cache[index] = payload[Number(index)];
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
return cache;
|
|
795
|
+
};
|
|
796
|
+
var fillStoreCache = (cache, capabilityName, op, cacheItem) => {
|
|
797
|
+
const path = [`/data/${capabilityName}`, cacheItem.version, cacheItem.key].filter((str) => str !== "" && str !== void 0).join("-");
|
|
798
|
+
if (op === "add") {
|
|
799
|
+
const value = cacheItem.value || "";
|
|
800
|
+
const cacheIdx = [op, path, value].join(":");
|
|
801
|
+
cache[cacheIdx] = { op, path, value };
|
|
802
|
+
} else if (op === "remove") {
|
|
803
|
+
if (cacheItem.key.length < 1) {
|
|
804
|
+
throw new Error(`Key is required for REMOVE operation`);
|
|
805
|
+
}
|
|
806
|
+
const cacheIndex = [op, path].join(":");
|
|
807
|
+
cache[cacheIndex] = { op, path };
|
|
808
|
+
} else {
|
|
809
|
+
throw new Error(`Unsupported operation: ${op}`);
|
|
810
|
+
}
|
|
811
|
+
return cache;
|
|
812
|
+
};
|
|
773
813
|
|
|
774
814
|
// src/lib/controller/store.ts
|
|
775
|
-
var redactedValue = "**redacted**";
|
|
776
815
|
var namespace = "pepr-system";
|
|
777
816
|
var debounceBackoff = 5e3;
|
|
778
|
-
var
|
|
817
|
+
var StoreController = class {
|
|
779
818
|
#name;
|
|
780
819
|
#stores = {};
|
|
781
820
|
#sendDebounce;
|
|
@@ -783,87 +822,53 @@ var PeprControllerStore = class {
|
|
|
783
822
|
constructor(capabilities, name, onReady) {
|
|
784
823
|
this.#onReady = onReady;
|
|
785
824
|
this.#name = name;
|
|
825
|
+
const setStorageInstance = (registrationFunction, name2) => {
|
|
826
|
+
const scheduleStore = registrationFunction();
|
|
827
|
+
scheduleStore.registerSender(this.#send(name2));
|
|
828
|
+
this.#stores[name2] = scheduleStore;
|
|
829
|
+
};
|
|
786
830
|
if (name.includes("schedule")) {
|
|
787
831
|
for (const { name: name2, registerScheduleStore, hasSchedule } of capabilities) {
|
|
788
|
-
if (hasSchedule
|
|
789
|
-
|
|
832
|
+
if (hasSchedule === true) {
|
|
833
|
+
setStorageInstance(registerScheduleStore, name2);
|
|
790
834
|
}
|
|
791
|
-
const { scheduleStore } = registerScheduleStore();
|
|
792
|
-
scheduleStore.registerSender(this.#send(name2));
|
|
793
|
-
this.#stores[name2] = scheduleStore;
|
|
794
835
|
}
|
|
795
836
|
} else {
|
|
796
837
|
for (const { name: name2, registerStore } of capabilities) {
|
|
797
|
-
|
|
798
|
-
store.registerSender(this.#send(name2));
|
|
799
|
-
this.#stores[name2] = store;
|
|
838
|
+
setStorageInstance(registerStore, name2);
|
|
800
839
|
}
|
|
801
840
|
}
|
|
802
841
|
setTimeout(
|
|
803
|
-
() => (0,
|
|
842
|
+
() => (0, import_kubernetes_fluent_client3.K8s)(Store).InNamespace(namespace).Get(this.#name).then(async (store) => await this.#migrateAndSetupWatch(store)).catch(this.#createStoreResource),
|
|
804
843
|
Math.random() * 3e3
|
|
844
|
+
// Add a jitter to the Store creation to avoid collisions
|
|
805
845
|
);
|
|
806
846
|
}
|
|
807
847
|
#setupWatch = () => {
|
|
808
|
-
const watcher = (0,
|
|
848
|
+
const watcher = (0, import_kubernetes_fluent_client3.K8s)(Store, { name: this.#name, namespace }).Watch(this.#receive);
|
|
809
849
|
watcher.start().catch((e) => logger_default.error(e, "Error starting Pepr store watch"));
|
|
810
850
|
};
|
|
811
851
|
#migrateAndSetupWatch = async (store) => {
|
|
812
852
|
logger_default.debug(redactedStore(store), "Pepr Store migration");
|
|
813
853
|
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
|
-
};
|
|
854
|
+
let storeCache = {};
|
|
857
855
|
for (const name of Object.keys(this.#stores)) {
|
|
858
856
|
const offset = `${name}-`.length;
|
|
859
857
|
for (const key of Object.keys(data)) {
|
|
860
858
|
if ((0, import_ramda4.startsWith)(name, key) && !(0, import_ramda4.startsWith)(`${name}-v2`, key)) {
|
|
861
|
-
|
|
862
|
-
|
|
859
|
+
storeCache = fillStoreCache(storeCache, name, "remove", {
|
|
860
|
+
key: [key.slice(offset)],
|
|
861
|
+
value: data[key]
|
|
862
|
+
});
|
|
863
|
+
storeCache = fillStoreCache(storeCache, name, "add", {
|
|
864
|
+
key: [key.slice(offset)],
|
|
865
|
+
value: data[key],
|
|
866
|
+
version: "v2"
|
|
867
|
+
});
|
|
863
868
|
}
|
|
864
869
|
}
|
|
865
870
|
}
|
|
866
|
-
await
|
|
871
|
+
storeCache = await sendUpdatesAndFlushCache(storeCache, namespace, this.#name);
|
|
867
872
|
this.#setupWatch();
|
|
868
873
|
};
|
|
869
874
|
#receive = (store) => {
|
|
@@ -889,56 +894,14 @@ var PeprControllerStore = class {
|
|
|
889
894
|
this.#sendDebounce = setTimeout(debounced, this.#onReady ? 0 : debounceBackoff);
|
|
890
895
|
};
|
|
891
896
|
#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);
|
|
897
|
+
let storeCache = {};
|
|
898
|
+
const sender = async (op, key, value) => {
|
|
899
|
+
storeCache = fillStoreCache(storeCache, capabilityName, op, { key, value });
|
|
937
900
|
};
|
|
938
901
|
setInterval(() => {
|
|
939
|
-
if (Object.keys(
|
|
940
|
-
logger_default.debug(redactedPatch(
|
|
941
|
-
void
|
|
902
|
+
if (Object.keys(storeCache).length > 0) {
|
|
903
|
+
logger_default.debug(redactedPatch(storeCache), "Sending updates to Pepr store");
|
|
904
|
+
void sendUpdatesAndFlushCache(storeCache, namespace, this.#name);
|
|
942
905
|
}
|
|
943
906
|
}, debounceBackoff);
|
|
944
907
|
return sender;
|
|
@@ -947,7 +910,7 @@ var PeprControllerStore = class {
|
|
|
947
910
|
logger_default.info(`Pepr store not found, creating...`);
|
|
948
911
|
logger_default.debug(e);
|
|
949
912
|
try {
|
|
950
|
-
await (0,
|
|
913
|
+
await (0, import_kubernetes_fluent_client3.K8s)(Store).Apply({
|
|
951
914
|
metadata: {
|
|
952
915
|
name: this.#name,
|
|
953
916
|
namespace
|
|
@@ -963,33 +926,6 @@ var PeprControllerStore = class {
|
|
|
963
926
|
}
|
|
964
927
|
};
|
|
965
928
|
};
|
|
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
929
|
|
|
994
930
|
// src/lib/controller/index.ts
|
|
995
931
|
if (!process.env.PEPR_NODE_WARNINGS) {
|
|
@@ -1012,11 +948,11 @@ var Controller = class _Controller {
|
|
|
1012
948
|
constructor(config, capabilities, beforeHook, afterHook, onReady) {
|
|
1013
949
|
this.#config = config;
|
|
1014
950
|
this.#capabilities = capabilities;
|
|
1015
|
-
new
|
|
951
|
+
new StoreController(capabilities, `pepr-${config.uuid}-store`, () => {
|
|
1016
952
|
this.#bindEndpoints();
|
|
1017
953
|
onReady && onReady();
|
|
1018
954
|
logger_default.info("\u2705 Controller startup complete");
|
|
1019
|
-
new
|
|
955
|
+
new StoreController(capabilities, `pepr-${config.uuid}-schedule`, () => {
|
|
1020
956
|
logger_default.info("\u2705 Scheduling processed");
|
|
1021
957
|
});
|
|
1022
958
|
});
|
|
@@ -1222,11 +1158,11 @@ var Controller = class _Controller {
|
|
|
1222
1158
|
};
|
|
1223
1159
|
|
|
1224
1160
|
// src/lib/watch-processor.ts
|
|
1225
|
-
var
|
|
1226
|
-
var
|
|
1161
|
+
var import_kubernetes_fluent_client7 = require("kubernetes-fluent-client");
|
|
1162
|
+
var import_types = require("kubernetes-fluent-client/dist/fluent/types");
|
|
1227
1163
|
|
|
1228
1164
|
// src/lib/helpers.ts
|
|
1229
|
-
var
|
|
1165
|
+
var import_kubernetes_fluent_client5 = require("kubernetes-fluent-client");
|
|
1230
1166
|
|
|
1231
1167
|
// src/sdk/sdk.ts
|
|
1232
1168
|
var sdk_exports = {};
|
|
@@ -1236,7 +1172,7 @@ __export(sdk_exports, {
|
|
|
1236
1172
|
sanitizeResourceName: () => sanitizeResourceName,
|
|
1237
1173
|
writeEvent: () => writeEvent
|
|
1238
1174
|
});
|
|
1239
|
-
var
|
|
1175
|
+
var import_kubernetes_fluent_client4 = require("kubernetes-fluent-client");
|
|
1240
1176
|
function containers(request, containerType) {
|
|
1241
1177
|
const containers2 = request.Raw.spec?.containers || [];
|
|
1242
1178
|
const initContainers = request.Raw.spec?.initContainers || [];
|
|
@@ -1254,7 +1190,7 @@ function containers(request, containerType) {
|
|
|
1254
1190
|
}
|
|
1255
1191
|
async function writeEvent(cr, event, eventType, eventReason, reportingComponent, reportingInstance) {
|
|
1256
1192
|
logger_default.debug(cr.metadata, `Writing event: ${event.message}`);
|
|
1257
|
-
await (0,
|
|
1193
|
+
await (0, import_kubernetes_fluent_client4.K8s)(import_kubernetes_fluent_client4.kind.CoreEvent).Create({
|
|
1258
1194
|
type: eventType,
|
|
1259
1195
|
reason: eventReason,
|
|
1260
1196
|
...event,
|
|
@@ -1300,7 +1236,7 @@ function filterNoMatchReason(binding, obj, capabilityNamespaces, ignoredNamespac
|
|
|
1300
1236
|
}
|
|
1301
1237
|
|
|
1302
1238
|
// src/lib/finalizer.ts
|
|
1303
|
-
var
|
|
1239
|
+
var import_kubernetes_fluent_client6 = require("kubernetes-fluent-client");
|
|
1304
1240
|
function addFinalizer(request) {
|
|
1305
1241
|
if (request.Request.operation === "DELETE" /* DELETE */) {
|
|
1306
1242
|
return;
|
|
@@ -1322,7 +1258,7 @@ async function removeFinalizer(binding, obj) {
|
|
|
1322
1258
|
logger_default.debug({ obj }, `Removing finalizer '${peprFinal}' from '${resource}'`);
|
|
1323
1259
|
const { model, kind: kind4 } = binding;
|
|
1324
1260
|
try {
|
|
1325
|
-
(0,
|
|
1261
|
+
(0, import_kubernetes_fluent_client6.RegisterKind)(model, kind4);
|
|
1326
1262
|
} catch (e) {
|
|
1327
1263
|
const expected = e.message === `GVK ${model.name} already registered`;
|
|
1328
1264
|
if (!expected) {
|
|
@@ -1331,7 +1267,7 @@ async function removeFinalizer(binding, obj) {
|
|
|
1331
1267
|
}
|
|
1332
1268
|
}
|
|
1333
1269
|
const finalizers = meta.finalizers?.filter((f) => f !== peprFinal) || [];
|
|
1334
|
-
obj = await (0,
|
|
1270
|
+
obj = await (0, import_kubernetes_fluent_client6.K8s)(model, meta).Patch([
|
|
1335
1271
|
{
|
|
1336
1272
|
op: "replace",
|
|
1337
1273
|
path: `/metadata/finalizers`,
|
|
@@ -1455,18 +1391,18 @@ function getOrCreateQueue(obj) {
|
|
|
1455
1391
|
return queues[key];
|
|
1456
1392
|
}
|
|
1457
1393
|
var watchCfg = {
|
|
1458
|
-
|
|
1394
|
+
useLegacyWatch: process.env.PEPR_USE_LEGACY_WATCH === "true",
|
|
1459
1395
|
resyncFailureMax: process.env.PEPR_RESYNC_FAILURE_MAX ? parseInt(process.env.PEPR_RESYNC_FAILURE_MAX, 10) : 5,
|
|
1460
1396
|
resyncDelaySec: process.env.PEPR_RESYNC_DELAY_SECONDS ? parseInt(process.env.PEPR_RESYNC_DELAY_SECONDS, 10) : 5,
|
|
1461
1397
|
lastSeenLimitSeconds: process.env.PEPR_LAST_SEEN_LIMIT_SECONDS ? parseInt(process.env.PEPR_LAST_SEEN_LIMIT_SECONDS, 10) : 300,
|
|
1462
1398
|
relistIntervalSec: process.env.PEPR_RELIST_INTERVAL_SECONDS ? parseInt(process.env.PEPR_RELIST_INTERVAL_SECONDS, 10) : 600
|
|
1463
1399
|
};
|
|
1464
1400
|
var eventToPhaseMap = {
|
|
1465
|
-
["CREATE" /* Create */]: [
|
|
1466
|
-
["UPDATE" /* Update */]: [
|
|
1467
|
-
["CREATEORUPDATE" /* CreateOrUpdate */]: [
|
|
1468
|
-
["DELETE" /* Delete */]: [
|
|
1469
|
-
["*" /* Any */]: [
|
|
1401
|
+
["CREATE" /* Create */]: [import_types.WatchPhase.Added],
|
|
1402
|
+
["UPDATE" /* Update */]: [import_types.WatchPhase.Modified],
|
|
1403
|
+
["CREATEORUPDATE" /* CreateOrUpdate */]: [import_types.WatchPhase.Added, import_types.WatchPhase.Modified],
|
|
1404
|
+
["DELETE" /* Delete */]: [import_types.WatchPhase.Deleted],
|
|
1405
|
+
["*" /* Any */]: [import_types.WatchPhase.Added, import_types.WatchPhase.Modified, import_types.WatchPhase.Deleted]
|
|
1470
1406
|
};
|
|
1471
1407
|
function setupWatch(capabilities, ignoredNamespaces) {
|
|
1472
1408
|
capabilities.map(
|
|
@@ -1476,32 +1412,39 @@ function setupWatch(capabilities, ignoredNamespaces) {
|
|
|
1476
1412
|
async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
1477
1413
|
const phaseMatch = eventToPhaseMap[binding.event] || eventToPhaseMap["*" /* Any */];
|
|
1478
1414
|
logger_default.debug({ watchCfg }, "Effective WatchConfig");
|
|
1479
|
-
const watchCallback = async (
|
|
1415
|
+
const watchCallback = async (kubernetesObject, phase) => {
|
|
1480
1416
|
if (phaseMatch.includes(phase)) {
|
|
1481
1417
|
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 {
|
|
1418
|
+
const filterMatch = filterNoMatchReason(binding, kubernetesObject, capabilityNamespaces, ignoredNamespaces);
|
|
1419
|
+
if (filterMatch !== "") {
|
|
1497
1420
|
logger_default.debug(filterMatch);
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
if (binding.isFinalize) {
|
|
1424
|
+
await handleFinalizerRemoval(kubernetesObject);
|
|
1425
|
+
} else {
|
|
1426
|
+
await binding.watchCallback?.(kubernetesObject, phase);
|
|
1498
1427
|
}
|
|
1499
1428
|
} catch (e) {
|
|
1500
1429
|
logger_default.error(e, "Error executing watch callback");
|
|
1501
1430
|
}
|
|
1502
1431
|
}
|
|
1503
1432
|
};
|
|
1504
|
-
const
|
|
1433
|
+
const handleFinalizerRemoval = async (kubernetesObject) => {
|
|
1434
|
+
if (!kubernetesObject.metadata?.deletionTimestamp) {
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
let shouldRemoveFinalizer = true;
|
|
1438
|
+
try {
|
|
1439
|
+
shouldRemoveFinalizer = await binding.finalizeCallback?.(kubernetesObject);
|
|
1440
|
+
} finally {
|
|
1441
|
+
const peprFinal = "pepr.dev/finalizer";
|
|
1442
|
+
const meta = kubernetesObject.metadata;
|
|
1443
|
+
const resource = `${meta.namespace || "ClusterScoped"}/${meta.name}`;
|
|
1444
|
+
shouldRemoveFinalizer === false ? logger_default.debug({ obj: kubernetesObject }, `Skipping removal of finalizer '${peprFinal}' from '${resource}'`) : await removeFinalizer(binding, kubernetesObject);
|
|
1445
|
+
}
|
|
1446
|
+
};
|
|
1447
|
+
const watcher = (0, import_kubernetes_fluent_client7.K8s)(binding.model, binding.filters).Watch(async (obj, phase) => {
|
|
1505
1448
|
logger_default.debug(obj, `Watch event ${phase} received`);
|
|
1506
1449
|
if (binding.isQueue) {
|
|
1507
1450
|
const queue = getOrCreateQueue(obj);
|
|
@@ -1510,30 +1453,30 @@ async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
|
1510
1453
|
await watchCallback(obj, phase);
|
|
1511
1454
|
}
|
|
1512
1455
|
}, watchCfg);
|
|
1513
|
-
watcher.events.on(
|
|
1456
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.GIVE_UP, (err) => {
|
|
1514
1457
|
logger_default.error(err, "Watch failed after 5 attempts, giving up");
|
|
1515
1458
|
process.exit(1);
|
|
1516
1459
|
});
|
|
1517
|
-
watcher.events.on(
|
|
1518
|
-
watcher.events.on(
|
|
1460
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.CONNECT, (url) => logEvent(import_kubernetes_fluent_client7.WatchEvent.CONNECT, url));
|
|
1461
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.DATA_ERROR, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.DATA_ERROR, err.message));
|
|
1519
1462
|
watcher.events.on(
|
|
1520
|
-
|
|
1521
|
-
(retryCount) => logEvent(
|
|
1463
|
+
import_kubernetes_fluent_client7.WatchEvent.RECONNECT,
|
|
1464
|
+
(retryCount) => logEvent(import_kubernetes_fluent_client7.WatchEvent.RECONNECT, `Reconnecting after ${retryCount} attempt${retryCount === 1 ? "" : "s"}`)
|
|
1522
1465
|
);
|
|
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(
|
|
1466
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.RECONNECT_PENDING, () => logEvent(import_kubernetes_fluent_client7.WatchEvent.RECONNECT_PENDING));
|
|
1467
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.GIVE_UP, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.GIVE_UP, err.message));
|
|
1468
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.ABORT, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.ABORT, err.message));
|
|
1469
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.OLD_RESOURCE_VERSION, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.OLD_RESOURCE_VERSION, err));
|
|
1470
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.NETWORK_ERROR, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.NETWORK_ERROR, err.message));
|
|
1471
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.LIST_ERROR, (err) => logEvent(import_kubernetes_fluent_client7.WatchEvent.LIST_ERROR, err.message));
|
|
1472
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.LIST, (list) => logEvent(import_kubernetes_fluent_client7.WatchEvent.LIST, JSON.stringify(list, void 0, 2)));
|
|
1473
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.CACHE_MISS, (windowName) => {
|
|
1531
1474
|
metricsCollector.incCacheMiss(windowName);
|
|
1532
1475
|
});
|
|
1533
|
-
watcher.events.on(
|
|
1476
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.INIT_CACHE_MISS, (windowName) => {
|
|
1534
1477
|
metricsCollector.initCacheMissWindow(windowName);
|
|
1535
1478
|
});
|
|
1536
|
-
watcher.events.on(
|
|
1479
|
+
watcher.events.on(import_kubernetes_fluent_client7.WatchEvent.INC_RESYNC_FAILURE_COUNT, (retryCount) => {
|
|
1537
1480
|
metricsCollector.incRetryCount(retryCount);
|
|
1538
1481
|
});
|
|
1539
1482
|
try {
|
|
@@ -1959,8 +1902,6 @@ var Capability = class {
|
|
|
1959
1902
|
}
|
|
1960
1903
|
/**
|
|
1961
1904
|
* Register the store with the capability. This is called automatically by the Pepr controller.
|
|
1962
|
-
*
|
|
1963
|
-
* @param store
|
|
1964
1905
|
*/
|
|
1965
1906
|
registerScheduleStore = () => {
|
|
1966
1907
|
logger_default.info(`Registering schedule store for ${this.#name}`);
|
|
@@ -1968,9 +1909,7 @@ var Capability = class {
|
|
|
1968
1909
|
throw new Error(`Schedule store already registered for ${this.#name}`);
|
|
1969
1910
|
}
|
|
1970
1911
|
this.#scheduleRegistered = true;
|
|
1971
|
-
return
|
|
1972
|
-
scheduleStore: this.#scheduleStore
|
|
1973
|
-
};
|
|
1912
|
+
return this.#scheduleStore;
|
|
1974
1913
|
};
|
|
1975
1914
|
/**
|
|
1976
1915
|
* Register the store with the capability. This is called automatically by the Pepr controller.
|
|
@@ -1983,9 +1922,7 @@ var Capability = class {
|
|
|
1983
1922
|
throw new Error(`Store already registered for ${this.#name}`);
|
|
1984
1923
|
}
|
|
1985
1924
|
this.#registered = true;
|
|
1986
|
-
return
|
|
1987
|
-
store: this.#store
|
|
1988
|
-
};
|
|
1925
|
+
return this.#store;
|
|
1989
1926
|
};
|
|
1990
1927
|
/**
|
|
1991
1928
|
* The When method is used to register a action to be executed when a Kubernetes resource is
|
|
@@ -1997,7 +1934,7 @@ var Capability = class {
|
|
|
1997
1934
|
* @returns
|
|
1998
1935
|
*/
|
|
1999
1936
|
When = (model, kind4) => {
|
|
2000
|
-
const matchedKind = (0,
|
|
1937
|
+
const matchedKind = (0, import_kubernetes_fluent_client8.modelToGroupVersionKind)(model.name);
|
|
2001
1938
|
if (!matchedKind && !kind4) {
|
|
2002
1939
|
throw new Error(`Kind not specified for ${model.name}`);
|
|
2003
1940
|
}
|
|
@@ -2108,7 +2045,7 @@ var Capability = class {
|
|
|
2108
2045
|
event: "UPDATE" /* Update */,
|
|
2109
2046
|
finalizeCallback: async (update, logger = aliasLogger) => {
|
|
2110
2047
|
logger_default.info(`Executing finalize action with alias: ${binding.alias || "no alias provided"}`);
|
|
2111
|
-
await finalizeCallback(update, logger);
|
|
2048
|
+
return await finalizeCallback(update, logger);
|
|
2112
2049
|
}
|
|
2113
2050
|
};
|
|
2114
2051
|
bindings.push(watchBinding);
|